Merging the iohandler branch back into main. 

The many many benefits include:
1 - Input/Output/Error streams are now handled as real streams not a push style input
2 - auto completion in python embedded interpreter
3 - multi-line input for "script" and "expression" commands now allow you to edit previous/next lines using up and down arrow keys and this makes multi-line input actually a viable thing to use
4 - it is now possible to use curses to drive LLDB (please try the "gui" command)

We will need to deal with and fix any buildbot failures and tests and arise now that input/output and error are correctly hooked up in all cases.

llvm-svn: 200263
diff --git a/lldb/tools/driver/CMakeLists.txt b/lldb/tools/driver/CMakeLists.txt
index 0cd021a..f671b5b 100644
--- a/lldb/tools/driver/CMakeLists.txt
+++ b/lldb/tools/driver/CMakeLists.txt
@@ -4,7 +4,6 @@
   #DriverEvents.cpp
   #DriverOptions.cpp
   #DriverPosix.cpp
-  IOChannel.cpp
   ELWrapper.cpp
   Platform.cpp
   GetOptWrapper.cpp
diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp
index e274242..9394efa 100644
--- a/lldb/tools/driver/Driver.cpp
+++ b/lldb/tools/driver/Driver.cpp
@@ -18,7 +18,6 @@
 #include <string>
 
 #include <thread>
-#include "IOChannel.h"
 #include "lldb/API/SBBreakpoint.h"
 #include "lldb/API/SBCommandInterpreter.h"
 #include "lldb/API/SBCommandReturnObject.h"
@@ -121,14 +120,7 @@
 Driver::Driver () :
     SBBroadcaster ("Driver"),
     m_debugger (SBDebugger::Create(false)),
-    m_editline_pty (),
-    m_editline_slave_fh (NULL),
-    m_editline_reader (),
-    m_io_channel_ap (),
-    m_option_data (),
-    m_executing_user_command (false),
-    m_waiting_for_command (false),
-    m_done(false)
+    m_option_data ()
 {
     // We want to be able to handle CTRL+D in the terminal to have it terminate
     // certain input
@@ -145,24 +137,6 @@
     g_debugger_name = NULL;
 }
 
-void
-Driver::CloseIOChannelFile ()
-{
-    // Write an End of File sequence to the file descriptor to ensure any
-    // read functions can exit.
-    char eof_str[] = "\x04";
-    int mfd = m_editline_pty.GetMasterFileDescriptor();
-    if (mfd != -1)
-        ::write (m_editline_pty.GetMasterFileDescriptor(), eof_str, strlen(eof_str));
-
-    m_editline_pty.CloseMasterFileDescriptor();
-
-    if (m_editline_slave_fh)
-    {
-        ::fclose (m_editline_slave_fh);
-        m_editline_slave_fh = NULL;
-    }
-}
 
 // This function takes INDENT, which tells how many spaces to output at the front
 // of each line; TEXT, which is the text that is to be output. It outputs the 
@@ -530,23 +504,27 @@
         {
             const size_t output_size = result.GetOutputSize();
             if (output_size > 0)
-                m_io_channel_ap->OutWrite (result.GetOutput(dump_stream_only_if_no_immediate), output_size, NO_ASYNC);
+            {
+                const char *cstr = result.GetOutput(dump_stream_only_if_no_immediate);
+                if (cstr)
+                    printf ("%s", cstr);
+            }
             const size_t error_size = result.GetErrorSize();
             if (error_size > 0)
-                m_io_channel_ap->OutWrite (result.GetError(dump_stream_only_if_no_immediate), error_size, NO_ASYNC);
+            {
+                const char *cstr = result.GetError(dump_stream_only_if_no_immediate);
+                if (cstr)
+                    printf ("%s", cstr);
+            }
         }
         
         if (result.Succeeded() == false)
         {
-            char error_buffer[1024];
-            size_t error_size;
             const char *type = before_file ? "before file" : "after_file";
             if (is_file)
-                error_size = ::snprintf(error_buffer, sizeof(error_buffer), "Aborting %s command execution, command file: '%s' failed.\n", type, command);
+                ::fprintf(stderr, "Aborting %s command execution, command file: '%s' failed.\n", type, command);
             else
-                error_size = ::snprintf(error_buffer, sizeof(error_buffer), "Aborting %s command execution, command: '%s' failed.\n", type, command);
-            
-            m_io_channel_ap->OutWrite(error_buffer, error_size, NO_ASYNC);
+                ::fprintf(stderr, "Aborting %s command execution, command: '%s' failed.\n", type, command);
             break;
         }
         result.Clear();
@@ -861,524 +839,9 @@
     return error;
 }
 
-size_t
-Driver::GetProcessSTDOUT ()
-{
-    //  The process has stuff waiting for stdout; get it and write it out to the appropriate place.
-    char stdio_buffer[1024];
-    size_t len;
-    size_t total_bytes = 0;
-    while ((len = m_debugger.GetSelectedTarget().GetProcess().GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0)
-    {
-        m_io_channel_ap->OutWrite (stdio_buffer, len, NO_ASYNC);
-        total_bytes += len;
-    }
-    return total_bytes;
-}
-
-size_t
-Driver::GetProcessSTDERR ()
-{
-    //  The process has stuff waiting for stderr; get it and write it out to the appropriate place.
-    char stdio_buffer[1024];
-    size_t len;
-    size_t total_bytes = 0;
-    while ((len = m_debugger.GetSelectedTarget().GetProcess().GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0)
-    {
-        m_io_channel_ap->ErrWrite (stdio_buffer, len, NO_ASYNC);
-        total_bytes += len;
-    }
-    return total_bytes;
-}
-
-void
-Driver::UpdateSelectedThread ()
-{
-    using namespace lldb;
-    SBProcess process(m_debugger.GetSelectedTarget().GetProcess());
-    if (process.IsValid())
-    {
-        SBThread curr_thread (process.GetSelectedThread());
-        SBThread thread;
-        StopReason curr_thread_stop_reason = eStopReasonInvalid;
-        curr_thread_stop_reason = curr_thread.GetStopReason();
-
-        if (!curr_thread.IsValid() ||
-            curr_thread_stop_reason == eStopReasonInvalid ||
-            curr_thread_stop_reason == eStopReasonNone)
-        {
-            // Prefer a thread that has just completed its plan over another thread as current thread.
-            SBThread plan_thread;
-            SBThread other_thread;
-            const size_t num_threads = process.GetNumThreads();
-            size_t i;
-            for (i = 0; i < num_threads; ++i)
-            {
-                thread = process.GetThreadAtIndex(i);
-                StopReason thread_stop_reason = thread.GetStopReason();
-                switch (thread_stop_reason)
-                {
-                case eStopReasonInvalid:
-                case eStopReasonNone:
-                    break;
-
-                case eStopReasonTrace:
-                case eStopReasonBreakpoint:
-                case eStopReasonWatchpoint:
-                case eStopReasonSignal:
-                case eStopReasonException:
-                case eStopReasonExec:
-                case eStopReasonThreadExiting:
-                    if (!other_thread.IsValid())
-                        other_thread = thread;
-                    break;
-                case eStopReasonPlanComplete:
-                    if (!plan_thread.IsValid())
-                        plan_thread = thread;
-                    break;
-                }
-            }
-            if (plan_thread.IsValid())
-                process.SetSelectedThread (plan_thread);
-            else if (other_thread.IsValid())
-                process.SetSelectedThread (other_thread);
-            else
-            {
-                if (curr_thread.IsValid())
-                    thread = curr_thread;
-                else
-                    thread = process.GetThreadAtIndex(0);
-
-                if (thread.IsValid())
-                    process.SetSelectedThread (thread);
-            }
-        }
-    }
-}
-
-// This function handles events that were broadcast by the process.
-void
-Driver::HandleBreakpointEvent (const SBEvent &event)
-{
-    using namespace lldb;
-    const uint32_t event_type = SBBreakpoint::GetBreakpointEventTypeFromEvent (event);
-    
-    if (event_type & eBreakpointEventTypeAdded
-        || event_type & eBreakpointEventTypeRemoved
-        || event_type & eBreakpointEventTypeEnabled
-        || event_type & eBreakpointEventTypeDisabled
-        || event_type & eBreakpointEventTypeCommandChanged
-        || event_type & eBreakpointEventTypeConditionChanged
-        || event_type & eBreakpointEventTypeIgnoreChanged
-        || event_type & eBreakpointEventTypeLocationsResolved)
-    {
-        // Don't do anything about these events, since the breakpoint commands already echo these actions.
-    }              
-    else if (event_type & eBreakpointEventTypeLocationsAdded)
-    {
-        char message[256];
-        uint32_t num_new_locations = SBBreakpoint::GetNumBreakpointLocationsFromEvent(event);
-        if (num_new_locations > 0)
-        {
-            SBBreakpoint breakpoint = SBBreakpoint::GetBreakpointFromEvent(event);
-            int message_len = ::snprintf (message, sizeof(message), "%d location%s added to breakpoint %d\n", 
-                                          num_new_locations,
-                                          num_new_locations == 1 ? "" : "s",
-                                          breakpoint.GetID());
-            m_io_channel_ap->OutWrite(message, message_len, ASYNC);
-        }
-    }
-    else if (event_type & eBreakpointEventTypeLocationsRemoved)
-    {
-       // These locations just get disabled, not sure it is worth spamming folks about this on the command line.
-    }
-    else if (event_type & eBreakpointEventTypeLocationsResolved)
-    {
-       // This might be an interesting thing to note, but I'm going to leave it quiet for now, it just looked noisy.
-    }
-}
-
-// This function handles events that were broadcast by the process.
-void
-Driver::HandleProcessEvent (const SBEvent &event)
-{
-    using namespace lldb;
-    const uint32_t event_type = event.GetType();
-
-    if (event_type & SBProcess::eBroadcastBitSTDOUT)
-    {
-        // The process has stdout available, get it and write it out to the
-        // appropriate place.
-        GetProcessSTDOUT ();
-    }
-    else if (event_type & SBProcess::eBroadcastBitSTDERR)
-    {
-        // The process has stderr available, get it and write it out to the
-        // appropriate place.
-        GetProcessSTDERR ();
-    }
-    else if (event_type & SBProcess::eBroadcastBitStateChanged)
-    {
-        // Drain all stout and stderr so we don't see any output come after
-        // we print our prompts
-        GetProcessSTDOUT ();
-        GetProcessSTDERR ();
-        // Something changed in the process;  get the event and report the process's current status and location to
-        // the user.
-        StateType event_state = SBProcess::GetStateFromEvent (event);
-        if (event_state == eStateInvalid)
-            return;
-
-        SBProcess process (SBProcess::GetProcessFromEvent (event));
-        assert (process.IsValid());
-
-        switch (event_state)
-        {
-        case eStateInvalid:
-        case eStateUnloaded:
-        case eStateConnected:
-        case eStateAttaching:
-        case eStateLaunching:
-        case eStateStepping:
-        case eStateDetached:
-            {
-                char message[1024];
-                int message_len = ::snprintf (message, sizeof(message), "Process %" PRIu64 " %s\n", process.GetProcessID(),
-                                              m_debugger.StateAsCString (event_state));
-                m_io_channel_ap->OutWrite(message, message_len, ASYNC);
-            }
-            break;
-
-        case eStateRunning:
-            // Don't be chatty when we run...
-            break;
-
-        case eStateExited:
-            {
-                SBCommandReturnObject result;
-                m_debugger.GetCommandInterpreter().HandleCommand("process status", result, false);
-                m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize(), ASYNC);
-                m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), ASYNC);
-            }
-            break;
-
-        case eStateStopped:
-        case eStateCrashed:
-        case eStateSuspended:
-            // Make sure the program hasn't been auto-restarted:
-            if (SBProcess::GetRestartedFromEvent (event))
-            {
-                size_t num_reasons = SBProcess::GetNumRestartedReasonsFromEvent(event);
-                if (num_reasons > 0)
-                {
-                // FIXME: Do we want to report this, or would that just be annoyingly chatty?
-                    if (num_reasons == 1)
-                    {
-                        char message[1024];
-                        const char *reason = SBProcess::GetRestartedReasonAtIndexFromEvent (event, 0);
-                        int message_len = ::snprintf (message, sizeof(message), "Process %" PRIu64 " stopped and restarted: %s\n",
-                                              process.GetProcessID(), reason ? reason : "<UNKNOWN REASON>");
-                        m_io_channel_ap->OutWrite(message, message_len, ASYNC);
-                    }
-                    else
-                    {
-                        char message[1024];
-                        int message_len = ::snprintf (message, sizeof(message), "Process %" PRIu64 " stopped and restarted, reasons:\n",
-                                              process.GetProcessID());
-                        m_io_channel_ap->OutWrite(message, message_len, ASYNC);
-                        for (size_t i = 0; i < num_reasons; i++)
-                        {
-                            const char *reason = SBProcess::GetRestartedReasonAtIndexFromEvent (event, i);
-                            int message_len = ::snprintf(message, sizeof(message), "\t%s\n", reason ? reason : "<UNKNOWN REASON>");
-                            m_io_channel_ap->OutWrite(message, message_len, ASYNC);
-                        }
-                    }
-                }
-            }
-            else
-            {
-                if (GetDebugger().GetSelectedTarget() == process.GetTarget())
-                {
-                    SBCommandReturnObject result;
-                    UpdateSelectedThread ();
-                    m_debugger.GetCommandInterpreter().HandleCommand("process status", result, false);
-                    m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize(), ASYNC);
-                    m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), ASYNC);
-                }
-                else
-                {
-                    SBStream out_stream;
-                    uint32_t target_idx = GetDebugger().GetIndexOfTarget(process.GetTarget());
-                    if (target_idx != UINT32_MAX)
-                        out_stream.Printf ("Target %d: (", target_idx);
-                    else
-                        out_stream.Printf ("Target <unknown index>: (");
-                    process.GetTarget().GetDescription (out_stream, eDescriptionLevelBrief);
-                    out_stream.Printf (") stopped.\n");
-                    m_io_channel_ap->OutWrite (out_stream.GetData(), out_stream.GetSize(), ASYNC);
-                }
-            }
-            break;
-        }
-    }
-}
-
-void
-Driver::HandleThreadEvent (const SBEvent &event)
-{
-    // At present the only thread event we handle is the Frame Changed event, and all we do for that is just
-    // reprint the thread status for that thread.
-    using namespace lldb;
-    const uint32_t event_type = event.GetType();
-    if (event_type == SBThread::eBroadcastBitStackChanged
-        || event_type == SBThread::eBroadcastBitThreadSelected)
-    {
-        SBThread thread = SBThread::GetThreadFromEvent (event);
-        if (thread.IsValid())
-        {
-            SBStream out_stream;
-            thread.GetStatus(out_stream);
-            m_io_channel_ap->OutWrite (out_stream.GetData (), out_stream.GetSize (), ASYNC);
-        }
-    }
-}
-
-//  This function handles events broadcast by the IOChannel (HasInput, UserInterrupt, or ThreadShouldExit).
-
-bool
-Driver::HandleIOEvent (const SBEvent &event)
-{
-    bool quit = false;
-
-    const uint32_t event_type = event.GetType();
-
-    if (event_type & IOChannel::eBroadcastBitHasUserInput)
-    {
-        // We got some input (i.e. a command string) from the user; pass it off to the command interpreter for
-        // handling.
-
-        const char *command_string = SBEvent::GetCStringFromEvent(event);
-        if (command_string == NULL)
-            command_string = "";
-        SBCommandReturnObject result;
-        
-        // We don't want the result to bypass the OutWrite function in IOChannel, as this can result in odd
-        // output orderings and problems with the prompt.
-        
-        // Note that we are in the process of executing a command
-        m_executing_user_command = true;
-
-        m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, true);
-
-        // Note that we are back from executing a user command
-        m_executing_user_command = false;
-
-        // Display any STDOUT/STDERR _prior_ to emitting the command result text
-        GetProcessSTDOUT ();
-        GetProcessSTDERR ();
-
-        const bool only_if_no_immediate = true;
-
-        // Now emit the command output text from the command we just executed
-        const size_t output_size = result.GetOutputSize();
-        if (output_size > 0)
-            m_io_channel_ap->OutWrite (result.GetOutput(only_if_no_immediate), output_size, NO_ASYNC);
-
-        // Now emit the command error text from the command we just executed
-        const size_t error_size = result.GetErrorSize();
-        if (error_size > 0)
-            m_io_channel_ap->OutWrite (result.GetError(only_if_no_immediate), error_size, NO_ASYNC);
-
-        // We are done getting and running our command, we can now clear the
-        // m_waiting_for_command so we can get another one.
-        m_waiting_for_command = false;
-
-        // If our editline input reader is active, it means another input reader
-        // got pushed onto the input reader and caused us to become deactivated.
-        // When the input reader above us gets popped, we will get re-activated
-        // and our prompt will refresh in our callback
-        if (m_editline_reader.IsActive())
-        {
-            ReadyForCommand ();
-        }
-    }
-    else if (event_type & IOChannel::eBroadcastBitUserInterrupt)
-    {
-        // This is here to handle control-c interrupts from the user.  It has not yet really been implemented.
-        // TO BE DONE:  PROPERLY HANDLE CONTROL-C FROM USER
-        //m_io_channel_ap->CancelInput();
-        // Anything else?  Send Interrupt to process?
-    }
-    else if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) ||
-             (event_type & IOChannel::eBroadcastBitThreadDidExit))
-    {
-        // If the IOChannel thread is trying to go away, then it is definitely
-        // time to end the debugging session.
-        quit = true;
-    }
-
-    return quit;
-}
-
-void
-Driver::MasterThreadBytesReceived (void *baton, const void *src, size_t src_len)
-{
-    Driver *driver = (Driver*)baton;
-    driver->GetFromMaster ((const char *)src, src_len);
-}
-
-void
-Driver::GetFromMaster (const char *src, size_t src_len)
-{
-    // Echo the characters back to the Debugger's stdout, that way if you
-    // type characters while a command is running, you'll see what you've typed.
-    FILE *out_fh = m_debugger.GetOutputFileHandle();
-    if (out_fh)
-        ::fwrite (src, 1, src_len, out_fh);
-}
-
-size_t
-Driver::EditLineInputReaderCallback 
-(
-    void *baton, 
-    SBInputReader *reader, 
-    InputReaderAction notification,
-    const char *bytes, 
-    size_t bytes_len
-)
-{
-    Driver *driver = (Driver *)baton;
-
-    switch (notification)
-    {
-    case eInputReaderActivate:
-        break;
-
-    case eInputReaderReactivate:
-        if (driver->m_executing_user_command == false)
-            driver->ReadyForCommand();
-        break;
-
-    case eInputReaderDeactivate:
-        break;
-        
-    case eInputReaderAsynchronousOutputWritten:
-        if (driver->m_io_channel_ap.get() != NULL)
-            driver->m_io_channel_ap->RefreshPrompt();
-        break;
-
-    case eInputReaderInterrupt:
-        if (driver->m_io_channel_ap.get() != NULL)
-        {
-            SBProcess process(driver->GetDebugger().GetSelectedTarget().GetProcess());
-            if (!driver->m_io_channel_ap->EditLineHasCharacters()
-                &&  process.IsValid()
-                && (process.GetState() == lldb::eStateRunning || process.GetState() == lldb::eStateAttaching))
-            {
-                process.SendAsyncInterrupt ();
-            }
-            else
-            {
-                driver->m_io_channel_ap->OutWrite ("^C\n", 3, NO_ASYNC);
-                // I wish I could erase the entire input line, but there's no public API for that.
-                driver->m_io_channel_ap->EraseCharsBeforeCursor();
-                driver->m_io_channel_ap->RefreshPrompt();
-            }
-        }
-        break;
-        
-    case eInputReaderEndOfFile:
-        if (driver->m_io_channel_ap.get() != NULL)
-        {
-            driver->m_io_channel_ap->OutWrite ("^D\n", 3, NO_ASYNC);
-            driver->m_io_channel_ap->RefreshPrompt ();
-        }
-        write (driver->m_editline_pty.GetMasterFileDescriptor(), "quit\n", 5);
-        break;
-
-    case eInputReaderGotToken:
-        write (driver->m_editline_pty.GetMasterFileDescriptor(), bytes, bytes_len);
-        break;
-        
-    case eInputReaderDone:
-        break;
-    }
-    return bytes_len;
-}
-
 void
 Driver::MainLoop ()
 {
-#if defined(_MSC_VER)
-    m_editline_slave_fh = stdin;
-    FILE *editline_output_slave_fh = stdout;
-    lldb_utility::PseudoTerminal editline_output_pty;
-#else
-
-    char error_str[1024];
-    if (m_editline_pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, error_str, sizeof(error_str)) == false)
-    {
-        ::fprintf (stderr, "error: failed to open driver pseudo terminal : %s", error_str);
-        exit(1);
-    }
-    else
-    {
-        const char *driver_slave_name = m_editline_pty.GetSlaveName (error_str, sizeof(error_str));
-        if (driver_slave_name == NULL)
-        {
-            ::fprintf (stderr, "error: failed to get slave name for driver pseudo terminal : %s", error_str);
-            exit(2);
-        }
-        else
-        {
-            m_editline_slave_fh = ::fopen (driver_slave_name, "r+");
-            if (m_editline_slave_fh == NULL)
-            {
-                SBError error;
-                error.SetErrorToErrno();
-                ::fprintf (stderr, "error: failed to get open slave for driver pseudo terminal : %s",
-                           error.GetCString());
-                exit(3);
-            }
-
-            ::setbuf (m_editline_slave_fh, NULL);
-        }
-    }
-
-    lldb_utility::PseudoTerminal editline_output_pty;
-    FILE *editline_output_slave_fh = NULL;
-    
-    if (editline_output_pty.OpenFirstAvailableMaster (O_RDWR|O_NOCTTY, error_str, sizeof (error_str)) == false)
-    {
-        ::fprintf (stderr, "error: failed to open output pseudo terminal : %s", error_str);
-        exit(1);
-    }
-    else
-    {
-        const char *output_slave_name = editline_output_pty.GetSlaveName (error_str, sizeof(error_str));
-        if (output_slave_name == NULL)
-        {
-            ::fprintf (stderr, "error: failed to get slave name for output pseudo terminal : %s", error_str);
-            exit(2);
-        }
-        else
-        {
-            editline_output_slave_fh = ::fopen (output_slave_name, "r+");
-            if (editline_output_slave_fh == NULL)
-            {
-                SBError error;
-                error.SetErrorToErrno();
-                ::fprintf (stderr, "error: failed to get open slave for output pseudo terminal : %s",
-                           error.GetCString());
-                exit(3);
-            }
-            ::setbuf (editline_output_slave_fh, NULL);
-        }
-    }
-#endif
-
-   // struct termios stdin_termios;
-
     if (::tcgetattr(STDIN_FILENO, &g_old_stdin_termios) == 0)
     {
         g_old_stdin_termios_is_valid = true;
@@ -1394,43 +857,6 @@
     
     m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor);
 
-    // You have to drain anything that comes to the master side of the PTY.  master_out_comm is
-    // for that purpose.  The reason you need to do this is a curious reason...  editline will echo
-    // characters to the PTY when it gets characters while el_gets is not running, and then when
-    // you call el_gets (or el_getc) it will try to reset the terminal back to raw mode which blocks
-    // if there are unconsumed characters in the out buffer.
-    // However, you don't need to do anything with the characters, since editline will dump these
-    // unconsumed characters after printing the prompt again in el_gets.
-
-    SBCommunication master_out_comm("driver.editline");
-    master_out_comm.SetCloseOnEOF (false);
-    master_out_comm.AdoptFileDesriptor(m_editline_pty.GetMasterFileDescriptor(), false);
-    master_out_comm.SetReadThreadBytesReceivedCallback(Driver::MasterThreadBytesReceived, this);
-
-    if (master_out_comm.ReadThreadStart () == false)
-    {
-        ::fprintf (stderr, "error: failed to start master out read thread");
-        exit(5);
-    }
-
-    SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter();
-
-    m_io_channel_ap.reset (new IOChannel(m_editline_slave_fh, editline_output_slave_fh, stdout, stderr, this));
-
-#if !defined (_MSC_VER)
-    SBCommunication out_comm_2("driver.editline_output");
-    out_comm_2.SetCloseOnEOF (false);
-    out_comm_2.AdoptFileDesriptor (editline_output_pty.GetMasterFileDescriptor(), false);
-    out_comm_2.SetReadThreadBytesReceivedCallback (IOChannel::LibeditOutputBytesReceived, m_io_channel_ap.get());
-
-    if (out_comm_2.ReadThreadStart () == false)
-    {
-        ::fprintf (stderr, "error: failed to start libedit output read thread");
-        exit (5);
-    }
-#endif
-
-
     struct winsize window_size;
     if (isatty (STDIN_FILENO)
         && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
@@ -1439,286 +865,97 @@
             m_debugger.SetTerminalWidth (window_size.ws_col);
     }
 
-    // Since input can be redirected by the debugger, we must insert our editline
-    // input reader in the queue so we know when our reader should be active
-    // and so we can receive bytes only when we are supposed to.
-    SBError err (m_editline_reader.Initialize (m_debugger, 
-                                               Driver::EditLineInputReaderCallback, // callback
-                                               this,                              // baton
-                                               eInputReaderGranularityByte,       // token_size
-                                               NULL,                              // end token - NULL means never done
-                                               NULL,                              // prompt - taken care of elsewhere
-                                               false));                           // echo input - don't need Debugger 
-                                                                                  // to do this, we handle it elsewhere
+    SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter();
     
-    if (err.Fail())
+    // Before we handle any options from the command line, we parse the
+    // .lldbinit file in the user's home directory.
+    SBCommandReturnObject result;
+    sb_interpreter.SourceInitFileInHomeDirectory(result);
+    if (GetDebugMode())
     {
-        ::fprintf (stderr, "error: %s", err.GetCString());
-        exit (6);
+        result.PutError (m_debugger.GetErrorFileHandle());
+        result.PutOutput (m_debugger.GetOutputFileHandle());
     }
+
+    // Now we handle options we got from the command line
+    // First source in the commands specified to be run before the file arguments are processed.
+    ExecuteInitialCommands(true);
     
-    m_debugger.PushInputReader (m_editline_reader);
-
-    SBListener listener(m_debugger.GetListener());
-    if (listener.IsValid())
+    // Was there a core file specified?
+    std::string core_file_spec("");
+    if (!m_option_data.m_core_file.empty())
+        core_file_spec.append("--core ").append(m_option_data.m_core_file);
+    
+    char command_string[PATH_MAX * 2];
+    const size_t num_args = m_option_data.m_args.size();
+    if (num_args > 0)
     {
-
-        listener.StartListeningForEventClass(m_debugger, 
-                                         SBTarget::GetBroadcasterClassName(), 
-                                         SBTarget::eBroadcastBitBreakpointChanged);
-        listener.StartListeningForEventClass(m_debugger, 
-                                         SBThread::GetBroadcasterClassName(),
-                                         SBThread::eBroadcastBitStackChanged |
-                                         SBThread::eBroadcastBitThreadSelected);
-        listener.StartListeningForEvents (*m_io_channel_ap,
-                                          IOChannel::eBroadcastBitHasUserInput |
-                                          IOChannel::eBroadcastBitUserInterrupt |
-                                          IOChannel::eBroadcastBitThreadShouldExit |
-                                          IOChannel::eBroadcastBitThreadDidStart |
-                                          IOChannel::eBroadcastBitThreadDidExit);
-
-        if (m_io_channel_ap->Start ())
+        char arch_name[64];
+        if (m_debugger.GetDefaultArchitecture (arch_name, sizeof (arch_name)))
+            ::snprintf (command_string,
+                        sizeof (command_string),
+                        "target create --arch=%s %s \"%s\"",
+                        arch_name,
+                        core_file_spec.c_str(),
+                        m_option_data.m_args[0].c_str());
+        else
+            ::snprintf (command_string,
+                        sizeof(command_string),
+                        "target create %s \"%s\"",
+                        core_file_spec.c_str(),
+                        m_option_data.m_args[0].c_str());
+        
+        m_debugger.HandleCommand (command_string);
+        
+        if (num_args > 1)
         {
-            bool iochannel_thread_exited = false;
-
-            listener.StartListeningForEvents (sb_interpreter.GetBroadcaster(),
-                                              SBCommandInterpreter::eBroadcastBitQuitCommandReceived |
-                                              SBCommandInterpreter::eBroadcastBitAsynchronousOutputData |
-                                              SBCommandInterpreter::eBroadcastBitAsynchronousErrorData);
-
-            // Before we handle any options from the command line, we parse the
-            // .lldbinit file in the user's home directory.
-            SBCommandReturnObject result;
-            sb_interpreter.SourceInitFileInHomeDirectory(result);
-            if (GetDebugMode())
+            m_debugger.HandleCommand ("settings clear target.run-args");
+            char arg_cstr[1024];
+            for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx)
             {
-                result.PutError (m_debugger.GetErrorFileHandle());
-                result.PutOutput (m_debugger.GetOutputFileHandle());
+                ::snprintf (arg_cstr,
+                            sizeof(arg_cstr),
+                            "settings append target.run-args \"%s\"",
+                            m_option_data.m_args[arg_idx].c_str());
+                m_debugger.HandleCommand (arg_cstr);
             }
-
-            // Now we handle options we got from the command line
-            // First source in the commands specified to be run before the file arguments are processed.
-            ExecuteInitialCommands(true);
-            
-            // Was there a core file specified?
-            std::string core_file_spec("");
-            if (!m_option_data.m_core_file.empty())
-                core_file_spec.append("--core ").append(m_option_data.m_core_file);
-
-            char command_string[PATH_MAX * 2];
-            const size_t num_args = m_option_data.m_args.size();
-            if (num_args > 0)
-            {
-                char arch_name[64];
-                if (m_debugger.GetDefaultArchitecture (arch_name, sizeof (arch_name)))
-                    ::snprintf (command_string, 
-                                sizeof (command_string), 
-                                "target create --arch=%s %s \"%s\"", 
-                                arch_name,
-                                core_file_spec.c_str(),
-                                m_option_data.m_args[0].c_str());
-                else
-                    ::snprintf (command_string, 
-                                sizeof(command_string), 
-                                "target create %s \"%s\"", 
-                                core_file_spec.c_str(),
-                                m_option_data.m_args[0].c_str());
-
-                m_debugger.HandleCommand (command_string);
-                
-                if (num_args > 1)
-                {
-                    m_debugger.HandleCommand ("settings clear target.run-args");
-                    char arg_cstr[1024];
-                    for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx)
-                    {
-                        ::snprintf (arg_cstr, 
-                                    sizeof(arg_cstr), 
-                                    "settings append target.run-args \"%s\"", 
-                                    m_option_data.m_args[arg_idx].c_str());
-                        m_debugger.HandleCommand (arg_cstr);
-                    }
-                }
-            }
-            else if (!core_file_spec.empty())
-            {
-                ::snprintf (command_string, 
-                            sizeof(command_string), 
-                            "target create %s", 
-                            core_file_spec.c_str());
-                m_debugger.HandleCommand (command_string);;
-            }
-
-            // Now that all option parsing is done, we try and parse the .lldbinit
-            // file in the current working directory
-            sb_interpreter.SourceInitFileInCurrentWorkingDirectory (result);
-            if (GetDebugMode())
-            {
-                result.PutError(m_debugger.GetErrorFileHandle());
-                result.PutOutput(m_debugger.GetOutputFileHandle());
-            }
-            
-            // Now execute the commands specified for after the file arguments are processed.
-            ExecuteInitialCommands(false);
-
-            SBEvent event;
-
-            // Make sure the IO channel is started up before we try to tell it we
-            // are ready for input
-            listener.WaitForEventForBroadcasterWithType (UINT32_MAX, 
-                                                         *m_io_channel_ap,
-                                                         IOChannel::eBroadcastBitThreadDidStart, 
-                                                         event);
-            // If we were asked to attach, then do that here:
-            // I'm going to use the command string rather than directly
-            // calling the API's because then I don't have to recode the
-            // event handling here.
-            if (!m_option_data.m_process_name.empty()
-                || m_option_data.m_process_pid != LLDB_INVALID_PROCESS_ID)
-            {
-                std::string command_str("process attach ");
-                if (m_option_data.m_process_pid != LLDB_INVALID_PROCESS_ID)
-                {
-                    command_str.append("-p ");
-                    char pid_buffer[32];
-                    ::snprintf (pid_buffer, sizeof(pid_buffer), "%" PRIu64, m_option_data.m_process_pid);
-                    command_str.append(pid_buffer);
-                }
-                else 
-                {
-                    command_str.append("-n \"");
-                    command_str.append(m_option_data.m_process_name);
-                    command_str.push_back('\"');
-                    if (m_option_data.m_wait_for)
-                        command_str.append(" -w");
-                }
-                
-                if (m_debugger.GetOutputFileHandle())
-                    ::fprintf (m_debugger.GetOutputFileHandle(), 
-                               "Attaching to process with:\n    %s\n", 
-                               command_str.c_str());
-                                               
-                // Force the attach to be synchronous:
-                bool orig_async = m_debugger.GetAsync();
-                m_debugger.SetAsync(true);
-                m_debugger.HandleCommand(command_str.c_str());
-                m_debugger.SetAsync(orig_async);                
-            }
-                        
-            ReadyForCommand ();
-
-            while (!GetIsDone())
-            {
-                listener.WaitForEvent (UINT32_MAX, event);
-                if (event.IsValid())
-                {
-                    if (event.GetBroadcaster().IsValid())
-                    {
-                        uint32_t event_type = event.GetType();
-                        if (event.BroadcasterMatchesRef (*m_io_channel_ap))
-                        {
-                            if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) ||
-                                (event_type & IOChannel::eBroadcastBitThreadDidExit))
-                            {
-                                SetIsDone();
-                                if (event_type & IOChannel::eBroadcastBitThreadDidExit)
-                                    iochannel_thread_exited = true;
-                            }
-                            else
-                            {
-                                if (HandleIOEvent (event))
-                                    SetIsDone();
-                            }
-                        }
-                        else if (SBProcess::EventIsProcessEvent (event))
-                        {
-                            HandleProcessEvent (event);
-                        }
-                        else if (SBBreakpoint::EventIsBreakpointEvent (event))
-                        {
-                            HandleBreakpointEvent (event);
-                        }
-                        else if (SBThread::EventIsThreadEvent (event))
-                        {
-                            HandleThreadEvent (event);
-                        }
-                        else if (event.BroadcasterMatchesRef (sb_interpreter.GetBroadcaster()))
-                        {
-                            // TODO: deprecate the eBroadcastBitQuitCommandReceived event
-                            // now that we have SBCommandInterpreter::SetCommandOverrideCallback()
-                            // that can take over a command
-                            if (event_type & SBCommandInterpreter::eBroadcastBitQuitCommandReceived)
-                            {
-                                SetIsDone();
-                            }
-                            else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousErrorData)
-                            {
-                                const char *data = SBEvent::GetCStringFromEvent (event);
-                                m_io_channel_ap->ErrWrite (data, strlen(data), ASYNC);
-                            }
-                            else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousOutputData)
-                            {
-                                const char *data = SBEvent::GetCStringFromEvent (event);
-                                m_io_channel_ap->OutWrite (data, strlen(data), ASYNC);
-                            }
-                        }
-                    }
-                }
-            }
-
-            master_out_comm.SetReadThreadBytesReceivedCallback(NULL, NULL);
-            master_out_comm.Disconnect();
-            master_out_comm.ReadThreadStop();
-
-#if !defined(_MSC_VER)
-            out_comm_2.SetReadThreadBytesReceivedCallback(NULL, NULL);
-            out_comm_2.Disconnect();
-            out_comm_2.ReadThreadStop();
-#endif
-
-            editline_output_pty.CloseMasterFileDescriptor();
-            reset_stdin_termios();
-            fclose (stdin);
-
-            CloseIOChannelFile ();
-
-            if (!iochannel_thread_exited)
-            {
-                event.Clear();
-                listener.GetNextEventForBroadcasterWithType (*m_io_channel_ap,
-                                                             IOChannel::eBroadcastBitThreadDidExit,
-                                                             event);
-                if (!event.IsValid())
-                {
-                    // Send end EOF to the driver file descriptor
-                    m_io_channel_ap->Stop();
-                }
-            }
-
-            SBDebugger::Destroy (m_debugger);
         }
     }
-}
-
-
-void
-Driver::ReadyForCommand ()
-{
-    if (m_waiting_for_command == false)
+    else if (!core_file_spec.empty())
     {
-        m_waiting_for_command = true;
-        BroadcastEventByType (Driver::eBroadcastBitReadyForInput, true);
+        ::snprintf (command_string,
+                    sizeof(command_string),
+                    "target create %s",
+                    core_file_spec.c_str());
+        m_debugger.HandleCommand (command_string);;
     }
+
+    ExecuteInitialCommands(false);
+
+    // Now that all option parsing is done, we try and parse the .lldbinit
+    // file in the current working directory
+    sb_interpreter.SourceInitFileInCurrentWorkingDirectory (result);
+    if (GetDebugMode())
+    {
+        result.PutError(m_debugger.GetErrorFileHandle());
+        result.PutOutput(m_debugger.GetOutputFileHandle());
+    }
+    
+    bool handle_events = true;
+    bool spawn_thread = false;
+    m_debugger.RunCommandInterpreter(handle_events, spawn_thread);
+    
+    reset_stdin_termios();
+    fclose (stdin);
+    
+    SBDebugger::Destroy (m_debugger);
 }
 
+
 void
 Driver::ResizeWindow (unsigned short col)
 {
     GetDebugger().SetTerminalWidth (col);
-    if (m_io_channel_ap.get() != NULL)
-    {
-        m_io_channel_ap->ElResize();
-    }
 }
 
 void
diff --git a/lldb/tools/driver/Driver.h b/lldb/tools/driver/Driver.h
index dcfd5ed..6992446 100644
--- a/lldb/tools/driver/Driver.h
+++ b/lldb/tools/driver/Driver.h
@@ -22,27 +22,15 @@
 #include "lldb/API/SBBroadcaster.h"
 #include "lldb/API/SBDebugger.h"
 #include "lldb/API/SBError.h"
-#include "lldb/API/SBInputReader.h"
 
 #define ASYNC true
 #define NO_ASYNC false
 
 class IOChannel;
 
-namespace lldb
-{
-    class SBInputReader;
-}
-
-
 class Driver : public lldb::SBBroadcaster
 {
 public:
-    enum {
-        eBroadcastBitReadyForInput    = (1 << 0),
-        eBroadcastBitThreadShouldExit = (1 << 1)
-    };
-
     Driver ();
 
     virtual
@@ -51,24 +39,6 @@
     void
     MainLoop ();
 
-    void
-    PutSTDIN (const char *src, size_t src_len);
-
-    void
-    GetFromMaster (const char *src, size_t src_len);
-
-    bool
-    HandleIOEvent (const lldb::SBEvent &event);
-
-    void
-    HandleProcessEvent (const lldb::SBEvent &event);
-
-    void
-    HandleBreakpointEvent (const lldb::SBEvent &event);
-
-    void
-    HandleThreadEvent (const lldb::SBEvent &event);
-
     lldb::SBError
     ParseArgs (int argc, const char *argv[], FILE *out_fh, bool &do_exit);
 
@@ -137,66 +107,16 @@
         return m_debugger;
     }
     
-    bool
-    EditlineReaderIsTop ()
-    {
-        return m_debugger.InputReaderIsTopReader (m_editline_reader);
-    }
-
-    bool
-    GetIsDone () const
-    {
-        return m_done;
-    }
-
-    void
-    SetIsDone ()
-    {
-        m_done = true;
-    }
-    
     void
     ResizeWindow (unsigned short col);
 
 private:
     lldb::SBDebugger m_debugger;
-    lldb_utility::PseudoTerminal m_editline_pty;
-    FILE *m_editline_slave_fh;
-    lldb::SBInputReader m_editline_reader;
-    std::unique_ptr<IOChannel> m_io_channel_ap;
     OptionData m_option_data;
-    bool m_executing_user_command;
-    bool m_waiting_for_command;
-    bool m_done;
 
     void
     ResetOptionValues ();
 
-    size_t
-    GetProcessSTDOUT ();
-
-    size_t
-    GetProcessSTDERR ();
-
-    void
-    UpdateSelectedThread ();
-
-    void
-    CloseIOChannelFile ();
-
-    static size_t
-    EditLineInputReaderCallback (void *baton, 
-                                 lldb::SBInputReader *reader, 
-                                 lldb::InputReaderAction notification,
-                                 const char *bytes, 
-                                 size_t bytes_len);
-
-    static void
-    ReadThreadBytesReceived (void *baton, const void *src, size_t src_len);
-
-    static void
-    MasterThreadBytesReceived (void *baton, const void *src, size_t src_len);
-    
     void
     ReadyForCommand ();
 };
diff --git a/lldb/tools/driver/IOChannel.cpp b/lldb/tools/driver/IOChannel.cpp
deleted file mode 100644
index 7cba73a..0000000
--- a/lldb/tools/driver/IOChannel.cpp
+++ /dev/null
@@ -1,656 +0,0 @@
-//===-- IOChannel.cpp -------------------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Platform.h"
-#include "IOChannel.h"
-
-#include <map>
-
-#include "lldb/API/SBCommandInterpreter.h"
-#include "lldb/API/SBDebugger.h"
-#include "lldb/API/SBError.h"
-#include "lldb/API/SBEvent.h"
-#include "lldb/API/SBFileSpec.h"
-#include "lldb/API/SBHostOS.h"
-#include "lldb/API/SBListener.h"
-#include "lldb/API/SBStringList.h"
-
-#include <string.h>
-#include <limits.h>
-
-using namespace lldb;
-
-typedef std::map<EditLine *, std::string> PromptMap;
-const char *g_default_prompt = "(lldb) ";
-PromptMap g_prompt_map;
-
-// Printing the following string causes libedit to back up to the beginning of the line & blank it out.
-const char undo_prompt_string[4] = { (char) 13, (char) 27, (char) 91, (char) 75};
-
-static const char*
-el_prompt(EditLine *el)
-{
-    PromptMap::const_iterator pos = g_prompt_map.find (el);
-    if (pos == g_prompt_map.end())
-        return g_default_prompt;
-    return pos->second.c_str();
-}
-
-const char *
-IOChannel::GetPrompt ()
-{
-    PromptMap::const_iterator pos = g_prompt_map.find (m_edit_line);
-    if (pos == g_prompt_map.end())
-        return g_default_prompt;
-    return pos->second.c_str();
-}
-
-bool
-IOChannel::EditLineHasCharacters ()
-{
-    const LineInfo *line_info  = el_line(m_edit_line);
-    if (line_info)
-    {
-        // Sometimes we get called after the user has submitted the line, but before editline has
-        // cleared the buffer.  In that case the cursor will be pointing at the newline.  That's
-        // equivalent to having no characters on the line, since it has already been submitted.
-        if (*line_info->cursor == '\n')
-            return false;
-        else
-            return line_info->cursor != line_info->buffer;
-    }
-    else
-        return false;
-}
-
-
-void
-IOChannel::EraseCharsBeforeCursor ()
-{
-    const LineInfo *line_info  = el_line(m_edit_line);
-    if (line_info != NULL)
-        el_deletestr(m_edit_line, line_info->cursor - line_info->buffer);
-}
-
-unsigned char
-IOChannel::ElCompletionFn (EditLine *e, int ch)
-{
-    IOChannel *io_channel;
-    if (el_get(e, EL_CLIENTDATA, &io_channel) == 0)
-    {
-        return io_channel->HandleCompletion (e, ch);
-    }
-    else
-    {
-        return CC_ERROR;
-    }
-}
-
-void
-IOChannel::ElResize()
-{
-    el_resize(m_edit_line);
-}
-
-unsigned char
-IOChannel::HandleCompletion (EditLine *e, int ch)
-{
-    assert (e == m_edit_line);
-
-    const LineInfo *line_info  = el_line(m_edit_line);
-    SBStringList completions;
-    int page_size = 40;
-
-    int num_completions = m_driver->GetDebugger().GetCommandInterpreter().HandleCompletion (line_info->buffer,
-                                                                                            line_info->cursor,
-                                                                                            line_info->lastchar,
-                                                                                            0,
-                                                                                            -1,
-                                                                                            completions);
-    
-    if (num_completions == -1)
-    {
-        el_insertstr (m_edit_line, m_completion_key);
-        return CC_REDISPLAY;
-    }
-    else if (num_completions == -2)
-    {
-        el_deletestr (m_edit_line, line_info->cursor - line_info->buffer);
-        el_insertstr (m_edit_line, completions.GetStringAtIndex(0));
-        return CC_REDISPLAY;
-    }
-
-    // If we get a longer match display that first.
-    const char *completion_str = completions.GetStringAtIndex(0);
-    if (completion_str != NULL && *completion_str != '\0')
-    {
-        el_insertstr (m_edit_line, completion_str);
-        return CC_REDISPLAY;
-    }
-
-    if (num_completions > 1)
-    {
-        const char *comment = "\nAvailable completions:";
-
-        int num_elements = num_completions + 1;
-        OutWrite(comment,  strlen (comment), NO_ASYNC);
-        if (num_completions < page_size)
-        {
-            for (int i = 1; i < num_elements; i++)
-            {
-                completion_str = completions.GetStringAtIndex(i);
-                OutWrite("\n\t", 2, NO_ASYNC);
-                OutWrite(completion_str, strlen (completion_str), NO_ASYNC);
-            }
-            OutWrite ("\n", 1, NO_ASYNC);
-        }
-        else
-        {
-            int cur_pos = 1;
-            char reply;
-            int got_char;
-            while (cur_pos < num_elements)
-            {
-                int endpoint = cur_pos + page_size;
-                if (endpoint > num_elements)
-                    endpoint = num_elements;
-                for (; cur_pos < endpoint; cur_pos++)
-                {
-                    completion_str = completions.GetStringAtIndex(cur_pos);
-                    OutWrite("\n\t", 2, NO_ASYNC);
-                    OutWrite(completion_str, strlen (completion_str), NO_ASYNC);
-                }
-
-                if (cur_pos >= num_elements)
-                {
-                    OutWrite("\n", 1, NO_ASYNC);
-                    break;
-                }
-
-                OutWrite("\nMore (Y/n/a): ", strlen ("\nMore (Y/n/a): "), NO_ASYNC);
-                reply = 'n';
-                got_char = el_getc(m_edit_line, &reply);
-                if (got_char == -1 || reply == 'n')
-                    break;
-                if (reply == 'a')
-                    page_size = num_elements - cur_pos;
-            }
-        }
-
-    }
-
-    if (num_completions == 0)
-        return CC_REFRESH_BEEP;
-    else
-        return CC_REDISPLAY;
-}
-
-IOChannel::IOChannel
-(
-    FILE *editline_in,
-    FILE *editline_out,
-    FILE *out,  
-    FILE *err,
-    Driver *driver
-) :
-    SBBroadcaster ("IOChannel"),
-    m_output_mutex (),
-    m_enter_elgets_time (),
-    m_driver (driver),
-    m_read_thread (LLDB_INVALID_HOST_THREAD),
-    m_read_thread_should_exit (false),
-    m_out_file (out),
-    m_err_file (err),
-    m_editline_out (editline_out),
-    m_command_queue (),
-    m_completion_key ("\t"),
-    m_edit_line (::el_init (SBHostOS::GetProgramFileSpec().GetFilename(), editline_in, editline_out,  editline_out)),
-    m_history (history_init()),
-    m_history_event(),
-    m_getting_command (false),
-    m_expecting_prompt (false),
-    m_prompt_str (),
-    m_refresh_request_pending (false)
-{
-    assert (m_edit_line);
-    el_set (m_edit_line, EL_PROMPT, el_prompt);
-    el_set (m_edit_line, EL_EDITOR, "emacs");
-    el_set (m_edit_line, EL_HIST, history, m_history);
-    el_set (m_edit_line, EL_ADDFN, "lldb_complete", "LLDB completion function", IOChannel::ElCompletionFn);
-    el_set (m_edit_line, EL_BIND, m_completion_key, "lldb_complete", NULL);
-    el_set (m_edit_line, EL_BIND, "^r", "em-inc-search-prev", NULL);  // Cycle through backwards search, entering string
-    el_set (m_edit_line, EL_BIND, "^w", "ed-delete-prev-word", NULL); // Delete previous word, behave like bash does.
-    el_set (m_edit_line, EL_BIND, "\033[3~", "ed-delete-next-char", NULL); // Fix the delete key.
-    el_set (m_edit_line, EL_CLIENTDATA, this);
-
-    // Source $PWD/.editrc then $HOME/.editrc
-    el_source (m_edit_line, NULL);
-
-    assert (m_history);
-    history (m_history, &m_history_event, H_SETSIZE, 800);
-    history (m_history, &m_history_event, H_SETUNIQUE, 1);
-    // Load history
-    HistorySaveLoad (false);
-
-    // Initialize time that ::el_gets was last called.
-    m_enter_elgets_time.tv_sec = 0;
-    m_enter_elgets_time.tv_usec = 0;
-
-    // set the initial state to non flushed
-    m_output_flushed = false;
-}
-
-IOChannel::~IOChannel ()
-{
-    // Save history
-    HistorySaveLoad (true);
-
-    if (m_history != NULL)
-    {
-        ::history_end (m_history);
-        m_history = NULL;
-    }
-
-    if (m_edit_line != NULL)
-    {
-        ::el_end (m_edit_line);
-        m_edit_line = NULL;
-    }
-}
-
-void
-IOChannel::HistorySaveLoad (bool save)
-{
-    if (m_history != NULL)
-    {
-        char history_path[PATH_MAX];
-        ::snprintf (history_path, sizeof(history_path), "~/.%s-history", SBHostOS::GetProgramFileSpec().GetFilename());
-        if ((size_t)SBFileSpec::ResolvePath (history_path, history_path, sizeof(history_path)) < sizeof(history_path) - 1)
-        {
-            const char *path_ptr = history_path;
-            if (save)
-                ::history (m_history, &m_history_event, H_SAVE, path_ptr);
-            else
-                ::history (m_history, &m_history_event, H_LOAD, path_ptr);
-        }
-    }
-}
-
-void
-IOChannel::LibeditOutputBytesReceived (void *baton, const void *src, size_t src_len)
-{
-    IOChannel *io_channel = (IOChannel *) baton;
-    std::lock_guard<std::recursive_mutex> locker(io_channel->m_output_mutex);
-    const char *bytes = (const char *) src;
-
-    bool flush = false;
-
-    // See if we have a 'flush' synchronization point in there.
-    // this is performed from 'fputc ('\0', m_editline_out);' in LibeditGetInput()
-    if (src_len > 0 && bytes[src_len-1] == '\0')
-    {
-        src_len--;
-        flush = true;
-    }
-
-    if (io_channel->IsGettingCommand() && io_channel->m_expecting_prompt)
-    {
-        io_channel->m_prompt_str.append (bytes, src_len);
-        // Log this to make sure the prompt is really what you think it is.
-        if (io_channel->m_prompt_str.find (el_prompt(io_channel->m_edit_line)) == 0)
-        {
-            io_channel->m_expecting_prompt = false;
-            io_channel->m_refresh_request_pending = false;
-            io_channel->OutWrite (io_channel->m_prompt_str.c_str(), 
-                                  io_channel->m_prompt_str.size(), NO_ASYNC);
-            io_channel->m_prompt_str.clear();
-        }
-    }
-    else
-    {
-        if (io_channel->m_prompt_str.size() > 0)
-            io_channel->m_prompt_str.clear();
-        std::string tmp_str (bytes, src_len);
-        if (tmp_str.find (el_prompt (io_channel->m_edit_line)) == 0)
-            io_channel->m_refresh_request_pending = false;
-        io_channel->OutWrite (bytes, src_len, NO_ASYNC);
-    }
-
-#if !defined (_MSC_VER)
-    if (flush)
-    {
-        io_channel->m_output_flushed = true;
-        io_channel->m_output_cond.notify_all();
-    }
-#endif
-
-}
-
-IOChannel::LibeditGetInputResult
-IOChannel::LibeditGetInput (std::string &new_line)
-{
-    IOChannel::LibeditGetInputResult retval = IOChannel::eLibeditGetInputResultUnknown;
-    if (m_edit_line != NULL)
-    {
-        int line_len = 0;
-
-        // Set boolean indicating whether or not el_gets is trying to get input (i.e. whether or not to attempt
-        // to refresh the prompt after writing data).
-        SetGettingCommand (true);
-        m_expecting_prompt = true;
-
-        // Call el_gets to prompt the user and read the user's input.
-        const char *line = ::el_gets (m_edit_line, &line_len);
-
-#if !defined (_MSC_VER)
-        // Force the piped output from el_gets to finish processing.
-        // el_gets does an fflush internally, which is not sufficient here; it only
-        // writes the data into m_editline_out, but doesn't affect whether our worker
-        // thread will read that data yet. So we block here manually.
-        {
-            std::lock_guard<std::recursive_mutex> locker(m_output_mutex);
-            m_output_flushed = false;
-
-            // Write a synchronization point into the stream, so we can guarantee
-            // LibeditOutputBytesReceived has processed everything up till that mark.
-            fputc ('\0', m_editline_out);
-
-            while (!m_output_flushed)
-            {
-                // wait until the condition variable is signaled
-                m_output_cond.wait(m_output_mutex);
-            }
-        }
-#endif
-
-        // Re-set the boolean indicating whether or not el_gets is trying to get input.
-        SetGettingCommand (false);
-
-        if (line)
-        {
-            retval = IOChannel::eLibeditGetInputValid;
-            // strip any newlines off the end of the string...
-            while (line_len > 0 && (line[line_len - 1] == '\n' || line[line_len - 1] == '\r'))
-                --line_len;
-            if (line_len > 0)
-            {
-                ::history (m_history, &m_history_event, H_ENTER, line);
-                new_line.assign (line, line_len);   // Omit the newline
-            }
-            else
-            {
-                retval = IOChannel::eLibeditGetInputEmpty;
-                // Someone just hit ENTER, return the empty string
-                new_line.clear();
-            }
-            // Return true to indicate success even if a string is empty
-            return retval;
-        }
-        else
-        {
-            retval = (line_len == 0 ? IOChannel::eLibeditGetInputEOF : IOChannel::eLibeditGetInputResultError);
-        }
-    }
-    // Return false to indicate failure. This can happen when the file handle
-    // is closed (EOF).
-    new_line.clear();
-    return retval;
-}
-
-thread_result_t
-IOChannel::IOReadThread (void *ptr)
-{
-    IOChannel *myself = static_cast<IOChannel *> (ptr);
-    myself->Run();
-    return NULL;
-}
-
-void
-IOChannel::Run ()
-{
-    SBListener listener("IOChannel::Run");
-    std::string new_line;
-
-    SBBroadcaster interpreter_broadcaster (m_driver->GetDebugger().GetCommandInterpreter().GetBroadcaster());
-    listener.StartListeningForEvents (interpreter_broadcaster,
-                                      SBCommandInterpreter::eBroadcastBitResetPrompt |
-                                      SBCommandInterpreter::eBroadcastBitThreadShouldExit |
-                                      SBCommandInterpreter::eBroadcastBitQuitCommandReceived);
-
-    listener.StartListeningForEvents (*this,
-                                      IOChannel::eBroadcastBitThreadShouldExit);
-
-    listener.StartListeningForEvents (*m_driver,
-                                      Driver::eBroadcastBitReadyForInput |
-                                      Driver::eBroadcastBitThreadShouldExit);
-
-    // Let anyone know that the IO channel is up and listening and ready for events
-    BroadcastEventByType (eBroadcastBitThreadDidStart);
-    bool done = false;
-    while (!done)
-    {
-        SBEvent event;
-
-        listener.WaitForEvent (UINT32_MAX, event);
-        if (!event.IsValid())
-            continue;
-
-        const uint32_t event_type = event.GetType();
-
-        if (event.GetBroadcaster().IsValid())
-        {
-            if (event.BroadcasterMatchesPtr (m_driver))
-            {
-                if (event_type & Driver::eBroadcastBitReadyForInput)
-                {
-                    std::string line;
-
-                    if (CommandQueueIsEmpty())
-                    {
-                        IOChannel::LibeditGetInputResult getline_result = LibeditGetInput(line);
-                        if (getline_result == IOChannel::eLibeditGetInputEOF)
-                        {
-                            // EOF occurred
-                            // pretend that a quit was typed so the user gets a potential
-                            // chance to confirm
-                            line.assign("quit");
-                        }
-                        else if (getline_result == IOChannel::eLibeditGetInputResultError || getline_result == IOChannel::eLibeditGetInputResultUnknown)
-                        {
-                            // some random error occurred, exit and don't ask because the state might be corrupt
-                            done = true;
-                            continue;
-                        }
-                    }
-                    else
-                    {
-                        GetCommandFromQueue (line);
-                    }
-
-                    // TO BE DONE: FIGURE OUT WHICH COMMANDS SHOULD NOT BE REPEATED IF USER PRESSES PLAIN 'RETURN'
-                    // AND TAKE CARE OF THAT HERE.
-
-                    SBEvent line_event(IOChannel::eBroadcastBitHasUserInput,
-                             line.c_str(),
-                             line.size());
-                    BroadcastEvent (line_event);
-                }
-                else if (event_type & Driver::eBroadcastBitThreadShouldExit)
-                {
-                    done = true;
-                    continue;
-                }
-            }
-            else if (event.BroadcasterMatchesRef (interpreter_broadcaster))
-            {
-                switch (event_type)
-                {
-                case SBCommandInterpreter::eBroadcastBitResetPrompt:
-                    {
-                        const char *new_prompt = SBEvent::GetCStringFromEvent (event);
-                        if (new_prompt)
-                            g_prompt_map[m_edit_line] = new_prompt;
-                    }
-                    break;
-
-                case SBCommandInterpreter::eBroadcastBitThreadShouldExit:
-                case SBCommandInterpreter::eBroadcastBitQuitCommandReceived:
-                    done = true;
-                    break;
-                }
-            }
-            else if (event.BroadcasterMatchesPtr (this))
-            {
-                if (event_type & IOChannel::eBroadcastBitThreadShouldExit)
-                {
-                    done = true;
-                    continue;
-                }
-            }
-        }
-    }
-    BroadcastEventByType (IOChannel::eBroadcastBitThreadDidExit);
-    m_driver = NULL;
-    m_read_thread = 0;
-}
-
-bool
-IOChannel::Start ()
-{
-    if (IS_VALID_LLDB_HOST_THREAD(m_read_thread))
-        return true;
-
-    m_read_thread = SBHostOS::ThreadCreate("<lldb.driver.commandline_io>", (lldb::thread_func_t) IOChannel::IOReadThread, this, NULL);
-
-    return (IS_VALID_LLDB_HOST_THREAD(m_read_thread));
-}
-
-bool
-IOChannel::Stop ()
-{
-    if (!IS_VALID_LLDB_HOST_THREAD(m_read_thread))
-        return true;
-
-    BroadcastEventByType (eBroadcastBitThreadShouldExit);
-
-    // Don't call Host::ThreadCancel since el_gets won't respond to this
-    // function call -- the thread will just die and all local variables in
-    // IOChannel::Run() won't get destructed down which is bad since there is
-    // a local listener holding onto broadcasters... To ensure proper shutdown,
-    // a ^D (control-D) sequence (0x04) should be written to other end of the
-    // the "in" file handle that was passed into the contructor as closing the
-    // file handle doesn't seem to make el_gets() exit....
-    return SBHostOS::ThreadJoin (m_read_thread, NULL, NULL);
-}
-
-void
-IOChannel::RefreshPrompt ()
-{
-    // If we are not in the middle of getting input from the user, there is no need to 
-    // refresh the prompt.
-    std::lock_guard<std::recursive_mutex> locker(m_output_mutex);
-    if (! IsGettingCommand())
-        return;
-
-    // If we haven't finished writing the prompt, there's no need to refresh it.
-    if (m_expecting_prompt)
-        return;
-
-    if (m_refresh_request_pending)
-        return;
-
-    ::el_set (m_edit_line, EL_REFRESH);
-    m_refresh_request_pending = true;    
-}
-
-void
-IOChannel::OutWrite (const char *buffer, size_t len, bool asynchronous)
-{
-    if (len == 0 || buffer == NULL)
-        return;
-
-    // We're in the process of exiting -- IOChannel::Run() has already completed
-    // and set m_driver to NULL - it is time for us to leave now.  We might not
-    // print the final ^D to stdout in this case.  We need to do some re-work on
-    // how the I/O streams are managed at some point.
-    if (m_driver == NULL)
-    {
-        return;
-    }
-
-    // Use the mutex to make sure OutWrite and ErrWrite do not interfere with each other's output.
-    std::lock_guard<std::recursive_mutex> locker(m_output_mutex);
-    if (m_driver->EditlineReaderIsTop() && asynchronous)
-        ::fwrite (undo_prompt_string, 1, 4, m_out_file);
-    ::fwrite (buffer, 1, len, m_out_file);
-    if (asynchronous)
-        m_driver->GetDebugger().NotifyTopInputReader (eInputReaderAsynchronousOutputWritten);
-}
-
-void
-IOChannel::ErrWrite (const char *buffer, size_t len, bool asynchronous)
-{
-    if (len == 0 || buffer == NULL)
-        return;
-
-    // Use the mutex to make sure OutWrite and ErrWrite do not interfere with each other's output.
-    std::lock_guard<std::recursive_mutex> locker(m_output_mutex);
-    if (asynchronous)
-        ::fwrite (undo_prompt_string, 1, 4, m_err_file);
-    ::fwrite (buffer, 1, len, m_err_file);
-    if (asynchronous)
-        m_driver->GetDebugger().NotifyTopInputReader (eInputReaderAsynchronousOutputWritten);
-}
-
-void
-IOChannel::AddCommandToQueue (const char *command)
-{
-    m_command_queue.push (std::string(command));
-}
-
-bool
-IOChannel::GetCommandFromQueue (std::string &cmd)
-{
-    if (m_command_queue.empty())
-        return false;
-    cmd.swap(m_command_queue.front());
-    m_command_queue.pop ();
-    return true;
-}
-
-int
-IOChannel::CommandQueueSize () const
-{
-    return m_command_queue.size();
-}
-
-void
-IOChannel::ClearCommandQueue ()
-{
-    while (!m_command_queue.empty())
-        m_command_queue.pop();
-}
-
-bool
-IOChannel::CommandQueueIsEmpty () const
-{
-    return m_command_queue.empty();
-}
-
-bool
-IOChannel::IsGettingCommand () const
-{
-    return m_getting_command;
-}
-
-void
-IOChannel::SetGettingCommand (bool new_value)
-{
-    m_getting_command = new_value;
-}
diff --git a/lldb/tools/driver/IOChannel.h b/lldb/tools/driver/IOChannel.h
deleted file mode 100644
index 3788673..0000000
--- a/lldb/tools/driver/IOChannel.h
+++ /dev/null
@@ -1,154 +0,0 @@
-//===-- IOChannel.h ---------------------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef lldb_IOChannel_h_
-#define lldb_IOChannel_h_
-
-#include <thread>
-#include <mutex>
-#include <atomic>
-#include <condition_variable>
-
-#include <string>
-#include <queue>
-#include "Driver.h"
-
-class IOChannel : public lldb::SBBroadcaster
-{
-public:
-    enum {
-        eBroadcastBitHasUserInput     = (1 << 0),
-        eBroadcastBitUserInterrupt    = (1 << 1),
-        eBroadcastBitThreadShouldExit = (1 << 2),
-        eBroadcastBitThreadDidExit    = (1 << 3),
-        eBroadcastBitThreadDidStart   = (1 << 4),
-        eBroadcastBitsSTDOUT          = (1 << 5),
-        eBroadcastBitsSTDERR          = (1 << 6),
-        eBroadcastBitsSTDIN           = (1 << 7),
-        eAllEventBits                 = 0xffffffff
-    };
-    
-    enum LibeditGetInputResult
-    {
-        eLibeditGetInputEOF = 0,
-        eLibeditGetInputValid = 1,
-        eLibeditGetInputEmpty = 2,
-        eLibeditGetInputResultError = 4,
-        eLibeditGetInputResultUnknown = 0xffffffff
-    };
-
-    IOChannel (FILE *editline_in,
-               FILE *editline_out,
-               FILE *out,
-               FILE *err,
-               Driver *driver = NULL);
-
-    virtual
-    ~IOChannel ();
-
-    bool
-    Start ();
-
-    bool
-    Stop ();
-
-    static lldb::thread_result_t
-    IOReadThread (void *);
-
-    void
-    Run ();
-
-    void
-    OutWrite (const char *buffer, size_t len, bool asynchronous);
-
-    void
-    ErrWrite (const char *buffer, size_t len, bool asynchronous);
-
-    LibeditGetInputResult
-    LibeditGetInput (std::string &);
-    
-    static void
-    LibeditOutputBytesReceived (void *baton, const void *src,size_t src_len);
-
-    void
-    SetPrompt ();
-
-    void
-    RefreshPrompt ();
-
-    void
-    AddCommandToQueue (const char *command);
-
-    bool
-    GetCommandFromQueue (std::string &cmd);
-
-    int
-    CommandQueueSize () const;
-
-    void
-    ClearCommandQueue ();
-
-    bool
-    CommandQueueIsEmpty () const;
-
-    const char *
-    GetPrompt ();
-
-    bool
-    EditLineHasCharacters ();
-    
-    void
-    EraseCharsBeforeCursor ();
-
-    static unsigned char 
-    ElCompletionFn (EditLine *e, int ch);
-    
-    void
-    ElResize();
-
-protected:
-
-    bool
-    IsGettingCommand () const;
-
-    void
-    SetGettingCommand (bool new_value);
-
-private:
-
-    std::recursive_mutex m_output_mutex;
-    std::condition_variable_any m_output_cond;
-    struct timeval m_enter_elgets_time;
-
-    Driver *m_driver;
-    lldb::thread_t m_read_thread;
-    bool m_read_thread_should_exit;
-    FILE *m_out_file;
-    FILE *m_err_file;
-    FILE *m_editline_out;
-    std::queue<std::string> m_command_queue;
-    const char *m_completion_key;
-
-    EditLine *m_edit_line;
-    History *m_history;
-    HistEvent m_history_event;
-    bool m_getting_command;
-    bool m_expecting_prompt;
-    bool m_output_flushed;
-    std::string m_prompt_str;  // for accumlating the prompt as it gets written out by editline
-    bool m_refresh_request_pending;
-
-    void
-    HistorySaveLoad (bool save);
-
-    unsigned char
-    HandleCompletion (EditLine *e, int ch);
-};
-
-#endif  // lldb_IOChannel_h_