diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp
new file mode 100644
index 0000000..07777a1
--- /dev/null
+++ b/lldb/source/Commands/CommandObjectThread.cpp
@@ -0,0 +1,1277 @@
+//===-- CommandObjectThread.cpp ---------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CommandObjectThread.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Options.h"
+#include "lldb/Core/State.h"
+#include "lldb/Core/SourceManager.h"
+
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+#include "lldb/Target/ThreadPlanContinue.h"
+#include "lldb/Target/ThreadPlanStepInstruction.h"
+#include "lldb/Target/ThreadPlanStepOut.h"
+#include "lldb/Target/ThreadPlanStepRange.h"
+#include "lldb/Target/ThreadPlanStepInRange.h"
+#include "lldb/Symbol/LineTable.h"
+#include "lldb/Symbol/LineEntry.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+
+bool
+lldb_private::DisplayThreadInfo
+(
+    CommandInterpreter *interpreter,
+    Stream &strm,
+    Thread *thread,
+    bool only_threads_with_stop_reason,
+    bool show_source
+)
+{
+    if (thread)
+    {
+        if (only_threads_with_stop_reason)
+        {
+            StopReason thread_stop_reason = eStopReasonNone;
+            Thread::StopInfo thread_stop_info;
+            if (thread->GetStopInfo(&thread_stop_info))
+            {
+                thread_stop_reason = thread_stop_info.GetStopReason();
+                if (thread_stop_reason == eStopReasonNone)
+                    return false;
+            }
+        }
+
+        strm.Indent();
+        strm.Printf("%c ", thread->GetProcess().GetThreadList().GetCurrentThread().get() == thread ? '*' : ' ');
+
+        // Show one frame with only the first showing source
+        if (show_source)
+        {
+            DisplayFramesForExecutionContext (thread,
+                                              interpreter,
+                                              strm,
+                                              true,
+                                              0,    // Start at first frame
+                                              1,    // Number of frames to show
+                                              false,// Don't show the frame info since we already displayed most of it above...
+                                              1,    // Show source for the first frame
+                                              3,    // lines of source context before
+                                              3);   // lines of source context after
+        }
+        else
+        {
+            thread->DumpInfo (strm,
+                              true, // Dump the stop reason?
+                              true, // Dump the thread name?
+                              true, // Dump the queue name?
+                              0);   // Display context info for stack frame zero
+
+            strm.EOL();
+        }
+
+        return true;
+    }
+    return false;
+}
+
+size_t
+lldb_private::DisplayThreadsInfo
+(
+    CommandInterpreter *interpreter,
+    ExecutionContext *exe_ctx,
+    CommandReturnObject &result,
+    bool only_threads_with_stop_reason,
+    bool show_source
+)
+{
+    StreamString strm;
+
+    size_t num_thread_infos_dumped = 0;
+
+    if (!exe_ctx->process)
+        return 0;
+
+    const size_t num_threads = exe_ctx->process->GetThreadList().GetSize();
+    if (num_threads > 0)
+    {
+
+        for (uint32_t i = 0; i < num_threads; i++)
+        {
+            Thread *thread = exe_ctx->process->GetThreadList().GetThreadAtIndex(i).get();
+            if (thread)
+            {
+                if (DisplayThreadInfo (interpreter,
+                                       strm,
+                                       thread,
+                                       only_threads_with_stop_reason,
+                                       show_source))
+                    ++num_thread_infos_dumped;
+            }
+        }
+    }
+
+    if (num_thread_infos_dumped > 0)
+    {
+        if (num_thread_infos_dumped < num_threads)
+            result.GetOutputStream().Printf("%u of %u threads stopped with reasons:\n", num_thread_infos_dumped, num_threads);
+
+        result.GetOutputStream().GetString().append(strm.GetString());
+        result.SetStatus (eReturnStatusSuccessFinishNoResult);
+    }
+    return num_thread_infos_dumped;
+}
+
+
+size_t
+lldb_private::DisplayFramesForExecutionContext
+(
+    Thread *thread,
+    CommandInterpreter *interpreter,
+    Stream& strm,
+    bool ascending,
+    uint32_t first_frame,
+    uint32_t num_frames,
+    bool show_frame_info,
+    uint32_t num_frames_with_source,
+    uint32_t source_lines_before,
+    uint32_t source_lines_after
+)
+{
+    if (thread == NULL)
+        return 0;
+
+    size_t num_frames_displayed = 0;
+
+    if (num_frames == 0)
+        return 0;
+    
+    thread->DumpInfo (strm,
+                      true,     // Dump the stop reason?
+                      true,     // Dump the thread name?
+                      true,     // Dump the queue name?
+                      0);       // Dump info for stack frame zero
+    strm.EOL();
+    strm.IndentMore();
+
+    StackFrameSP frame_sp;
+    int frame_idx = 0;
+
+    if (ascending)
+    {
+        for (frame_idx = first_frame; frame_idx < first_frame + num_frames; ++frame_idx)
+        {
+            frame_sp = thread->GetStackFrameAtIndex (frame_idx);
+            if (frame_sp.get() == NULL)
+                break;
+
+            if (DisplayFrameForExecutionContext (thread,
+                                                 frame_sp.get(),
+                                                 interpreter,
+                                                 strm,
+                                                 show_frame_info,
+                                                 num_frames_with_source > first_frame - frame_idx,
+                                                 source_lines_before,
+                                                 source_lines_after) == false)
+                break;
+
+            ++num_frames_displayed;
+        }
+    }
+    else
+    {
+        for (frame_idx = first_frame + num_frames - 1; frame_idx >= first_frame; --frame_idx)
+        {
+            frame_sp = thread->GetStackFrameAtIndex (frame_idx);
+            if (frame_sp == NULL)
+                break;
+
+            if (DisplayFrameForExecutionContext (thread,
+                                                 frame_sp.get(),
+                                                 interpreter,
+                                                 strm,
+                                                 show_frame_info,
+                                                 num_frames_with_source > first_frame - frame_idx,
+                                                 source_lines_before,
+                                                 source_lines_after) == false)
+                break;
+
+            ++num_frames_displayed;
+        }
+    }
+    strm.IndentLess();
+    return num_frames_displayed;
+}
+
+bool
+lldb_private::DisplayFrameForExecutionContext
+(
+    Thread *thread,
+    StackFrame *frame,
+    CommandInterpreter *interpreter,
+    Stream& strm,
+    bool show_frame_info,
+    bool show_source,
+    uint32_t source_lines_before,
+    uint32_t source_lines_after
+)
+{
+    // thread and frame must be filled in prior to calling this function
+    if (thread && frame)
+    {
+        if (show_frame_info)
+        {
+            strm.Indent();
+            frame->Dump (&strm, true);
+            strm.EOL();
+        }
+
+        SymbolContext sc (frame->GetSymbolContext(eSymbolContextCompUnit | eSymbolContextLineEntry));
+
+        if (show_source && sc.comp_unit && sc.line_entry.IsValid())
+        {
+            interpreter->GetSourceManager().DisplaySourceLinesWithLineNumbers (
+                    sc.line_entry.file,
+                    sc.line_entry.line,
+                    3,
+                    3,
+                    "->",
+                    &strm);
+
+        }
+        return true;
+    }
+    return false;
+}
+
+
+//-------------------------------------------------------------------------
+// CommandObjectThreadBacktrace
+//-------------------------------------------------------------------------
+
+class CommandObjectThreadBacktrace : public CommandObject
+{
+public:
+
+    CommandObjectThreadBacktrace () :
+        CommandObject ("thread backtrace",
+                       "Shows the stack for one or more threads.",
+                       "thread backtrace [<thread-idx>] ...",
+                       eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
+        m_ascending (true)
+    {
+    }
+
+    ~CommandObjectThreadBacktrace()
+    {
+    }
+
+
+    bool
+    Execute
+    (
+        Args& command,
+        CommandContext *context,
+        CommandInterpreter *interpreter,
+        CommandReturnObject &result
+    )
+    {
+        if (command.GetArgumentCount() == 0)
+        {
+            ExecutionContext exe_ctx(context->GetExecutionContext());
+            if (exe_ctx.thread)
+            {
+                bool show_frame_info = true;
+                uint32_t num_frames_with_source = 0; // Don't show any frasmes with source when backtracing
+                if (DisplayFramesForExecutionContext (exe_ctx.thread,
+                                                      interpreter,
+                                                      result.GetOutputStream(),
+                                                      m_ascending,
+                                                      0,
+                                                      UINT32_MAX,
+                                                      show_frame_info,
+                                                      num_frames_with_source,
+                                                      3,
+                                                      3))
+                {
+                    result.SetStatus (eReturnStatusSuccessFinishResult);
+                }
+            }
+            else
+            {
+                result.AppendError ("invalid thread");
+                result.SetStatus (eReturnStatusFailed);
+            }
+        }
+        else
+        {
+            result.AppendError ("backtrace doesn't take arguments (for now)");
+            result.SetStatus (eReturnStatusFailed);
+        }
+        return result.Succeeded();
+    }
+protected:
+    bool m_ascending;
+};
+
+
+typedef enum StepScope
+{
+    eStepScopeSource,
+    eStepScopeInstruction
+};
+
+class CommandObjectThreadStepWithTypeAndScope : public CommandObject
+{
+public:
+
+    class CommandOptions : public Options
+    {
+    public:
+
+        CommandOptions () :
+            Options()
+        {
+            // Keep default values of all options in one place: ResetOptionValues ()
+            ResetOptionValues ();
+        }
+
+        virtual
+        ~CommandOptions ()
+        {
+        }
+
+        virtual Error
+        SetOptionValue (int option_idx, const char *option_arg)
+        {
+            Error error;
+            char short_option = (char) m_getopt_table[option_idx].val;
+
+            switch (short_option)
+            {
+                case 'a':
+                {
+                    bool success;
+                    m_avoid_no_debug =  Args::StringToBoolean (option_arg, true, &success);
+                    if (!success)
+                        error.SetErrorStringWithFormat("Invalid boolean value for option '%c'.\n", short_option);
+                }
+                break;
+                case 'm':
+                {
+                    bool found_one = false;
+                    OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values; 
+                    m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, &found_one);
+                    if (!found_one)
+                        error.SetErrorStringWithFormat("Invalid enumeration value for option '%c'.\n", short_option);
+                }
+                break;
+                default:
+                    error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
+                    break;
+
+            }
+            return error;
+        }
+
+        void
+        ResetOptionValues ()
+        {
+            Options::ResetOptionValues();
+            m_avoid_no_debug = true;
+            m_run_mode = eOnlyDuringStepping;
+        }
+
+        const lldb::OptionDefinition*
+        GetDefinitions ()
+        {
+            return g_option_table;
+        }
+
+        // Options table: Required for subclasses of Options.
+
+        static lldb::OptionDefinition g_option_table[];
+
+        // Instance variables to hold the values for command options.
+        bool m_avoid_no_debug;
+        RunMode m_run_mode;
+    };
+
+    CommandObjectThreadStepWithTypeAndScope (const char *name,
+                         const char *help,
+                         const char *syntax,
+                         uint32_t flags,
+                         StepType step_type,
+                         StepScope step_scope) :
+        CommandObject (name, help, syntax, flags),
+        m_step_type (step_type),
+        m_step_scope (step_scope),
+        m_options ()
+    {
+    }
+
+    virtual
+    ~CommandObjectThreadStepWithTypeAndScope ()
+    {
+    }
+
+    virtual
+    Options *
+    GetOptions ()
+    {
+        return &m_options;
+    }
+
+    virtual bool
+    Execute (Args& command,
+             CommandContext *context,
+             CommandInterpreter *interpreter,
+             CommandReturnObject &result)
+    {
+        Process *process = context->GetExecutionContext().process;
+        bool synchronous_execution = interpreter->GetSynchronous();
+
+        if (process == NULL)
+        {
+            result.AppendError ("need a valid process to step");
+            result.SetStatus (eReturnStatusFailed);
+
+        }
+        else
+        {
+            const uint32_t num_threads = process->GetThreadList().GetSize();
+            Thread *thread = NULL;
+
+            if (command.GetArgumentCount() == 0)
+            {
+                thread = process->GetThreadList().GetCurrentThread().get();
+                if (thread == NULL)
+                {
+                    result.AppendError ("no current thread in process");
+                    result.SetStatus (eReturnStatusFailed);
+                    return false;
+                }
+            }
+            else
+            {
+                const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
+                uint32_t step_thread_idx = Args::StringToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
+                if (step_thread_idx == LLDB_INVALID_INDEX32)
+                {
+                    result.AppendErrorWithFormat ("Invalid thread index '%s'.\n", thread_idx_cstr);
+                    result.SetStatus (eReturnStatusFailed);
+                    return false;
+                }
+                thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
+                if (thread == NULL)
+                {
+                    result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n", 
+                                                  step_thread_idx, 0, num_threads);
+                    result.SetStatus (eReturnStatusFailed);
+                    return false;
+                }
+            }
+
+            const bool abort_other_plans = false;
+            const lldb::RunMode stop_other_threads = m_options.m_run_mode;
+            
+            // This is a bit unfortunate, but not all the commands in this command object support
+            // only while stepping, so I use the bool for them.
+            bool bool_stop_other_threads;
+            if (m_options.m_run_mode == eAllThreads)
+                bool_stop_other_threads = false;
+            else
+                bool_stop_other_threads = true;
+
+            if (m_step_type == eStepTypeInto)
+            {
+                StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
+                ThreadPlan *new_plan;
+
+                if (frame->HasDebugInformation ())
+                {
+                    new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans, m_step_type, 
+                                                                    frame->GetSymbolContext(eSymbolContextEverything).line_entry.range, 
+                                                                    frame->GetSymbolContext(eSymbolContextEverything), 
+                                                                    stop_other_threads);
+                    if (new_plan)
+                    {
+                        ThreadPlanStepInRange *real_plan = dynamic_cast<ThreadPlanStepInRange *> (new_plan);
+                        if (real_plan)
+                        {
+                            if (m_options.m_avoid_no_debug)
+                            {
+                                real_plan->GetFlags().Set (ThreadPlanShouldStopHere::eAvoidNoDebug);
+                            }
+                            else
+                            {
+                                real_plan->GetFlags().Clear (ThreadPlanShouldStopHere::eAvoidNoDebug);
+                            }
+                        }
+                    }
+                }
+                else
+                    new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
+
+                process->GetThreadList().SetCurrentThreadByID (thread->GetID());
+                process->Resume ();
+            }
+            else if (m_step_type == eStepTypeOver)
+            {
+                StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
+                ThreadPlan *new_plan;
+
+                if (frame->HasDebugInformation())
+                    new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans, 
+                                                                    m_step_type, 
+                                                                    frame->GetSymbolContext(eSymbolContextEverything).line_entry.range, 
+                                                                    frame->GetSymbolContext(eSymbolContextEverything), 
+                                                                    stop_other_threads);
+                else
+                    new_plan = thread->QueueThreadPlanForStepSingleInstruction (true, 
+                                                                                abort_other_plans, 
+                                                                                bool_stop_other_threads);
+
+                // FIXME: This will keep the step plan on the thread stack when we hit a breakpoint while stepping over.
+                // Maybe there should be a parameter to control this.
+                new_plan->SetOkayToDiscard(false);
+
+                process->GetThreadList().SetCurrentThreadByID (thread->GetID());
+                process->Resume ();
+            }
+            else if (m_step_type == eStepTypeTrace)
+            {
+                thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
+                process->GetThreadList().SetCurrentThreadByID (thread->GetID());
+                process->Resume ();
+            }
+            else if (m_step_type == eStepTypeTraceOver)
+            {
+                thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
+                process->GetThreadList().SetCurrentThreadByID (thread->GetID());
+                process->Resume ();
+            }
+            else if (m_step_type == eStepTypeOut)
+            {
+                ThreadPlan *new_plan;
+
+                new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans, NULL, false, bool_stop_other_threads, eVoteYes, eVoteNoOpinion);
+                // FIXME: This will keep the step plan on the thread stack when we hit a breakpoint while stepping over.
+                // Maybe there should be a parameter to control this.
+                new_plan->SetOkayToDiscard(false);
+
+                process->GetThreadList().SetCurrentThreadByID (thread->GetID());
+                process->Resume ();
+            }
+            else
+            {
+                result.AppendError ("step type is not supported");
+                result.SetStatus (eReturnStatusFailed);
+            }
+            if (synchronous_execution)
+            {
+                StateType state = process->WaitForProcessToStop (NULL);
+                
+                //EventSP event_sp;
+                //StateType state = process->WaitForStateChangedEvents (NULL, event_sp);
+                //while (! StateIsStoppedState (state))
+                //  {
+                //    state = process->WaitForStateChangedEvents (NULL, event_sp);
+                //  }
+                process->GetThreadList().SetCurrentThreadByID (thread->GetID());
+                result.SetDidChangeProcessState (true);
+                result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
+                result.SetStatus (eReturnStatusSuccessFinishNoResult);
+            }
+        }
+        return result.Succeeded();
+    }
+
+protected:
+    StepType m_step_type;
+    StepScope m_step_scope;
+    CommandOptions m_options;
+};
+
+static lldb::OptionEnumValueElement
+g_tri_running_mode[] =
+{
+{ eOnlyThisThread,     "thisThread",    "Run only this thread"},
+{ eAllThreads,         "allThreads",    "Run all threads"},
+{ eOnlyDuringStepping, "whileStepping", "Run only this thread while stepping"},
+{ 0, NULL, NULL }
+};
+
+static lldb::OptionEnumValueElement
+g_duo_running_mode[] =
+{
+{ eOnlyThisThread,     "thisThread",    "Run only this thread"},
+{ eAllThreads,         "allThreads",    "Run all threads"},
+{ 0, NULL, NULL }
+};
+
+lldb::OptionDefinition
+CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
+{
+{ 0, true, "avoid_no_debug", 'a', required_argument,       NULL, 0, "<avoid_no_debug>",        "Should step-in step over functions with no debug information"},
+{ 0, true, "run_mode", 'm', required_argument,       g_tri_running_mode, 0, "<run_mode>",        "Determine how to run other threads while stepping this one"},
+{ 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
+};
+
+
+//-------------------------------------------------------------------------
+// CommandObjectThreadContinue
+//-------------------------------------------------------------------------
+
+class CommandObjectThreadContinue : public CommandObject
+{
+public:
+
+    CommandObjectThreadContinue () :
+        CommandObject ("thread continue",
+                       "Continues execution of one or more threads in an active process.",
+                       "thread continue <thread-index> [<thread-index> ...]",
+                       eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
+    {
+    }
+
+
+    virtual
+    ~CommandObjectThreadContinue ()
+    {
+    }
+
+    virtual bool
+    Execute (Args& command,
+             CommandContext *context,
+             CommandInterpreter *interpreter,
+             CommandReturnObject &result)
+    {
+        bool synchronous_execution = interpreter->GetSynchronous ();
+
+        if (!context->GetTarget())
+        {
+            result.AppendError ("invalid target, set executable file using 'file' command");
+            result.SetStatus (eReturnStatusFailed);
+            return false;
+        }
+
+        Process *process = context->GetExecutionContext().process;
+        if (process == NULL)
+        {
+            result.AppendError ("no process exists. Cannot continue");
+            result.SetStatus (eReturnStatusFailed);
+            return false;
+        }
+
+        StateType state = process->GetState();
+        if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
+        {
+            const uint32_t num_threads = process->GetThreadList().GetSize();
+            uint32_t idx;
+            const size_t argc = command.GetArgumentCount();
+            if (argc > 0)
+            {
+                std::vector<uint32_t> resume_thread_indexes;
+                for (uint32_t i=0; i<argc; ++i)
+                {
+                    idx = Args::StringToUInt32 (command.GetArgumentAtIndex(0), LLDB_INVALID_INDEX32);
+                    if (idx < num_threads)
+                        resume_thread_indexes.push_back(idx);
+                    else
+                        result.AppendWarningWithFormat("Thread index %u out of range.\n", idx);
+                }
+
+                if (resume_thread_indexes.empty())
+                {
+                    result.AppendError ("no valid thread indexes were specified");
+                    result.SetStatus (eReturnStatusFailed);
+                    return false;
+                }
+                else
+                {
+                    result.AppendMessage ("Resuming thread ");
+                    for (idx=0; idx<num_threads; ++idx)
+                    {
+                        Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
+                        if (find(resume_thread_indexes.begin(), resume_thread_indexes.end(), idx) != resume_thread_indexes.end())
+                        {
+                            result.AppendMessageWithFormat ("%u ", idx);
+                            thread->SetResumeState (eStateRunning);
+                        }
+                        else
+                        {
+                            thread->SetResumeState (eStateSuspended);
+                        }
+                    }
+                    result.AppendMessageWithFormat ("in process %i\n", process->GetID());
+                }
+            }
+            else
+            {
+                Thread *current_thread = process->GetThreadList().GetCurrentThread().get();
+                if (current_thread == NULL)
+                {
+                    result.AppendError ("the process doesn't have a current thread");
+                    result.SetStatus (eReturnStatusFailed);
+                    return false;
+                }
+                // Set the actions that the threads should each take when resuming
+                for (idx=0; idx<num_threads; ++idx)
+                {
+                    Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
+                    if (thread == current_thread)
+                    {
+                        result.AppendMessageWithFormat ("Resuming thread 0x%4.4x in process %i\n", thread->GetID(), process->GetID());
+                        thread->SetResumeState (eStateRunning);
+                    }
+                    else
+                    {
+                        thread->SetResumeState (eStateSuspended);
+                    }
+                }
+            }
+
+            Error error (process->Resume());
+            if (error.Success())
+            {
+                result.AppendMessageWithFormat ("Resuming process %i\n", process->GetID());
+                if (synchronous_execution)
+                {
+                    StateType state = process->WaitForProcessToStop (NULL);
+
+                    result.SetDidChangeProcessState (true);
+                    result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
+                    result.SetStatus (eReturnStatusSuccessFinishNoResult);
+                }
+                else
+                {
+                    result.SetStatus (eReturnStatusSuccessContinuingNoResult);
+                }
+            }
+            else
+            {
+                result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
+                result.SetStatus (eReturnStatusFailed);
+            }
+        }
+        else
+        {
+            result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
+                                          StateAsCString(state));
+            result.SetStatus (eReturnStatusFailed);
+        }
+
+        return result.Succeeded();
+    }
+
+};
+
+//-------------------------------------------------------------------------
+// CommandObjectThreadUntil
+//-------------------------------------------------------------------------
+
+class CommandObjectThreadUntil : public CommandObject
+{
+public:
+
+    class CommandOptions : public Options
+    {
+    public:
+        uint32_t m_thread_idx;
+        uint32_t m_frame_idx;
+
+        CommandOptions () :
+            Options(),
+            m_thread_idx(LLDB_INVALID_THREAD_ID),
+            m_frame_idx(LLDB_INVALID_FRAME_ID)
+        {
+            // Keep default values of all options in one place: ResetOptionValues ()
+            ResetOptionValues ();
+        }
+
+        virtual
+        ~CommandOptions ()
+        {
+        }
+
+        virtual Error
+        SetOptionValue (int option_idx, const char *option_arg)
+        {
+            Error error;
+            char short_option = (char) m_getopt_table[option_idx].val;
+
+            switch (short_option)
+            {
+                case 't':
+                {
+                    uint32_t m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32);
+                    if (m_thread_idx == LLDB_INVALID_INDEX32)
+                    {
+                        error.SetErrorStringWithFormat ("Invalid thread index '%s'.\n", option_arg);
+                    }
+                }
+                break;
+                case 'f':
+                {
+                    m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
+                    if (m_frame_idx == LLDB_INVALID_FRAME_ID)
+                    {
+                        error.SetErrorStringWithFormat ("Invalid frame index '%s'.\n", option_arg);
+                    }
+                }
+                break;
+                case 'm':
+                {
+                    bool found_one = false;
+                    OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values; 
+                    lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, &found_one);
+
+                    if (!found_one)
+                        error.SetErrorStringWithFormat("Invalid enumeration value for option '%c'.\n", short_option);
+                    else if (run_mode == eAllThreads)
+                        m_stop_others = false;
+                    else
+                        m_stop_others = true;
+        
+                }
+                break;
+                default:
+                    error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
+                    break;
+
+            }
+            return error;
+        }
+
+        void
+        ResetOptionValues ()
+        {
+            Options::ResetOptionValues();
+            m_thread_idx = LLDB_INVALID_THREAD_ID;
+            m_frame_idx = 0;
+            m_stop_others = false;
+        }
+
+        const lldb::OptionDefinition*
+        GetDefinitions ()
+        {
+            return g_option_table;
+        }
+
+        uint32_t m_step_thread_idx;
+        bool m_stop_others;
+
+        // Options table: Required for subclasses of Options.
+
+        static lldb::OptionDefinition g_option_table[];
+
+        // Instance variables to hold the values for command options.
+    };
+
+    CommandObjectThreadUntil () :
+        CommandObject ("thread until",
+                       "Runs the current or specified thread until it reaches a given line number or leaves the current function.",
+                       "thread until [<cmd-options>] <line-number>",
+                       eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
+        m_options ()
+    {
+    }
+
+
+    virtual
+    ~CommandObjectThreadUntil ()
+    {
+    }
+
+    virtual
+    Options *
+    GetOptions ()
+    {
+        return &m_options;
+    }
+
+    virtual bool
+    Execute (Args& command,
+             CommandContext *context,
+             CommandInterpreter *interpreter,
+             CommandReturnObject &result)
+    {
+        bool synchronous_execution = interpreter->GetSynchronous ();
+
+        if (!context->GetTarget())
+        {
+            result.AppendError ("invalid target, set executable file using 'file' command");
+            result.SetStatus (eReturnStatusFailed);
+            return false;
+        }
+
+        Process *process = context->GetExecutionContext().process;
+        if (process == NULL)
+        {
+            result.AppendError ("need a valid process to step");
+            result.SetStatus (eReturnStatusFailed);
+
+        }
+        else
+        {
+            Thread *thread = NULL;
+            uint32_t line_number;
+
+            if (command.GetArgumentCount() != 1)
+            {
+                result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax());
+                result.SetStatus (eReturnStatusFailed);
+                return false;
+            }
+
+            line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
+            if (line_number == UINT32_MAX)
+            {
+                result.AppendErrorWithFormat ("Invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
+                result.SetStatus (eReturnStatusFailed);
+                return false;
+            }
+
+            if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
+            {
+                thread = process->GetThreadList().GetCurrentThread().get();
+            }
+            else
+            {
+                thread = process->GetThreadList().GetThreadAtIndex(m_options.m_thread_idx).get();
+            }
+
+            if (thread == NULL)
+            {
+                const uint32_t num_threads = process->GetThreadList().GetSize();
+                result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n", m_options.m_thread_idx, 0, num_threads);
+                result.SetStatus (eReturnStatusFailed);
+                return false;
+            }
+
+            const bool abort_other_plans = true;
+
+            StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
+            if (frame == NULL)
+            {
+
+                result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n", m_options.m_frame_idx, m_options.m_thread_idx);
+                result.SetStatus (eReturnStatusFailed);
+                return false;
+            }
+
+            ThreadPlan *new_plan;
+
+            if (frame->HasDebugInformation ())
+            {
+                // Finally we got here...  Translate the given line number to a bunch of addresses:
+                SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
+                LineTable *line_table = NULL;
+                if (sc.comp_unit)
+                    line_table = sc.comp_unit->GetLineTable();
+
+                if (line_table == NULL)
+                {
+                    result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
+                                                 m_options.m_frame_idx, m_options.m_thread_idx);
+                    result.SetStatus (eReturnStatusFailed);
+                    return false;
+                }
+
+                LineEntry function_start;
+                uint32_t index_ptr = 0, end_ptr;
+                std::vector<addr_t> address_list;
+
+                // Find the beginning & end index of the
+                AddressRange fun_addr_range = sc.function->GetAddressRange();
+                Address fun_start_addr = fun_addr_range.GetBaseAddress();
+                line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
+
+                Address fun_end_addr(fun_start_addr.GetSection(), fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
+                line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
+
+                while (index_ptr <= end_ptr)
+                {
+                    LineEntry line_entry;
+                    index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, &line_entry);
+                    if (index_ptr == UINT32_MAX)
+                        break;
+
+                    addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(process);
+                    if (address != LLDB_INVALID_ADDRESS)
+                        address_list.push_back (address);
+                    index_ptr++;
+                }
+
+                new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans, address_list.data(), address_list.size(), m_options.m_stop_others);
+                new_plan->SetOkayToDiscard(false);
+            }
+            else
+            {
+                result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n", m_options.m_frame_idx, m_options.m_thread_idx);
+                result.SetStatus (eReturnStatusFailed);
+                return false;
+
+            }
+
+            process->GetThreadList().SetCurrentThreadByID (m_options.m_thread_idx);
+            Error error (process->Resume ());
+            if (error.Success())
+            {
+                result.AppendMessageWithFormat ("Resuming process %i\n", process->GetID());
+                if (synchronous_execution)
+                {
+                    StateType state = process->WaitForProcessToStop (NULL);
+
+                    result.SetDidChangeProcessState (true);
+                    result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
+                    result.SetStatus (eReturnStatusSuccessFinishNoResult);
+                }
+                else
+                {
+                    result.SetStatus (eReturnStatusSuccessContinuingNoResult);
+                }
+            }
+            else
+            {
+                result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
+                result.SetStatus (eReturnStatusFailed);
+            }
+
+        }
+        return result.Succeeded();
+    }
+protected:
+    CommandOptions m_options;
+
+};
+
+lldb::OptionDefinition
+CommandObjectThreadUntil::CommandOptions::g_option_table[] =
+{
+{ 0, true, "frame", 'f', required_argument,       NULL, 0, "<frame>",        "Frame index for until operation - defaults to 0"},
+{ 0, true, "thread", 't', required_argument,       NULL, 0, "<thread>",      "Thread index for the thread for until operation"},
+{ 0, true, "run_mode", 'm', required_argument,       g_duo_running_mode, 0, "<run_mode>",        "Determine how to run other threads while stepping this one"},
+{ 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
+};
+
+
+//-------------------------------------------------------------------------
+// CommandObjectThreadSelect
+//-------------------------------------------------------------------------
+
+class CommandObjectThreadSelect : public CommandObject
+{
+public:
+
+    CommandObjectThreadSelect () :
+        CommandObject ("thread select",
+                         "Selects a threads as the currently active thread.",
+                         "thread select <thread-index>",
+                         eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
+    {
+    }
+
+
+    virtual
+    ~CommandObjectThreadSelect ()
+    {
+    }
+
+    virtual bool
+    Execute (Args& command,
+             CommandContext *context,
+             CommandInterpreter *interpreter,
+             CommandReturnObject &result)
+    {
+        Process *process = context->GetExecutionContext().process;
+        if (process == NULL)
+        {
+            result.AppendError ("no process");
+            result.SetStatus (eReturnStatusFailed);
+            return false;
+        }
+        else if (command.GetArgumentCount() != 1)
+        {
+            result.AppendErrorWithFormat("'%s' takes exactly one thread index argument:\nUsage: \n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
+            result.SetStatus (eReturnStatusFailed);
+            return false;
+        }
+
+        uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0);
+
+        Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
+        if (new_thread == NULL)
+        {
+            result.AppendErrorWithFormat ("Invalid thread #%s.\n", command.GetArgumentAtIndex(0));
+            result.SetStatus (eReturnStatusFailed);
+            return false;
+        }
+
+        process->GetThreadList().SetCurrentThreadByID(new_thread->GetID());
+        
+        DisplayThreadInfo (interpreter,
+                           result.GetOutputStream(),
+                           new_thread,
+                           false,
+                           true);
+
+        return result.Succeeded();
+    }
+
+};
+
+
+//-------------------------------------------------------------------------
+// CommandObjectThreadList
+//-------------------------------------------------------------------------
+
+CommandObjectThreadList::CommandObjectThreadList ():
+    CommandObject ("thread list",
+                     "Shows a summary of all current threads in a process.",
+                     "thread list",
+                     eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
+{
+}
+
+CommandObjectThreadList::~CommandObjectThreadList()
+{
+}
+
+bool
+CommandObjectThreadList::Execute
+(
+    Args& command,
+    CommandContext *context,
+    CommandInterpreter *interpreter,
+    CommandReturnObject &result
+)
+{
+    StreamString &strm = result.GetOutputStream();
+    result.SetStatus (eReturnStatusSuccessFinishNoResult);
+    ExecutionContext exe_ctx(context->GetExecutionContext());
+    if (exe_ctx.process)
+    {
+        const StateType state = exe_ctx.process->GetState();
+
+        if (StateIsStoppedState(state))
+        {
+            if (state == eStateExited)
+            {
+                int exit_status = exe_ctx.process->GetExitStatus();
+                const char *exit_description = exe_ctx.process->GetExitDescription();
+                strm.Printf ("Process %d exited with status = %i (0x%8.8x) %s\n",
+                                      exe_ctx.process->GetID(),
+                                      exit_status,
+                                      exit_status,
+                                      exit_description ? exit_description : "");
+            }
+            else
+            {
+                strm.Printf ("Process %d state is %s\n", exe_ctx.process->GetID(), StateAsCString (state));
+                if (exe_ctx.thread == NULL)
+                    exe_ctx.thread = exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get();
+                if (exe_ctx.thread != NULL)
+                {
+                    DisplayThreadsInfo (interpreter, &exe_ctx, result, false, false);
+                }
+                else
+                {
+                    result.AppendError ("no valid thread found in current process");
+                    result.SetStatus (eReturnStatusFailed);
+                }
+            }
+        }
+        else
+        {
+            result.AppendError ("process is currently running");
+            result.SetStatus (eReturnStatusFailed);
+        }
+    }
+    else
+    {
+        result.AppendError ("no current location or status available");
+        result.SetStatus (eReturnStatusFailed);
+    }
+    return result.Succeeded();
+}
+
+//-------------------------------------------------------------------------
+// CommandObjectMultiwordThread
+//-------------------------------------------------------------------------
+
+CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter *interpreter) :
+    CommandObjectMultiword ("thread",
+                            "A set of commands for operating on one or more thread within a running process.",
+                            "thread <subcommand> [<subcommand-options>]")
+{
+    LoadSubCommand (CommandObjectSP (new CommandObjectThreadBacktrace ()), "backtrace", interpreter);
+    LoadSubCommand (CommandObjectSP (new CommandObjectThreadContinue ()), "continue", interpreter);
+    LoadSubCommand (CommandObjectSP (new CommandObjectThreadList ()), "list", interpreter);
+    LoadSubCommand (CommandObjectSP (new CommandObjectThreadSelect ()), "select", interpreter);
+    LoadSubCommand (CommandObjectSP (new CommandObjectThreadUntil ()), "until", interpreter);
+    LoadSubCommand (CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ("thread step-in",
+                                                                                  "Source level single step in in specified thread (current thread, if none specified).",
+                                                                                  "thread step-in [<thread-id>]",
+                                                                                  eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
+                                                                                  eStepTypeInto,
+                                                                                  eStepScopeSource)),
+                    "step-in", interpreter);
+
+    LoadSubCommand (CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ("thread step-out",
+                                                                                      "Source level single step out in specified thread (current thread, if none specified).",
+                                                                                      "thread step-out [<thread-id>]",
+                                                                                      eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
+                                                                                      eStepTypeOut,
+                                                                                      eStepScopeSource)),
+                    "step-out", interpreter);
+
+    LoadSubCommand (CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ("thread step-over",
+                                                                                      "Source level single step over in specified thread (current thread, if none specified).",
+                                                                                      "thread step-over [<thread-id>]",
+                                                                                      eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
+                                                                                      eStepTypeOver,
+                                                                                      eStepScopeSource)),
+                    "step-over", interpreter);
+
+    LoadSubCommand (CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ("thread step-inst",
+                                                                                      "Single step one instruction in specified thread (current thread, if none specified).",
+                                                                                      "thread step-inst [<thread-id>]",
+                                                                                      eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
+                                                                                      eStepTypeTrace,
+                                                                                      eStepScopeInstruction)),
+                    "step-inst", interpreter);
+    LoadSubCommand (CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ("thread step-inst-over",
+                                                                                      "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
+                                                                                      "thread step-inst-over [<thread-id>]",
+                                                                                      eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
+                                                                                      eStepTypeTraceOver,
+                                                                                      eStepScopeInstruction)),
+                    "step-inst-over", interpreter);
+}
+
+CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
+{
+}
+
+
