Initial checkin of lldb code from internal Apple repo.


git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@105619 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Target/ABI.cpp b/source/Target/ABI.cpp
new file mode 100644
index 0000000..20d35e3
--- /dev/null
+++ b/source/Target/ABI.cpp
@@ -0,0 +1,47 @@
+//===-- ABI.cpp -------------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/ABI.h"
+#include "lldb/Core/PluginManager.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+ABI*
+ABI::FindPlugin (const ConstString &triple)
+{
+    std::auto_ptr<ABI> abi_ap;
+    ABICreateInstance create_callback;
+
+    for (uint32_t idx = 0;
+         (create_callback = PluginManager::GetABICreateCallbackAtIndex(idx)) != NULL;
+         ++idx)
+    {
+        abi_ap.reset (create_callback(triple));
+
+        if (abi_ap.get())
+            return abi_ap.release();
+    }
+
+    return NULL;
+}
+
+//----------------------------------------------------------------------
+// Constructor
+//----------------------------------------------------------------------
+ABI::ABI()
+{
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+ABI::~ABI()
+{
+}
diff --git a/source/Target/ExecutionContext.cpp b/source/Target/ExecutionContext.cpp
new file mode 100644
index 0000000..e79f8c2
--- /dev/null
+++ b/source/Target/ExecutionContext.cpp
@@ -0,0 +1,107 @@
+//===-- ExecutionContext.cpp ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//
+
+//
+//===----------------------------------------------------------------------===//
+
+
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+
+using namespace lldb_private;
+
+ExecutionContext::ExecutionContext() :
+    target (NULL),
+    process (NULL),
+    thread (NULL),
+    frame (NULL)
+{
+}
+
+ExecutionContext::ExecutionContext (Target* t, bool fill_current_process_thread_frame) :
+    target (t),
+    process (NULL),
+    thread (NULL),
+    frame (NULL)
+{
+    if (t && fill_current_process_thread_frame)
+    {
+        process = t->GetProcessSP().get();
+        if (process)
+        {
+            thread = process->GetThreadList().GetCurrentThread().get();
+            if (thread)
+                frame = thread->GetCurrentFrame().get();
+        }
+    }
+}
+
+ExecutionContext::ExecutionContext(Process* p, Thread *t, StackFrame *f) :
+    target (p ? &p->GetTarget() : NULL),
+    process (p),
+    thread (t),
+    frame (f)
+{
+}
+
+ExecutionContext::ExecutionContext (ExecutionContextScope *exe_scope_ptr)
+{
+    if (exe_scope_ptr)
+        exe_scope_ptr->Calculate (*this);
+    else
+    {
+        target  = NULL;
+        process = NULL;
+        thread  = NULL;
+        frame   = NULL;
+    }
+}
+
+ExecutionContext::ExecutionContext (ExecutionContextScope &exe_scope_ref)
+{
+    exe_scope_ref.Calculate (*this);
+}
+
+void
+ExecutionContext::Clear()
+{
+    target  = NULL;
+    process = NULL;
+    thread  = NULL;
+    frame   = NULL;
+}
+
+
+RegisterContext *
+ExecutionContext::GetRegisterContext () const
+{
+    if (frame)
+        return frame->GetRegisterContext();
+    else if (thread)
+        return thread->GetRegisterContext();
+    return NULL;
+}
+
+ExecutionContextScope *
+ExecutionContext::GetBestExecutionContextScope () const
+{
+    if (frame)
+        return frame;
+    if (thread)
+        return thread;
+    if (process)
+        return process;
+    return target;
+}
diff --git a/source/Target/ObjCObjectPrinter.cpp b/source/Target/ObjCObjectPrinter.cpp
new file mode 100644
index 0000000..81c73aa
--- /dev/null
+++ b/source/Target/ObjCObjectPrinter.cpp
@@ -0,0 +1,120 @@
+//===-- ObjCObjectPrinter.cpp -------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/StreamString.h"
+#include "lldb/Expression/ClangFunction.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+
+#include "ObjCObjectPrinter.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// ObjCObjectPrinter constructor
+//----------------------------------------------------------------------
+ObjCObjectPrinter::ObjCObjectPrinter (Process &process) :
+    m_process(process)
+{
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+ObjCObjectPrinter::~ObjCObjectPrinter ()
+{
+}
+
+bool
+ObjCObjectPrinter::PrintObject (ConstString &str, Value &object_ptr, ExecutionContext &exe_ctx)
+{
+    if (!exe_ctx.process)
+        return false;
+    
+    const Address *function_address = GetPrintForDebuggerAddr();
+
+    if (!function_address)
+        return false;
+    
+    const char *target_triple = exe_ctx.process->GetTargetTriple().GetCString();
+    ClangASTContext *ast_context = exe_ctx.target->GetScratchClangASTContext();
+    
+    void *return_qualtype = ast_context->GetCStringType(true);
+    Value ret;
+    ret.SetContext(Value::eContextTypeOpaqueClangQualType, return_qualtype);
+    
+    ValueList arg_value_list;
+    arg_value_list.PushValue(object_ptr);
+    
+    ClangFunction func(target_triple, ast_context, return_qualtype, *function_address, arg_value_list);
+    StreamString error_stream;
+    
+    lldb::addr_t wrapper_struct_addr = LLDB_INVALID_ADDRESS;
+    func.InsertFunction(exe_ctx, wrapper_struct_addr, error_stream);
+    // FIXME: Check result of ExecuteFunction.
+    func.ExecuteFunction(exe_ctx, &wrapper_struct_addr, error_stream, true, 1000, true, ret);
+        
+    addr_t result_ptr = ret.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
+    
+    // poor man's strcpy
+    
+    size_t len = 0;
+    bool keep_reading = true;
+    Error error;
+    while (keep_reading)
+    {
+        char byte;
+        
+        if (exe_ctx.process->ReadMemory(result_ptr + len, &byte, 1, error) != 1)
+            return false;
+        
+        if (byte == '\0')
+            keep_reading = false;
+        else
+            ++len;
+    }
+    
+    char desc[len + 1];
+    
+    if (exe_ctx.process->ReadMemory(result_ptr, &desc[0], len + 1, error) != len + 1)
+        return false;
+    
+    str.SetCString(desc);
+    
+    return true;
+}
+
+Address *
+ObjCObjectPrinter::GetPrintForDebuggerAddr()
+{
+    if (!m_PrintForDebugger_addr.get())
+    {
+        ModuleList &modules = m_process.GetTarget().GetImages();
+        
+        SymbolContextList contexts;
+        SymbolContext context;
+        
+        if((!modules.FindSymbolsWithNameAndType(ConstString ("_NSPrintForDebugger"), eSymbolTypeCode, contexts)) &&
+           (!modules.FindSymbolsWithNameAndType(ConstString ("_CFPrintForDebugger"), eSymbolTypeCode, contexts)))
+            return NULL;
+        
+        contexts.GetContextAtIndex(0, context);
+        
+        m_PrintForDebugger_addr.reset(new Address(context.symbol->GetValue()));
+    }
+    
+    return m_PrintForDebugger_addr.get();
+}
+
diff --git a/source/Target/PathMappingList.cpp b/source/Target/PathMappingList.cpp
new file mode 100644
index 0000000..02ca067
--- /dev/null
+++ b/source/Target/PathMappingList.cpp
@@ -0,0 +1,125 @@
+//===-- PathMappingList.cpp -------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Stream.h"
+// Project includes
+#include "PathMappingList.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// PathMappingList constructor
+//----------------------------------------------------------------------
+PathMappingList::PathMappingList 
+(
+    ChangedCallback callback,
+    void *callback_baton
+) :
+    m_pairs (),
+    m_callback (callback),
+    m_callback_baton (callback_baton)
+{
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+PathMappingList::~PathMappingList ()
+{
+}
+
+void
+PathMappingList::Append (const ConstString &path,
+                         const ConstString &replacement,
+                         bool notify)
+{
+    m_pairs.push_back(pair(path, replacement));
+    if (notify && m_callback)
+        m_callback (*this, m_callback_baton);
+}
+
+void
+PathMappingList::Insert (const ConstString &path,
+                         const ConstString &replacement,
+                         uint32_t index,
+                         bool notify)
+{
+    iterator insert_iter;
+    if (index >= m_pairs.size())
+        insert_iter = m_pairs.end();
+    else
+        insert_iter = m_pairs.begin() + index;
+    m_pairs.insert(insert_iter, pair(path, replacement));
+    if (notify && m_callback)
+        m_callback (*this, m_callback_baton);
+}
+
+bool
+PathMappingList::Remove (off_t index, bool notify)
+{
+    if (index >= m_pairs.size())
+        return false;
+
+    iterator iter = m_pairs.begin() + index;
+    m_pairs.erase(iter);
+    if (notify && m_callback)
+        m_callback (*this, m_callback_baton);
+    return true;
+}
+
+void
+PathMappingList::Dump (Stream *s)
+{
+    unsigned int numPairs = m_pairs.size();
+    unsigned int index;
+
+    for (index = 0; index < numPairs; ++index)
+    {
+        s->Printf("[%d] \"%s\" -> \"%s\"\n",
+                  index, m_pairs[index].first.GetCString(), m_pairs[index].second.GetCString());
+    }
+}
+
+void
+PathMappingList::Clear (bool notify)
+{
+    m_pairs.clear();
+    if (notify && m_callback)
+        m_callback (*this, m_callback_baton);
+}
+
+size_t
+PathMappingList::GetSize ()
+{
+    return m_pairs.size();
+}
+
+bool
+PathMappingList::RemapPath (const ConstString &path, ConstString &new_path)
+{
+    const_iterator pos, end = m_pairs.end();
+    for (pos = m_pairs.begin(); pos != end; ++pos)
+    {
+        const size_t prefixLen = pos->first.GetLength();
+
+        if (::strncmp (pos->first.GetCString(), path.GetCString(), prefixLen) == 0)
+        {
+            std::string new_path_str (pos->second.GetCString());
+            new_path_str.append(path.GetCString() + prefixLen);
+            new_path.SetCString(new_path_str.c_str());
+            return true;
+        }
+    }
+    return false;
+}
diff --git a/source/Target/Process.cpp b/source/Target/Process.cpp
new file mode 100644
index 0000000..9a6ab0c
--- /dev/null
+++ b/source/Target/Process.cpp
@@ -0,0 +1,1876 @@
+//===-- Process.cpp ---------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/Process.h"
+
+#include "lldb/lldb-private-log.h"
+
+#include "lldb/Breakpoint/StoppointCallbackContext.h"
+#include "lldb/Breakpoint/BreakpointLocation.h"
+#include "lldb/Core/Event.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/State.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Target/ABI.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/TargetList.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+Process*
+Process::FindPlugin (Target &target, const char *plugin_name, Listener &listener)
+{
+    ProcessCreateInstance create_callback = NULL;
+    if (plugin_name)
+    {
+        create_callback  = PluginManager::GetProcessCreateCallbackForPluginName (plugin_name);
+        if (create_callback)
+        {
+            std::auto_ptr<Process> debugger_ap(create_callback(target, listener));
+            if (debugger_ap->CanDebug(target))
+                return debugger_ap.release();
+        }
+    }
+    else
+    {
+        for (uint32_t idx = 0; create_callback = PluginManager::GetProcessCreateCallbackAtIndex(idx); ++idx)
+        {
+            create_callback = PluginManager::GetProcessCreateCallbackAtIndex (idx);
+            if (create_callback)
+            {
+                std::auto_ptr<Process> debugger_ap(create_callback(target, listener));
+                if (debugger_ap->CanDebug(target))
+                    return debugger_ap.release();
+            }
+        }
+    }
+    return NULL;
+}
+
+
+//----------------------------------------------------------------------
+// Process constructor
+//----------------------------------------------------------------------
+Process::Process(Target &target, Listener &listener) :
+    UserID (LLDB_INVALID_PROCESS_ID),
+    Broadcaster ("Process"),
+    m_target (target),
+    m_section_load_info (),
+    m_public_state (eStateUnloaded),
+    m_private_state (eStateUnloaded),
+    m_private_state_broadcaster ("lldb.process.internal_state_broadcaster"),
+    m_private_state_control_broadcaster ("lldb.process.internal_state_control_broadcaster"),
+    m_private_state_listener ("lldb.process.internal_state_listener"),
+    m_private_state_control_wait(),
+    m_private_state_thread (LLDB_INVALID_HOST_THREAD),
+    m_stop_id (0),
+    m_thread_index_id (0),
+    m_exit_status (-1),
+    m_exit_string (),
+    m_thread_list (this),
+    m_notifications (),
+    m_listener(listener),
+    m_unix_signals (),
+    m_objc_object_printer(*this)
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT);
+    if (log)
+        log->Printf ("%p Process::Process()", this);
+
+    listener.StartListeningForEvents (this,
+                                      eBroadcastBitStateChanged |
+                                      eBroadcastBitInterrupt |
+                                      eBroadcastBitSTDOUT |
+                                      eBroadcastBitSTDERR);
+
+    m_private_state_listener.StartListeningForEvents(&m_private_state_broadcaster,
+                                                     eBroadcastBitStateChanged);
+
+    m_private_state_listener.StartListeningForEvents(&m_private_state_control_broadcaster,
+                                                     eBroadcastInternalStateControlStop |
+                                                     eBroadcastInternalStateControlPause |
+                                                     eBroadcastInternalStateControlResume);
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+Process::~Process()
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT);
+    if (log)
+        log->Printf ("%p Process::~Process()", this);
+    StopPrivateStateThread();
+}
+
+void
+Process::Finalize()
+{
+    // Do any cleanup needed prior to being destructed... Subclasses
+    // that override this method should call this superclass method as well.
+}
+
+void
+Process::RegisterNotificationCallbacks (const Notifications& callbacks)
+{
+    m_notifications.push_back(callbacks);
+    if (callbacks.initialize != NULL)
+        callbacks.initialize (callbacks.baton, this);
+}
+
+bool
+Process::UnregisterNotificationCallbacks(const Notifications& callbacks)
+{
+    std::vector<Notifications>::iterator pos, end = m_notifications.end();
+    for (pos = m_notifications.begin(); pos != end; ++pos)
+    {
+        if (pos->baton == callbacks.baton &&
+            pos->initialize == callbacks.initialize &&
+            pos->process_state_changed == callbacks.process_state_changed)
+        {
+            m_notifications.erase(pos);
+            return true;
+        }
+    }
+    return false;
+}
+
+void
+Process::SynchronouslyNotifyStateChanged (StateType state)
+{
+    std::vector<Notifications>::iterator notification_pos, notification_end = m_notifications.end();
+    for (notification_pos = m_notifications.begin(); notification_pos != notification_end; ++notification_pos)
+    {
+        if (notification_pos->process_state_changed)
+            notification_pos->process_state_changed (notification_pos->baton, this, state);
+    }
+}
+
+// FIXME: We need to do some work on events before the general Listener sees them.
+// For instance if we are continuing from a breakpoint, we need to ensure that we do
+// the little "insert real insn, step & stop" trick.  But we can't do that when the
+// event is delivered by the broadcaster - since that is done on the thread that is
+// waiting for new events, so if we needed more than one event for our handling, we would
+// stall.  So instead we do it when we fetch the event off of the queue.
+//
+
+StateType
+Process::GetNextEvent (EventSP &event_sp)
+{
+    StateType state = eStateInvalid;
+
+    if (m_listener.GetNextEventForBroadcaster (this, event_sp) && event_sp)
+        state = Process::ProcessEventData::GetStateFromEvent (event_sp.get());
+
+    return state;
+}
+
+
+StateType
+Process::WaitForProcessToStop (const TimeValue *timeout)
+{
+    StateType match_states[] = { eStateStopped, eStateCrashed, eStateDetached, eStateExited, eStateUnloaded };
+    return WaitForState (timeout, match_states, sizeof(match_states) / sizeof(StateType));
+}
+
+
+StateType
+Process::WaitForState
+(
+    const TimeValue *timeout,
+    const StateType *match_states, const uint32_t num_match_states
+)
+{
+    EventSP event_sp;
+    uint32_t i;
+    StateType state = eStateUnloaded;
+    while (state != eStateInvalid)
+    {
+        state = WaitForStateChangedEvents (timeout, event_sp);
+
+        for (i=0; i<num_match_states; ++i)
+        {
+            if (match_states[i] == state)
+                return state;
+        }
+    }
+    return state;
+}
+
+StateType
+Process::WaitForStateChangedEvents (const TimeValue *timeout, EventSP &event_sp)
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
+
+    if (log)
+        log->Printf ("Process::%s (timeout = %p, event_sp)...", __FUNCTION__, timeout);
+
+    StateType state = eStateInvalid;
+    if (m_listener.WaitForEventForBroadcasterWithType(timeout,
+                                                      this,
+                                                      eBroadcastBitStateChanged,
+                                                      event_sp))
+        state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
+
+    if (log)
+        log->Printf ("Process::%s (timeout = %p, event_sp) => %s",
+                     __FUNCTION__,
+                     timeout,
+                     StateAsCString(state));
+    return state;
+}
+
+Event *
+Process::PeekAtStateChangedEvents ()
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
+
+    if (log)
+        log->Printf ("Process::%s...", __FUNCTION__);
+
+    Event *event_ptr;
+    event_ptr = m_listener.PeekAtNextEventForBroadcasterWithType(this,
+                                                      eBroadcastBitStateChanged);
+    if (log)
+    {
+        if (event_ptr)
+        {
+            log->Printf ("Process::%s (event_ptr) => %s",
+                         __FUNCTION__,
+                         StateAsCString(ProcessEventData::GetStateFromEvent (event_ptr)));
+        }
+        else 
+        {
+            log->Printf ("Process::%s no events found",
+                         __FUNCTION__);
+        }
+    }
+    return event_ptr;
+}
+
+StateType
+Process::WaitForStateChangedEventsPrivate (const TimeValue *timeout, EventSP &event_sp)
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
+
+    if (log)
+        log->Printf ("Process::%s (timeout = %p, event_sp)...", __FUNCTION__, timeout);
+
+    StateType state = eStateInvalid;
+    if (m_private_state_listener.WaitForEventForBroadcasterWithType(timeout,
+                                                                    &m_private_state_broadcaster,
+                                                                    eBroadcastBitStateChanged,
+                                                                    event_sp))
+        state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
+
+    // This is a bit of a hack, but when we wait here we could very well return
+    // to the command-line, and that could disable the log, which would render the
+    // log we got above invalid.
+    log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
+    if (log)
+        log->Printf ("Process::%s (timeout = %p, event_sp) => %s", __FUNCTION__, timeout, StateAsCString(state));
+    return state;
+}
+
+bool
+Process::WaitForEventsPrivate (const TimeValue *timeout, EventSP &event_sp, bool control_only)
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
+
+    if (log)
+        log->Printf ("Process::%s (timeout = %p, event_sp)...", __FUNCTION__, timeout);
+
+    if (control_only)
+        return m_private_state_listener.WaitForEventForBroadcaster(timeout, &m_private_state_control_broadcaster, event_sp);
+    else
+        return m_private_state_listener.WaitForEvent(timeout, event_sp);
+}
+
+bool
+Process::IsRunning () const
+{
+    return StateIsRunningState (m_public_state.GetValue());
+}
+
+int
+Process::GetExitStatus ()
+{
+    if (m_public_state.GetValue() == eStateExited)
+        return m_exit_status;
+    return -1;
+}
+
+const char *
+Process::GetExitDescription ()
+{
+    if (m_public_state.GetValue() == eStateExited && !m_exit_string.empty())
+        return m_exit_string.c_str();
+    return NULL;
+}
+
+void
+Process::SetExitStatus (int status, const char *cstr)
+{
+    m_exit_status = status;
+    if (cstr)
+        m_exit_string = cstr;
+    else
+        m_exit_string.clear();
+
+    SetPrivateState (eStateExited);
+}
+
+// This static callback can be used to watch for local child processes on
+// the current host. The the child process exits, the process will be
+// found in the global target list (we want to be completely sure that the
+// lldb_private::Process doesn't go away before we can deliver the signal.
+bool
+Process::SetProcessExitStatus
+(
+    void *callback_baton,
+    lldb::pid_t pid,
+    int signo,      // Zero for no signal
+    int exit_status      // Exit value of process if signal is zero
+)
+{
+    if (signo == 0 || exit_status)
+    {
+        TargetSP target_sp(Debugger::GetSharedInstance().GetTargetList().FindTargetWithProcessID (pid));
+        if (target_sp)
+        {
+            ProcessSP process_sp (target_sp->GetProcessSP());
+            if (process_sp)
+            {
+                const char *signal_cstr = NULL;
+                if (signo)
+                    signal_cstr = process_sp->GetUnixSignals().GetSignalAsCString (signo);
+
+                process_sp->SetExitStatus (exit_status, signal_cstr);
+            }
+        }
+        return true;
+    }
+    return false;
+}
+
+
+uint32_t
+Process::GetNextThreadIndexID ()
+{
+    return ++m_thread_index_id;
+}
+
+StateType
+Process::GetState()
+{
+    // If any other threads access this we will need a mutex for it
+    return m_public_state.GetValue ();
+}
+
+void
+Process::SetPublicState (StateType new_state)
+{
+    Log *log = lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STATE);
+    if (log)
+        log->Printf("Process::SetPublicState (%s)", StateAsCString(new_state));
+    m_public_state.SetValue (new_state);
+}
+
+StateType
+Process::GetPrivateState ()
+{
+    return m_private_state.GetValue();
+}
+
+void
+Process::SetPrivateState (StateType new_state)
+{
+    Log *log = lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STATE);
+    bool state_changed = false;
+
+    if (log)
+        log->Printf("Process::SetPrivateState (%s)", StateAsCString(new_state));
+
+    Mutex::Locker locker(m_private_state.GetMutex());
+
+    const StateType old_state = m_private_state.GetValueNoLock ();
+    state_changed = old_state != new_state;
+    if (state_changed)
+    {
+        m_private_state.SetValueNoLock (new_state);
+        if (StateIsStoppedState(new_state))
+        {
+            m_stop_id++;
+            if (log)
+                log->Printf("Process::SetPrivateState (%s) stop_id = %u", StateAsCString(new_state), m_stop_id);
+        }
+        // Use our target to get a shared pointer to ourselves...
+        m_private_state_broadcaster.BroadcastEvent (eBroadcastBitStateChanged, new ProcessEventData (GetTarget().GetProcessSP(), new_state));
+    }
+    else
+    {
+        if (log)
+            log->Printf("Process::SetPrivateState (%s) state didn't change. Ignoring...", StateAsCString(new_state), StateAsCString(old_state));
+    }
+}
+
+
+uint32_t
+Process::GetStopID() const
+{
+    return m_stop_id;
+}
+
+addr_t
+Process::GetImageInfoAddress()
+{
+    return LLDB_INVALID_ADDRESS;
+}
+
+DynamicLoader *
+Process::GetDynamicLoader()
+{
+    return NULL;
+}
+
+const ABI *
+Process::GetABI()
+{
+    ConstString& triple = m_target_triple;
+
+    if (triple.IsEmpty())
+        return NULL;
+
+    if (m_abi_sp.get() == NULL)
+    {
+        m_abi_sp.reset(ABI::FindPlugin(triple));
+    }
+
+    return m_abi_sp.get();
+}
+
+BreakpointSiteList &
+Process::GetBreakpointSiteList()
+{
+    return m_breakpoint_site_list;
+}
+
+const BreakpointSiteList &
+Process::GetBreakpointSiteList() const
+{
+    return m_breakpoint_site_list;
+}
+
+
+void
+Process::DisableAllBreakpointSites ()
+{
+    m_breakpoint_site_list.SetEnabledForAll (false);
+}
+
+Error
+Process::ClearBreakpointSiteByID (lldb::user_id_t break_id)
+{
+    Error error (DisableBreakpointSiteByID (break_id));
+    
+    if (error.Success())
+        m_breakpoint_site_list.Remove(break_id);
+
+    return error;
+}
+
+Error
+Process::DisableBreakpointSiteByID (lldb::user_id_t break_id)
+{
+    Error error;
+    BreakpointSiteSP bp_site_sp = m_breakpoint_site_list.FindByID (break_id);
+    if (bp_site_sp)
+    {
+        if (bp_site_sp->IsEnabled())
+            error = DisableBreakpoint (bp_site_sp.get());
+    }
+    else
+    {
+        error.SetErrorStringWithFormat("invalid breakpoint site ID: %i", break_id);
+    }
+
+    return error;
+}
+
+Error
+Process::EnableBreakpointSiteByID (lldb::user_id_t break_id)
+{
+    Error error;
+    BreakpointSiteSP bp_site_sp = m_breakpoint_site_list.FindByID (break_id);
+    if (bp_site_sp)
+    {
+        if (!bp_site_sp->IsEnabled())
+            error = EnableBreakpoint (bp_site_sp.get());
+    }
+    else
+    {
+        error.SetErrorStringWithFormat("invalid breakpoint site ID: %i", break_id);
+    }
+    return error;
+}
+
+lldb::user_id_t
+Process::CreateBreakpointSite (BreakpointLocationSP &owner, bool use_hardware)
+{
+    const addr_t load_addr = owner->GetAddress().GetLoadAddress (this);
+    if (load_addr != LLDB_INVALID_ADDRESS)
+    {
+        BreakpointSiteSP bp_site_sp;
+
+        // Look up this breakpoint site.  If it exists, then add this new owner, otherwise
+        // create a new breakpoint site and add it.
+
+        bp_site_sp = m_breakpoint_site_list.FindByAddress (load_addr);
+
+        if (bp_site_sp)
+        {
+            bp_site_sp->AddOwner (owner);
+            owner->SetBreakpointSite (bp_site_sp);
+            return bp_site_sp->GetID();
+        }
+        else
+        {
+            bp_site_sp.reset (new BreakpointSite (&m_breakpoint_site_list, owner, load_addr, LLDB_INVALID_THREAD_ID, use_hardware));
+            if (bp_site_sp)
+            {
+                if (EnableBreakpoint (bp_site_sp.get()).Success())
+                {
+                    owner->SetBreakpointSite (bp_site_sp);
+                    return m_breakpoint_site_list.Add (bp_site_sp);
+                }
+            }
+        }
+    }
+    // We failed to enable the breakpoint
+    return LLDB_INVALID_BREAK_ID;
+
+}
+
+void
+Process::RemoveOwnerFromBreakpointSite (lldb::user_id_t owner_id, lldb::user_id_t owner_loc_id, BreakpointSiteSP &bp_site_sp)
+{
+    uint32_t num_owners = bp_site_sp->RemoveOwner (owner_id, owner_loc_id);
+    if (num_owners == 0)
+    {
+        DisableBreakpoint(bp_site_sp.get());
+        m_breakpoint_site_list.RemoveByAddress(bp_site_sp->GetLoadAddress());
+    }
+}
+
+
+size_t
+Process::RemoveBreakpointOpcodesFromBuffer (addr_t bp_addr, size_t size, uint8_t *buf) const
+{
+    size_t bytes_removed = 0;
+    addr_t intersect_addr;
+    size_t intersect_size;
+    size_t opcode_offset;
+    size_t idx;
+    BreakpointSiteSP bp;
+
+    for (idx = 0; (bp = m_breakpoint_site_list.GetByIndex(idx)) != NULL; ++idx)
+    {
+        if (bp->GetType() == BreakpointSite::eSoftware)
+        {
+            if (bp->IntersectsRange(bp_addr, size, &intersect_addr, &intersect_size, &opcode_offset))
+            {
+                assert(bp_addr <= intersect_addr && intersect_addr < bp_addr + size);
+                assert(bp_addr < intersect_addr + intersect_size && intersect_addr + intersect_size <= bp_addr + size);
+                assert(opcode_offset + intersect_size <= bp->GetByteSize());
+                size_t buf_offset = intersect_addr - bp_addr;
+                ::memcpy(buf + buf_offset, bp->GetSavedOpcodeBytes() + opcode_offset, intersect_size);
+            }
+        }
+    }
+    return bytes_removed;
+}
+
+
+Error
+Process::EnableSoftwareBreakpoint (BreakpointSite *bp_site)
+{
+    Error error;
+    assert (bp_site != NULL);
+    Log *log = lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
+    const addr_t bp_addr = bp_site->GetLoadAddress();
+    if (log)
+        log->Printf ("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%llx", bp_site->GetID(), (uint64_t)bp_addr);
+    if (bp_site->IsEnabled())
+    {
+        if (log)
+            log->Printf ("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%llx -- already enabled", bp_site->GetID(), (uint64_t)bp_addr);
+        return error;
+    }
+
+    if (bp_addr == LLDB_INVALID_ADDRESS)
+    {
+        error.SetErrorString("BreakpointSite contains an invalid load address.");
+        return error;
+    }
+    // Ask the lldb::Process subclass to fill in the correct software breakpoint
+    // trap for the breakpoint site
+    const size_t bp_opcode_size = GetSoftwareBreakpointTrapOpcode(bp_site);
+
+    if (bp_opcode_size == 0)
+    {
+        error.SetErrorStringWithFormat ("Process::GetSoftwareBreakpointTrapOpcode() returned zero, unable to get breakpoint trap for address 0x%llx.\n", bp_addr);
+    }
+    else
+    {
+        const uint8_t * const bp_opcode_bytes = bp_site->GetTrapOpcodeBytes();
+
+        if (bp_opcode_bytes == NULL)
+        {
+            error.SetErrorString ("BreakpointSite doesn't contain a valid breakpoint trap opcode.");
+            return error;
+        }
+
+        // Save the original opcode by reading it
+        if (DoReadMemory(bp_addr, bp_site->GetSavedOpcodeBytes(), bp_opcode_size, error) == bp_opcode_size)
+        {
+            // Write a software breakpoint in place of the original opcode
+            if (DoWriteMemory(bp_addr, bp_opcode_bytes, bp_opcode_size, error) == bp_opcode_size)
+            {
+                uint8_t verify_bp_opcode_bytes[64];
+                if (DoReadMemory(bp_addr, verify_bp_opcode_bytes, bp_opcode_size, error) == bp_opcode_size)
+                {
+                    if (::memcmp(bp_opcode_bytes, verify_bp_opcode_bytes, bp_opcode_size) == 0)
+                    {
+                        bp_site->SetEnabled(true);
+                        bp_site->SetType (BreakpointSite::eSoftware);
+                        if (log)
+                            log->Printf ("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%llx -- SUCCESS",
+                                         bp_site->GetID(),
+                                         (uint64_t)bp_addr);
+                    }
+                    else
+                        error.SetErrorString("Failed to verify the breakpoint trap in memory.");
+                }
+                else
+                    error.SetErrorString("Unable to read memory to verify breakpoint trap.");
+            }
+            else
+                error.SetErrorString("Unable to write breakpoint trap to memory.");
+        }
+        else
+            error.SetErrorString("Unable to read memory at breakpoint address.");
+    }
+    if (log)
+        log->Printf ("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%llx -- FAILED: %s",
+                     bp_site->GetID(),
+                     (uint64_t)bp_addr,
+                     error.AsCString());
+    return error;
+}
+
+Error
+Process::DisableSoftwareBreakpoint (BreakpointSite *bp_site)
+{
+    Error error;
+    assert (bp_site != NULL);
+    Log *log = lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
+    addr_t bp_addr = bp_site->GetLoadAddress();
+    lldb::user_id_t breakID = bp_site->GetID();
+    if (log)
+        log->Printf ("ProcessMacOSX::DisableBreakpoint (breakID = %d) addr = 0x%llx", breakID, (uint64_t)bp_addr);
+
+    if (bp_site->IsHardware())
+    {
+        error.SetErrorString("Breakpoint site is a hardware breakpoint.");
+    }
+    else if (bp_site->IsEnabled())
+    {
+        const size_t break_op_size = bp_site->GetByteSize();
+        const uint8_t * const break_op = bp_site->GetTrapOpcodeBytes();
+        if (break_op_size > 0)
+        {
+            // Clear a software breakoint instruction
+            uint8_t curr_break_op[break_op_size];
+            bool break_op_found = false;
+
+            // Read the breakpoint opcode
+            if (DoReadMemory (bp_addr, curr_break_op, break_op_size, error) == break_op_size)
+            {
+                bool verify = false;
+                // Make sure we have the a breakpoint opcode exists at this address
+                if (::memcmp (curr_break_op, break_op, break_op_size) == 0)
+                {
+                    break_op_found = true;
+                    // We found a valid breakpoint opcode at this address, now restore
+                    // the saved opcode.
+                    if (DoWriteMemory (bp_addr, bp_site->GetSavedOpcodeBytes(), break_op_size, error) == break_op_size)
+                    {
+                        verify = true;
+                    }
+                    else
+                        error.SetErrorString("Memory write failed when restoring original opcode.");
+                }
+                else
+                {
+                    error.SetErrorString("Original breakpoint trap is no longer in memory.");
+                    // Set verify to true and so we can check if the original opcode has already been restored
+                    verify = true;
+                }
+
+                if (verify)
+                {
+                    uint8_t verify_opcode[break_op_size];
+                    // Verify that our original opcode made it back to the inferior
+                    if (DoReadMemory (bp_addr, verify_opcode, break_op_size, error) == break_op_size)
+                    {
+                        // compare the memory we just read with the original opcode
+                        if (::memcmp (bp_site->GetSavedOpcodeBytes(), verify_opcode, break_op_size) == 0)
+                        {
+                            // SUCCESS
+                            bp_site->SetEnabled(false);
+                            if (log)
+                                log->Printf ("Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%llx -- SUCCESS", bp_site->GetID(), (uint64_t)bp_addr);
+                            return error;
+                        }
+                        else
+                        {
+                            if (break_op_found)
+                                error.SetErrorString("Failed to restore original opcode.");
+                        }
+                    }
+                    else
+                        error.SetErrorString("Failed to read memory to verify that breakpoint trap was restored.");
+                }
+            }
+            else
+                error.SetErrorString("Unable to read memory that should contain the breakpoint trap.");
+        }
+    }
+    else
+    {
+        if (log)
+            log->Printf ("Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%llx -- already disabled", bp_site->GetID(), (uint64_t)bp_addr);
+        return error;
+    }
+
+    if (log)
+        log->Printf ("Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%llx -- FAILED: %s",
+                     bp_site->GetID(),
+                     (uint64_t)bp_addr,
+                     error.AsCString());
+    return error;
+
+}
+
+
+size_t
+Process::ReadMemory (addr_t addr, void *buf, size_t size, Error &error)
+{
+    if (buf == NULL || size == 0)
+        return 0;
+
+    size_t bytes_read = 0;
+    uint8_t *bytes = (uint8_t *)buf;
+    
+    while (bytes_read < size)
+    {
+        const size_t curr_size = size - bytes_read;
+        const size_t curr_bytes_read = DoReadMemory (addr + bytes_read, 
+                                                     bytes + bytes_read, 
+                                                     curr_size,
+                                                     error);
+        bytes_read += curr_bytes_read;
+        if (curr_bytes_read == curr_size || curr_bytes_read == 0)
+            break;
+    }
+
+    // Replace any software breakpoint opcodes that fall into this range back
+    // into "buf" before we return
+    if (bytes_read > 0)
+        RemoveBreakpointOpcodesFromBuffer (addr, bytes_read, (uint8_t *)buf);
+    return bytes_read;
+}
+
+size_t
+Process::WriteMemoryPrivate (addr_t addr, const void *buf, size_t size, Error &error)
+{
+    size_t bytes_written = 0;
+    const uint8_t *bytes = (const uint8_t *)buf;
+    
+    while (bytes_written < size)
+    {
+        const size_t curr_size = size - bytes_written;
+        const size_t curr_bytes_written = DoWriteMemory (addr + bytes_written, 
+                                                         bytes + bytes_written, 
+                                                         curr_size,
+                                                         error);
+        bytes_written += curr_bytes_written;
+        if (curr_bytes_written == curr_size || curr_bytes_written == 0)
+            break;
+    }
+    return bytes_written;
+}
+
+size_t
+Process::WriteMemory (addr_t addr, const void *buf, size_t size, Error &error)
+{
+    if (buf == NULL || size == 0)
+        return 0;
+    // We need to write any data that would go where any current software traps
+    // (enabled software breakpoints) any software traps (breakpoints) that we
+    // may have placed in our tasks memory.
+
+    BreakpointSiteList::collection::const_iterator iter = m_breakpoint_site_list.GetMap()->lower_bound (addr);
+    BreakpointSiteList::collection::const_iterator end =  m_breakpoint_site_list.GetMap()->end();
+
+    if (iter == end || iter->second->GetLoadAddress() > addr + size)
+        return DoWriteMemory(addr, buf, size, error);
+
+    BreakpointSiteList::collection::const_iterator pos;
+    size_t bytes_written = 0;
+    addr_t intersect_addr;
+    size_t intersect_size;
+    size_t opcode_offset;
+    const uint8_t *ubuf = (const uint8_t *)buf;
+
+    for (pos = iter; pos != end; ++pos)
+    {
+        BreakpointSiteSP bp;
+        bp = pos->second;
+
+        assert(bp->IntersectsRange(addr, size, &intersect_addr, &intersect_size, &opcode_offset));
+        assert(addr <= intersect_addr && intersect_addr < addr + size);
+        assert(addr < intersect_addr + intersect_size && intersect_addr + intersect_size <= addr + size);
+        assert(opcode_offset + intersect_size <= bp->GetByteSize());
+
+        // Check for bytes before this breakpoint
+        const addr_t curr_addr = addr + bytes_written;
+        if (intersect_addr > curr_addr)
+        {
+            // There are some bytes before this breakpoint that we need to
+            // just write to memory
+            size_t curr_size = intersect_addr - curr_addr;
+            size_t curr_bytes_written = WriteMemoryPrivate (curr_addr, 
+                                                            ubuf + bytes_written, 
+                                                            curr_size, 
+                                                            error);
+            bytes_written += curr_bytes_written;
+            if (curr_bytes_written != curr_size)
+            {
+                // We weren't able to write all of the requested bytes, we
+                // are done looping and will return the number of bytes that
+                // we have written so far.
+                break;
+            }
+        }
+
+        // Now write any bytes that would cover up any software breakpoints
+        // directly into the breakpoint opcode buffer
+        ::memcpy(bp->GetSavedOpcodeBytes() + opcode_offset, ubuf + bytes_written, intersect_size);
+        bytes_written += intersect_size;
+    }
+
+    // Write any remaining bytes after the last breakpoint if we have any left
+    if (bytes_written < size)
+        bytes_written += WriteMemoryPrivate (addr + bytes_written, 
+                                             ubuf + bytes_written, 
+                                             size - bytes_written, 
+                                             error);
+    
+    return bytes_written;
+}
+
+addr_t
+Process::AllocateMemory(size_t size, uint32_t permissions, Error &error)
+{
+    // Fixme: we should track the blocks we've allocated, and clean them up...
+    // We could even do our own allocator here if that ends up being more efficient.
+    return DoAllocateMemory (size, permissions, error);
+}
+
+Error
+Process::DeallocateMemory (addr_t ptr)
+{
+    return DoDeallocateMemory (ptr);
+}
+
+
+Error
+Process::EnableWatchpoint (WatchpointLocation *watchpoint)
+{
+    Error error;
+    error.SetErrorString("watchpoints are not supported");
+    return error;
+}
+
+Error
+Process::DisableWatchpoint (WatchpointLocation *watchpoint)
+{
+    Error error;
+    error.SetErrorString("watchpoints are not supported");
+    return error;
+}
+
+StateType
+Process::WaitForProcessStopPrivate (const TimeValue *timeout, EventSP &event_sp)
+{
+    StateType state;
+    // Now wait for the process to launch and return control to us, and then
+    // call DidLaunch:
+    while (1)
+    {
+        // FIXME: Might want to put a timeout in here:
+        state = WaitForStateChangedEventsPrivate (NULL, event_sp);
+        if (state == eStateStopped || state == eStateCrashed || state == eStateExited)
+            break;
+        else
+            HandlePrivateEvent (event_sp);
+    }
+    return state;
+}
+
+Error
+Process::Launch
+(
+    char const *argv[],
+    char const *envp[],
+    const char *stdin_path,
+    const char *stdout_path,
+    const char *stderr_path
+)
+{
+    Error error;
+    m_target_triple.Clear();
+    m_abi_sp.reset();
+
+    Module *exe_module = m_target.GetExecutableModule().get();
+    if (exe_module)
+    {
+        char exec_file_path[PATH_MAX];
+        exe_module->GetFileSpec().GetPath(exec_file_path, sizeof(exec_file_path));
+        if (exe_module->GetFileSpec().Exists())
+        {
+            error = WillLaunch (exe_module);
+            if (error.Success())
+            {
+                // The args coming in should not contain the application name, the
+                // lldb_private::Process class will add this in case the executable
+                // gets resolved to a different file than was given on the command
+                // line (like when an applicaiton bundle is specified and will
+                // resolve to the contained exectuable file, or the file given was
+                // a symlink or other file system link that resolves to a different
+                // file).
+
+                // Get the resolved exectuable path
+
+                // Make a new argument vector
+                std::vector<const char *> exec_path_plus_argv;
+                // Append the resolved executable path
+                exec_path_plus_argv.push_back (exec_file_path);
+
+                // Push all args if there are any
+                if (argv)
+                {
+                    for (int i = 0; argv[i]; ++i)
+                        exec_path_plus_argv.push_back(argv[i]);
+                }
+
+                // Push a NULL to terminate the args.
+                exec_path_plus_argv.push_back(NULL);
+
+                // Now launch using these arguments.
+                error = DoLaunch (exe_module, exec_path_plus_argv.data(), envp, stdin_path, stdout_path, stderr_path);
+
+                if (error.Fail())
+                {
+                    if (GetID() != LLDB_INVALID_PROCESS_ID)
+                    {
+                        SetID (LLDB_INVALID_PROCESS_ID);
+                        const char *error_string = error.AsCString();
+                        if (error_string == NULL)
+                            error_string = "launch failed";
+                        SetExitStatus (-1, error_string);
+                    }
+                }
+                else
+                {
+                    EventSP event_sp;
+                    StateType state = WaitForProcessStopPrivate(NULL, event_sp);
+
+                    if (state == eStateStopped || state == eStateCrashed)
+                    {
+                        DidLaunch ();
+
+                        // This delays passing the stopped event to listeners till DidLaunch gets
+                        // a chance to complete...
+                        HandlePrivateEvent (event_sp);
+                        StartPrivateStateThread ();
+                    }
+                    else if (state == eStateExited)
+                    {
+                        // We exited while trying to launch somehow.  Don't call DidLaunch as that's
+                        // not likely to work, and return an invalid pid.
+                        HandlePrivateEvent (event_sp);
+                    }
+                }
+            }
+        }
+        else
+        {
+            error.SetErrorStringWithFormat("File doesn't exist: '%s'.\n", exec_file_path);
+        }
+    }
+    return error;
+}
+
+Error
+Process::CompleteAttach ()
+{
+    Error error;
+    EventSP event_sp;
+    StateType state = WaitForProcessStopPrivate(NULL, event_sp);
+    if (state == eStateStopped || state == eStateCrashed)
+    {
+        DidAttach ();
+
+        // This delays passing the stopped event to listeners till DidLaunch gets
+        // a chance to complete...
+        HandlePrivateEvent(event_sp);
+        StartPrivateStateThread();
+    }
+    else
+    {
+        // We exited while trying to launch somehow.  Don't call DidLaunch as that's
+        // not likely to work, and return an invalid pid.
+        if (state == eStateExited)
+            HandlePrivateEvent (event_sp);
+        error.SetErrorStringWithFormat("invalid state after attach: %s", 
+                                        lldb_private::StateAsCString(state));
+    }
+    return error;
+}
+
+Error
+Process::Attach (lldb::pid_t attach_pid)
+{
+
+    m_target_triple.Clear();
+    m_abi_sp.reset();
+
+    Error error(WillAttach (attach_pid));
+    if (error.Success())
+    {
+        error = DoAttach (attach_pid);
+        if (error.Success())
+        {
+            error = CompleteAttach();
+        }
+        else
+        {
+            if (GetID() != LLDB_INVALID_PROCESS_ID)
+            {
+                SetID (LLDB_INVALID_PROCESS_ID);
+                const char *error_string = error.AsCString();
+                if (error_string == NULL)
+                    error_string = "attach failed";
+
+                SetExitStatus(-1, error_string);
+            }
+        }
+    }
+    return error;
+}
+
+Error
+Process::Attach (const char *process_name, bool wait_for_launch)
+{
+    m_target_triple.Clear();
+    m_abi_sp.reset();
+
+    Error error (WillAttach (process_name, wait_for_launch));
+    if (error.Success())
+    {
+        StartPrivateStateThread();
+        error = DoAttach (process_name, wait_for_launch);
+        if (error.Fail())
+        {
+            if (GetID() != LLDB_INVALID_PROCESS_ID)
+            {
+                SetID (LLDB_INVALID_PROCESS_ID);
+                const char *error_string = error.AsCString();
+                if (error_string == NULL)
+                    error_string = "attach failed";
+
+                SetExitStatus(-1, error_string);
+            }
+        }
+        else
+        {
+            error = CompleteAttach();
+        }
+    }
+    return error;
+}
+
+Error
+Process::Resume ()
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
+    if (log)
+        log->Printf("Process::Resume() m_stop_id = %u", m_stop_id);
+
+    Error error (WillResume());
+    // Tell the process it is about to resume before the thread list
+    if (error.Success())
+    {
+        // Now let the thread list know we are about to resume to it
+        // can let all of our threads know that they are about to be
+        // resumed. Threads will each be called with
+        // Thread::WillResume(StateType) where StateType contains the state
+        // that they are supposed to have when the process is resumed
+        // (suspended/running/stepping). Threads should also check
+        // their resume signal in lldb::Thread::GetResumeSignal()
+        // to see if they are suppoed to start back up with a signal.
+        if (m_thread_list.WillResume())
+        {
+            error = DoResume();
+            if (error.Success())
+            {
+                DidResume();
+                m_thread_list.DidResume();
+            }
+        }
+        else
+        {
+            error.SetErrorStringWithFormat("thread list returned flase after WillResume");
+        }
+    }
+    return error;
+}
+
+Error
+Process::Halt ()
+{
+    Error error (WillHalt());
+    
+    if (error.Success())
+    {
+        error = DoHalt();
+        if (error.Success())
+            DidHalt();
+    }
+    return error;
+}
+
+Error
+Process::Detach ()
+{
+    Error error (WillDetach());
+
+    if (error.Success())
+    {
+        DisableAllBreakpointSites();
+        error = DoDetach(); 
+        if (error.Success())
+        {
+            DidDetach();
+            StopPrivateStateThread();
+        }
+    }
+    return error;
+}
+
+Error
+Process::Destroy ()
+{
+    Error error (WillDestroy());
+    if (error.Success())
+    {
+        DisableAllBreakpointSites();
+        error = DoDestroy();
+        if (error.Success())
+        {
+            DidDestroy();
+            StopPrivateStateThread();
+        }
+    }
+    return error;
+}
+
+Error
+Process::Signal (int signal)
+{
+    Error error (WillSignal());
+    if (error.Success())
+    {
+        error = DoSignal(signal);
+        if (error.Success())
+            DidSignal();
+    }
+    return error;
+}
+
+UnixSignals &
+Process::GetUnixSignals ()
+{
+    return m_unix_signals;
+}
+
+Target &
+Process::GetTarget ()
+{
+    return m_target;
+}
+
+const Target &
+Process::GetTarget () const
+{
+    return m_target;
+}
+
+uint32_t
+Process::GetAddressByteSize()
+{
+    return m_target.GetArchitecture().GetAddressByteSize();
+}
+
+bool
+Process::ShouldBroadcastEvent (Event *event_ptr)
+{
+    const StateType state = Process::ProcessEventData::GetStateFromEvent (event_ptr);
+    bool return_value = true;
+    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS);
+
+    switch (state)
+    {
+        case eStateAttaching:
+        case eStateLaunching:
+        case eStateDetached:
+        case eStateExited:
+        case eStateUnloaded:
+            // These events indicate changes in the state of the debugging session, always report them.
+            return_value = true;
+            break;
+        case eStateInvalid:
+            // We stopped for no apparent reason, don't report it.
+            return_value = false;
+            break;
+        case eStateRunning:
+        case eStateStepping:
+            // If we've started the target running, we handle the cases where we
+            // are already running and where there is a transition from stopped to
+            // running differently.
+            // running -> running: Automatically suppress extra running events
+            // stopped -> running: Report except when there is one or more no votes
+            //     and no yes votes.
+            SynchronouslyNotifyStateChanged (state);
+            switch (m_public_state.GetValue())
+            {
+                case eStateRunning:
+                case eStateStepping:
+                    // We always suppress multiple runnings with no PUBLIC stop in between.
+                    return_value = false;
+                    break;
+                default:
+                    // TODO: make this work correctly. For now always report
+                    // run if we aren't running so we don't miss any runnning
+                    // events. If I run the lldb/test/thread/a.out file and
+                    // break at main.cpp:58, run and hit the breakpoints on
+                    // multiple threads, then somehow during the stepping over
+                    // of all breakpoints no run gets reported.
+                    return_value = true;
+
+                    // This is a transition from stop to run.
+                    switch (m_thread_list.ShouldReportRun (event_ptr))
+                    {
+                        case eVoteYes:
+                        case eVoteNoOpinion:
+                            return_value = true;
+                            break;
+                        case eVoteNo:
+                            return_value = false;
+                            break;
+                    }
+                    break;
+            }
+            break;
+        case eStateStopped:
+        case eStateCrashed:
+        case eStateSuspended:
+        {
+            // We've stopped.  First see if we're going to restart the target.
+            // If we are going to stop, then we always broadcast the event.
+            // If we aren't going to stop, let the thread plans decide if we're going to report this event.
+            // If no thread has an opinion, we also report it.
+            if (state != eStateInvalid)
+            {
+
+                RefreshStateAfterStop ();
+
+                if (m_thread_list.ShouldStop (event_ptr) == false)
+                {
+                    switch (m_thread_list.ShouldReportStop (event_ptr))
+                    {
+                        case eVoteYes:
+                            Process::ProcessEventData::SetRestartedInEvent (event_ptr, true);
+                        case eVoteNoOpinion:
+                            return_value = true;
+                            break;
+                        case eVoteNo:
+                            return_value = false;
+                            break;
+                    }
+
+                    if (log)
+                        log->Printf ("Process::ShouldBroadcastEvent (%p) Restarting process", event_ptr, StateAsCString(state));
+                    Resume ();
+                }
+                else
+                {
+                    return_value = true;
+                    SynchronouslyNotifyStateChanged (state);
+                }
+            }
+        }
+    }
+
+    if (log)
+        log->Printf ("Process::ShouldBroadcastEvent (%p) => %s", event_ptr, StateAsCString(state), return_value ? "YES" : "NO");
+    return return_value;
+}
+
+//------------------------------------------------------------------
+// Thread Queries
+//------------------------------------------------------------------
+
+ThreadList &
+Process::GetThreadList ()
+{
+    return m_thread_list;
+}
+
+const ThreadList &
+Process::GetThreadList () const
+{
+    return m_thread_list;
+}
+
+
+bool
+Process::StartPrivateStateThread ()
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS);
+
+    if (log)
+        log->Printf ("Process::%s ( )", __FUNCTION__);
+
+    // Create a thread that watches our internal state and controls which
+    // events make it to clients (into the DCProcess event queue).
+    m_private_state_thread = Host::ThreadCreate ("<lldb.process.internal-state>", Process::PrivateStateThread, this, NULL);
+    return m_private_state_thread != LLDB_INVALID_HOST_THREAD;
+}
+
+void
+Process::PausePrivateStateThread ()
+{
+    ControlPrivateStateThread (eBroadcastInternalStateControlPause);
+}
+
+void
+Process::ResumePrivateStateThread ()
+{
+    ControlPrivateStateThread (eBroadcastInternalStateControlResume);
+}
+
+void
+Process::StopPrivateStateThread ()
+{
+    ControlPrivateStateThread (eBroadcastInternalStateControlStop);
+}
+
+void
+Process::ControlPrivateStateThread (uint32_t signal)
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS);
+
+    assert (signal == eBroadcastInternalStateControlStop ||
+            signal == eBroadcastInternalStateControlPause ||
+            signal == eBroadcastInternalStateControlResume);
+
+    if (log)
+        log->Printf ("Process::%s ( ) - signal: %d", __FUNCTION__, signal);
+
+    // Signal the private state thread
+    if (m_private_state_thread != LLDB_INVALID_HOST_THREAD)
+    {
+        TimeValue timeout_time;
+        bool timed_out;
+
+        m_private_state_control_broadcaster.BroadcastEvent (signal, NULL);
+
+        timeout_time = TimeValue::Now();
+        timeout_time.OffsetWithSeconds(2);
+        m_private_state_control_wait.WaitForValueEqualTo (true, &timeout_time, &timed_out);
+        m_private_state_control_wait.SetValue (false, eBroadcastNever);
+
+        if (signal == eBroadcastInternalStateControlStop)
+        {
+            if (timed_out)
+                Host::ThreadCancel (m_private_state_thread, NULL);
+
+            thread_result_t result = NULL;
+            Host::ThreadJoin (m_private_state_thread, &result, NULL);
+        }
+    }
+}
+
+void
+Process::HandlePrivateEvent (EventSP &event_sp)
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
+    const StateType internal_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
+    // See if we should broadcast this state to external clients?
+    const bool should_broadcast = ShouldBroadcastEvent (event_sp.get());
+    if (log)
+        log->Printf ("Process::%s (arg = %p, pid = %i) got event '%s' broadcast = %s", __FUNCTION__, this, GetID(), StateAsCString(internal_state), should_broadcast ? "yes" : "no");
+
+    if (should_broadcast)
+    {
+        if (log)
+        {
+            log->Printf ("\tChanging public state from: %s to %s", StateAsCString(GetState ()), StateAsCString (internal_state));
+        }
+        Process::ProcessEventData::SetUpdateStateOnRemoval(event_sp.get());
+        BroadcastEvent (event_sp);
+    }
+    else
+    {
+        if (log)
+        {
+            log->Printf ("\tNot changing public state with event: %s", StateAsCString (internal_state));
+        }
+    }
+}
+
+void *
+Process::PrivateStateThread (void *arg)
+{
+    Process *proc = static_cast<Process*> (arg);
+    void *result = proc->RunPrivateStateThread ();
+    proc->m_private_state_thread = LLDB_INVALID_HOST_THREAD;
+    return result;
+}
+
+void *
+Process::RunPrivateStateThread ()
+{
+    bool control_only = false;
+    m_private_state_control_wait.SetValue (false, eBroadcastNever);
+
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
+    if (log)
+        log->Printf ("Process::%s (arg = %p, pid = %i) thread starting...", __FUNCTION__, this, GetID());
+
+    bool exit_now = false;
+    while (!exit_now)
+    {
+        EventSP event_sp;
+        WaitForEventsPrivate (NULL, event_sp, control_only);
+        if (event_sp->BroadcasterIs(&m_private_state_control_broadcaster))
+        {
+            switch (event_sp->GetType())
+            {
+            case eBroadcastInternalStateControlStop:
+                exit_now = true;
+                continue;   // Go to next loop iteration so we exit without
+                break;      // doing any internal state managment below
+
+            case eBroadcastInternalStateControlPause:
+                control_only = true;
+                break;
+
+            case eBroadcastInternalStateControlResume:
+                control_only = false;
+                break;
+            }
+            m_private_state_control_wait.SetValue (true, eBroadcastAlways);
+        }
+
+
+        const StateType internal_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
+
+        if (internal_state != eStateInvalid)
+        {
+            HandlePrivateEvent (event_sp);
+        }
+
+        if (internal_state == eStateInvalid || internal_state == eStateExited)
+            break;
+    }
+
+    if (log)
+        log->Printf ("Process::%s (arg = %p, pid = %i) thread exiting...", __FUNCTION__, this, GetID());
+
+    return NULL;
+}
+
+addr_t
+Process::GetSectionLoadAddress (const Section *section) const
+{
+    // TODO: add support for the same section having multiple load addresses
+    addr_t section_load_addr = LLDB_INVALID_ADDRESS;
+    if (m_section_load_info.GetFirstKeyForValue (section, section_load_addr))
+        return section_load_addr;
+    return LLDB_INVALID_ADDRESS;
+}
+
+bool
+Process::SectionLoaded (const Section *section, addr_t load_addr)
+{
+    Log *log = lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_SHLIB | LIBLLDB_LOG_VERBOSE);
+
+    if (log)
+        log->Printf ("Process::%s (section = %p (%s.%s), load_addr = 0x%16.16llx)",
+                     __FUNCTION__,
+                     section,
+                     section->GetModule()->GetFileSpec().GetFilename().AsCString(),
+                     section->GetName().AsCString(),
+                     load_addr);
+
+
+    const Section *existing_section = NULL;
+    Mutex::Locker locker(m_section_load_info.GetMutex());
+
+    if (m_section_load_info.GetValueForKeyNoLock (load_addr, existing_section))
+    {
+        if (existing_section == section)
+            return false;   // No change
+    }
+    m_section_load_info.SetValueForKeyNoLock (load_addr, section);
+    return true;    // Changed
+}
+
+size_t
+Process::SectionUnloaded (const Section *section)
+{
+    Log *log = lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_SHLIB | LIBLLDB_LOG_VERBOSE);
+
+    if (log)
+        log->Printf ("Process::%s (section = %p (%s.%s))",
+                     __FUNCTION__,
+                     section,
+                     section->GetModule()->GetFileSpec().GetFilename().AsCString(),
+                     section->GetName().AsCString());
+
+    Mutex::Locker locker(m_section_load_info.GetMutex());
+
+    size_t unload_count = 0;
+    addr_t section_load_addr;
+    while (m_section_load_info.GetFirstKeyForValueNoLock (section, section_load_addr))
+    {
+        unload_count += m_section_load_info.EraseNoLock (section_load_addr);
+    }
+    return unload_count;
+}
+
+bool
+Process::SectionUnloaded (const Section *section, addr_t load_addr)
+{
+    Log *log = lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_SHLIB | LIBLLDB_LOG_VERBOSE);
+
+    if (log)
+        log->Printf ("Process::%s (section = %p (%s.%s), load_addr = 0x%16.16llx)",
+                     __FUNCTION__,
+                     section,
+                     section->GetModule()->GetFileSpec().GetFilename().AsCString(),
+                     section->GetName().AsCString(),
+                     load_addr);
+
+    return m_section_load_info.Erase (load_addr) == 1;
+}
+
+
+bool
+Process::ResolveLoadAddress (addr_t load_addr, Address &so_addr) const
+{
+    addr_t section_load_addr = LLDB_INVALID_ADDRESS;
+    const Section *section = NULL;
+
+    // First find the top level section that this load address exists in
+    if (m_section_load_info.LowerBound (load_addr, section_load_addr, section, true))
+    {
+        addr_t offset = load_addr - section_load_addr;
+        if (offset < section->GetByteSize())
+        {
+            // We have found the top level section, now we need to find the
+            // deepest child section.
+            return section->ResolveContainedAddress (offset, so_addr);
+        }
+    }
+    so_addr.Clear();
+    return false;
+}
+
+//------------------------------------------------------------------
+// Process Event Data
+//------------------------------------------------------------------
+
+Process::ProcessEventData::ProcessEventData () :
+    EventData (),
+    m_process_sp (),
+    m_state (eStateInvalid),
+    m_update_state (false),
+    m_restarted (false)
+{
+}
+
+Process::ProcessEventData::ProcessEventData (const ProcessSP &process_sp, StateType state) :
+    EventData (),
+    m_process_sp (process_sp),
+    m_state (state),
+    m_update_state (false),
+    m_restarted (false)
+{
+}
+
+Process::ProcessEventData::~ProcessEventData()
+{
+}
+
+const ConstString &
+Process::ProcessEventData::GetFlavorString ()
+{
+    static ConstString g_flavor ("Process::ProcessEventData");
+    return g_flavor;
+}
+
+const ConstString &
+Process::ProcessEventData::GetFlavor () const
+{
+    return ProcessEventData::GetFlavorString ();
+}
+
+const ProcessSP &
+Process::ProcessEventData::GetProcessSP () const
+{
+    return m_process_sp;
+}
+
+StateType
+Process::ProcessEventData::GetState () const
+{
+    return m_state;
+}
+
+bool
+Process::ProcessEventData::GetRestarted () const
+{
+    return m_restarted;
+}
+
+void
+Process::ProcessEventData::SetRestarted (bool new_value)
+{
+    m_restarted = new_value;
+}
+
+void
+Process::ProcessEventData::DoOnRemoval (Event *event_ptr)
+{
+    // This function gets called twice for each event, once when the event gets pulled 
+    // off of the private process event queue, and once when it gets pulled off of
+    // the public event queue.  m_update_state is used to distinguish these
+    // two cases; it is false when we're just pulling it off for private handling, 
+    // and we don't want to do the breakpoint command handling then.
+    
+    if (!m_update_state)
+        return;
+        
+    m_process_sp->SetPublicState (m_state);
+        
+    // If we're stopped and haven't restarted, then do the breakpoint commands here:
+    if (m_state == eStateStopped && ! m_restarted)
+    {
+        int num_threads = m_process_sp->GetThreadList().GetSize();
+        int idx;
+        
+        for (idx = 0; idx < num_threads; ++idx)
+        {
+            lldb::ThreadSP thread_sp = m_process_sp->GetThreadList().GetThreadAtIndex(idx);
+
+            Thread::StopInfo stop_info;
+            if (thread_sp->GetStopInfo(&stop_info))
+            {
+                StopReason reason = stop_info.GetStopReason();
+                if (reason == eStopReasonBreakpoint)
+                {
+                    BreakpointSiteSP bp_site_sp;
+                    // Look up the breakpoint site in the stop info, but the breakpoint
+                    // might be a temporary one that's been deleted between the time we
+                    // hit the breakpoint and now, if so there's nothing to do.
+                    
+                    bp_site_sp = m_process_sp->GetBreakpointSiteList().FindByID (stop_info.GetBreakpointSiteID());
+                    if (bp_site_sp)
+                    {
+                        size_t num_owners = bp_site_sp->GetNumberOfOwners();
+                        for (size_t j = 0; j < num_owners; j++)
+                        {
+                            lldb::BreakpointLocationSP bp_loc_sp = bp_site_sp->GetOwnerAtIndex(j);
+                            StoppointCallbackContext context (event_ptr, 
+                                                              m_process_sp.get(), 
+                                                              thread_sp.get(), 
+                                                              thread_sp->GetStackFrameAtIndex(0).get(),
+                                                              false);
+                            bp_loc_sp->InvokeCallback (&context);
+                        }
+                    }
+                    else
+                    {
+                        Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
+
+                        if (log)
+                            log->Printf ("Process::%s could not find breakpoint site id: %d...", __FUNCTION__, stop_info.GetBreakpointSiteID());
+                    }
+
+                }
+            }
+        }
+        if (m_process_sp->GetPrivateState() == eStateRunning)
+            SetRestarted(true);
+    }
+}
+
+void
+Process::ProcessEventData::Dump (Stream *s) const
+{
+    if (m_process_sp)
+        s->Printf(" process = %p (pid = %u), ", m_process_sp.get(), m_process_sp->GetID());
+
+    s->Printf("state = %s", StateAsCString(GetState()));;
+}
+
+const Process::ProcessEventData *
+Process::ProcessEventData::GetEventDataFromEvent (const Event *event_ptr)
+{
+    if (event_ptr)
+    {
+        const EventData *event_data = event_ptr->GetData();
+        if (event_data && event_data->GetFlavor() == ProcessEventData::GetFlavorString())
+            return static_cast <const ProcessEventData *> (event_ptr->GetData());
+    }
+    return NULL;
+}
+
+ProcessSP
+Process::ProcessEventData::GetProcessFromEvent (const Event *event_ptr)
+{
+    ProcessSP process_sp;
+    const ProcessEventData *data = GetEventDataFromEvent (event_ptr);
+    if (data)
+        process_sp = data->GetProcessSP();
+    return process_sp;
+}
+
+StateType
+Process::ProcessEventData::GetStateFromEvent (const Event *event_ptr)
+{
+    const ProcessEventData *data = GetEventDataFromEvent (event_ptr);
+    if (data == NULL)
+        return eStateInvalid;
+    else
+        return data->GetState();
+}
+
+bool
+Process::ProcessEventData::GetRestartedFromEvent (const Event *event_ptr)
+{
+    const ProcessEventData *data = GetEventDataFromEvent (event_ptr);
+    if (data == NULL)
+        return false;
+    else
+        return data->GetRestarted();
+}
+
+void
+Process::ProcessEventData::SetRestartedInEvent (Event *event_ptr, bool new_value)
+{
+    ProcessEventData *data = const_cast<ProcessEventData *>(GetEventDataFromEvent (event_ptr));
+    if (data != NULL)
+        data->SetRestarted(new_value);
+}
+
+bool
+Process::ProcessEventData::SetUpdateStateOnRemoval (Event *event_ptr)
+{
+    ProcessEventData *data = const_cast<ProcessEventData *>(GetEventDataFromEvent (event_ptr));
+    if (data)
+    {
+        data->SetUpdateStateOnRemoval();
+        return true;
+    }
+    return false;
+}
+
+void
+Process::ProcessEventData::SetUpdateStateOnRemoval()
+{
+    m_update_state = true;
+}
+
+Target *
+Process::CalculateTarget ()
+{
+    return &m_target;
+}
+
+Process *
+Process::CalculateProcess ()
+{
+    return this;
+}
+
+Thread *
+Process::CalculateThread ()
+{
+    return NULL;
+}
+
+StackFrame *
+Process::CalculateStackFrame ()
+{
+    return NULL;
+}
+
+void
+Process::Calculate (ExecutionContext &exe_ctx)
+{
+    exe_ctx.target = &m_target;
+    exe_ctx.process = this;
+    exe_ctx.thread = NULL;
+    exe_ctx.frame = NULL;
+}
+
+lldb::ProcessSP
+Process::GetSP ()
+{
+    return GetTarget().GetProcessSP();
+}
+
+ObjCObjectPrinter &
+Process::GetObjCObjectPrinter()
+{
+    return m_objc_object_printer;
+}
+
diff --git a/source/Target/RegisterContext.cpp b/source/Target/RegisterContext.cpp
new file mode 100644
index 0000000..b1838ba
--- /dev/null
+++ b/source/Target/RegisterContext.cpp
@@ -0,0 +1,238 @@
+//===-- RegisterContext.cpp -------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Core/Scalar.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Thread.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// RegisterContext constructor
+//----------------------------------------------------------------------
+RegisterContext::RegisterContext (Thread &thread, StackFrame *frame) :
+    m_thread (thread),
+    m_frame (frame)
+{
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+RegisterContext::~RegisterContext()
+{
+}
+
+const RegisterInfo *
+RegisterContext::GetRegisterInfoByName (const char *reg_name, uint32_t start_idx)
+{
+    if (reg_name && reg_name[0])
+    {
+        const uint32_t num_registers = GetRegisterCount();
+        for (uint32_t reg = start_idx; reg < num_registers; ++reg)
+        {
+            const RegisterInfo * reg_info = GetRegisterInfoAtIndex(reg);
+
+            if ((reg_info->name != NULL && ::strcasecmp (reg_info->name, reg_name) == 0) ||
+                (reg_info->alt_name != NULL && ::strcasecmp (reg_info->alt_name, reg_name) == 0))
+            {
+                return reg_info;
+            }
+        }
+    }
+    return NULL;
+}
+
+const char *
+RegisterContext::GetRegisterName (uint32_t reg)
+{
+    const RegisterInfo * reg_info = GetRegisterInfoAtIndex(reg);
+    if (reg_info)
+        return reg_info->name;
+    return NULL;
+}
+
+uint64_t
+RegisterContext::GetPC(uint64_t fail_value)
+{
+    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+    return ReadRegisterAsUnsigned (reg, fail_value);
+}
+
+bool
+RegisterContext::SetPC(uint64_t pc)
+{
+    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+    bool success = WriteRegisterFromUnsigned (reg, pc);
+    if (success)
+    {
+        if (m_frame)
+            m_frame->ChangePC(pc);
+        else
+            m_thread.ClearStackFrames ();
+    }
+    return success;
+}
+
+uint64_t
+RegisterContext::GetSP(uint64_t fail_value)
+{
+    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
+    return ReadRegisterAsUnsigned (reg, fail_value);
+}
+
+bool
+RegisterContext::SetSP(uint64_t sp)
+{
+    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
+    return WriteRegisterFromUnsigned (reg, sp);
+}
+
+uint64_t
+RegisterContext::GetFP(uint64_t fail_value)
+{
+    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
+    return ReadRegisterAsUnsigned (reg, fail_value);
+}
+
+bool
+RegisterContext::SetFP(uint64_t fp)
+{
+    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
+    return WriteRegisterFromUnsigned (reg, fp);
+}
+
+uint64_t
+RegisterContext::GetReturnAddress (uint64_t fail_value)
+{
+    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
+    return ReadRegisterAsUnsigned (reg, fail_value);
+}
+
+uint64_t
+RegisterContext::GetFlags (uint64_t fail_value)
+{
+    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
+    return ReadRegisterAsUnsigned (reg, fail_value);
+}
+
+
+uint64_t
+RegisterContext::ReadRegisterAsUnsigned (uint32_t reg, uint64_t fail_value)
+{
+    if (reg != LLDB_INVALID_REGNUM)
+    {
+        Scalar value;
+        if (ReadRegisterValue (reg, value))
+            return value.GetRawBits64(fail_value);
+    }
+    return fail_value;
+}
+
+bool
+RegisterContext::WriteRegisterFromUnsigned (uint32_t reg, uint64_t uval)
+{
+    if (reg == LLDB_INVALID_REGNUM)
+        return false;
+    Scalar value(uval);
+    return WriteRegisterValue (reg, value);
+}
+
+lldb::tid_t
+RegisterContext::GetThreadID() const
+{
+    return m_thread.GetID();
+}
+
+uint32_t
+RegisterContext::NumSupportedHardwareBreakpoints ()
+{
+    return 0;
+}
+
+uint32_t
+RegisterContext::SetHardwareBreakpoint (lldb::addr_t addr, size_t size)
+{
+    return LLDB_INVALID_INDEX32;
+}
+
+bool
+RegisterContext::ClearHardwareBreakpoint (uint32_t hw_idx)
+{
+    return false;
+}
+
+
+uint32_t
+RegisterContext::NumSupportedHardwareWatchpoints ()
+{
+    return 0;
+}
+
+uint32_t
+RegisterContext::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write)
+{
+    return LLDB_INVALID_INDEX32;
+}
+
+bool
+RegisterContext::ClearHardwareWatchpoint (uint32_t hw_index)
+{
+    return false;
+}
+
+bool
+RegisterContext::HardwareSingleStep (bool enable)
+{
+    return false;
+}
+
+Target *
+RegisterContext::CalculateTarget ()
+{
+    return m_thread.CalculateTarget();
+}
+
+
+Process *
+RegisterContext::CalculateProcess ()
+{
+    return m_thread.CalculateProcess ();
+}
+
+Thread *
+RegisterContext::CalculateThread ()
+{
+    return &m_thread;
+}
+
+StackFrame *
+RegisterContext::CalculateStackFrame ()
+{
+    return m_frame;
+}
+
+void
+RegisterContext::Calculate (ExecutionContext &exe_ctx)
+{
+    if (m_frame)
+        m_frame->Calculate (exe_ctx);
+    else
+        m_thread.Calculate (exe_ctx);
+}
+
+
+
diff --git a/source/Target/StackFrame.cpp b/source/Target/StackFrame.cpp
new file mode 100644
index 0000000..cb83295
--- /dev/null
+++ b/source/Target/StackFrame.cpp
@@ -0,0 +1,393 @@
+//===-- StackFrame.cpp ------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/StackFrame.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Module.h"
+#include "lldb/Core/Disassembler.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+// The first bits in the flags are reserved for the SymbolContext::Scope bits
+// so we know if we have tried to look up information in our internal symbol
+// context (m_sc) already.
+#define RESOLVED_PC_SO_ADDR (uint32_t(eSymbolContextEverything + 1))
+#define RESOLVED_FRAME_ID   (RESOLVED_PC_SO_ADDR << 1)
+#define GOT_FRAME_BASE      (RESOLVED_FRAME_ID << 1)
+#define FRAME_IS_OBSOLETE   (GOT_FRAME_BASE << 1)
+#define RESOLVED_VARIABLES  (FRAME_IS_OBSOLETE << 1)
+
+StackFrame::StackFrame (lldb::user_id_t frame_idx, Thread &thread, lldb::addr_t cfa, lldb::addr_t pc, const SymbolContext *sc_ptr) :
+    UserID (frame_idx),
+    m_thread (thread),
+    m_reg_context_sp(),
+    m_id(cfa),
+    m_pc(NULL, pc),
+    m_sc(),
+    m_flags(),
+    m_frame_base(),
+    m_frame_base_error(),
+    m_variable_list_sp (),
+    m_value_object_list ()
+{
+    if (sc_ptr != NULL)
+        m_sc = *sc_ptr;
+}
+
+StackFrame::StackFrame (lldb::user_id_t frame_idx, Thread &thread, RegisterContextSP &reg_context_sp, lldb::addr_t cfa, lldb::addr_t pc, const SymbolContext *sc_ptr) :
+    UserID (frame_idx),
+    m_thread (thread),
+    m_reg_context_sp(reg_context_sp),
+    m_id(cfa),
+    m_pc(NULL, pc),
+    m_sc(),
+    m_flags(),
+    m_frame_base(),
+    m_frame_base_error(),
+    m_variable_list_sp (),
+    m_value_object_list ()
+{
+    if (sc_ptr != NULL)
+        m_sc = *sc_ptr;
+}
+
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+StackFrame::~StackFrame()
+{
+}
+
+StackID&
+StackFrame::GetStackID()
+{
+    // Make sure we have resolved our stack ID's address range before we give
+    // it out to any external clients
+    if (m_id.GetStartAddress().IsValid() == 0 && m_flags.IsClear(RESOLVED_FRAME_ID))
+    {
+        m_flags.Set (RESOLVED_FRAME_ID);
+
+        // Resolve our PC to section offset if we haven't alreday done so
+        // and if we don't have a module. The resolved address section will
+        // contain the module to which it belongs.
+        if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_PC_SO_ADDR))
+            GetPC();
+
+        const uint32_t resolve_scope = eSymbolContextModule |
+                                       eSymbolContextCompUnit |
+                                       eSymbolContextFunction;
+
+        if (m_sc.module_sp)
+        {
+            if (m_sc.module_sp->ResolveSymbolContextForAddress (GetPC(), resolve_scope, m_sc) & eSymbolContextFunction)
+            {
+                assert (m_sc.function);
+                m_id.SetStartAddress(m_sc.function->GetAddressRange().GetBaseAddress());
+            }
+            else if (m_sc.module_sp->ResolveSymbolContextForAddress (GetPC(), resolve_scope, m_sc) & eSymbolContextSymbol)
+            {
+                assert (m_sc.symbol);
+                AddressRange *symbol_range_ptr = m_sc.symbol->GetAddressRangePtr();
+                if (symbol_range_ptr)
+                    m_id.SetStartAddress(symbol_range_ptr->GetBaseAddress());
+            }
+        }
+//      else if (m_sc.target != NULL)
+//      {
+//          if (m_sc.target->GetImages().ResolveSymbolContextForAddress (GetPC(), resolve_scope, m_sc) & eSymbolContextFunction)
+//          {
+//              assert (m_sc.function);
+//              m_id.GetAddressRange() = m_sc.function->GetAddressRange();
+//          }
+//          else if (m_sc.target->GetImages().ResolveSymbolContextForAddress (GetPC(), resolve_scope, m_sc) & eSymbolContextSymbol)
+//          {
+//              assert (m_sc.symbol);
+//              AddressRange *symbol_range_ptr = m_sc.symbol->GetAddressRange();
+//              if (symbol_range_ptr)
+//                  m_id.GetAddressRange() = *symbol_range_ptr;
+//          }
+//      }
+    }
+    return m_id;
+}
+
+Address&
+StackFrame::GetPC()
+{
+    if (m_flags.IsClear(RESOLVED_PC_SO_ADDR) && !m_pc.IsSectionOffset())
+    {
+        m_flags.Set (RESOLVED_PC_SO_ADDR);
+
+        // Resolve the PC into a temporary address because if ResolveLoadAddress
+        // fails to resolve the address, it will clear the address object...
+        Address resolved_pc;
+        if (m_thread.GetProcess().ResolveLoadAddress(m_pc.GetOffset(), resolved_pc))
+        {
+            m_pc = resolved_pc;
+            const Section *section = m_pc.GetSection();
+            if (section)
+            {
+                Module *module = section->GetModule();
+                if (module)
+                {
+                    m_sc.module_sp = module->GetSP();
+                    if (m_sc.module_sp)
+                        m_flags.Set(eSymbolContextModule);
+                }
+            }
+        }
+    }
+    return m_pc;
+}
+
+void
+StackFrame::ChangePC (addr_t pc)
+{
+    m_pc.SetOffset(pc);
+    m_pc.SetSection(NULL);
+    m_sc.Clear();
+    m_flags.SetAllFlagBits(0);
+    m_thread.ClearStackFrames ();
+}
+
+const char *
+StackFrame::Disassemble ()
+{
+    if (m_disassembly.GetSize() == 0)
+    {
+        ExecutionContext exe_ctx;
+        Calculate(exe_ctx);
+        Disassembler::Disassemble (m_thread.GetProcess().GetTarget().GetArchitecture(),
+                                   exe_ctx,
+                                   0,
+                                   m_disassembly);
+        if (m_disassembly.GetSize() == 0)
+            return NULL;
+    }
+    return m_disassembly.GetData();
+}
+
+//----------------------------------------------------------------------
+// Get the symbol context if we already haven't done so by resolving the
+// PC address as much as possible. This way when we pass around a
+// StackFrame object, everyone will have as much information as
+// possible and no one will ever have to look things up manually.
+//----------------------------------------------------------------------
+const SymbolContext&
+StackFrame::GetSymbolContext (uint32_t resolve_scope)
+{
+    // Copy our internal symbol context into "sc".
+
+    if ((m_flags.GetAllFlagBits() & resolve_scope) != resolve_scope)
+    {
+        // Resolve our PC to section offset if we haven't alreday done so
+        // and if we don't have a module. The resolved address section will
+        // contain the module to which it belongs
+        if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_PC_SO_ADDR))
+            GetPC();
+
+        // If this is not frame zero, then we need to subtract 1 from the PC
+        // value when doing address lookups since the PC will be on the 
+        // instruction following the function call instruction...
+        
+        Address lookup_addr(GetPC());
+        if (GetID() > 0 && lookup_addr.IsValid())
+        {
+            addr_t offset = lookup_addr.GetOffset();
+            if (offset > 0)
+                lookup_addr.SetOffset(offset - 1);
+        }
+
+        if (m_sc.module_sp)
+        {
+            // We have something in our stack frame symbol context, lets check
+            // if we haven't already tried to lookup one of those things. If we
+            // haven't then we will do the query.
+            if ((m_sc.comp_unit == NULL     && (resolve_scope & eSymbolContextCompUnit ) && m_flags.IsClear(eSymbolContextCompUnit   )) ||
+                (m_sc.function  == NULL     && (resolve_scope & eSymbolContextFunction ) && m_flags.IsClear(eSymbolContextFunction   )) ||
+                (m_sc.block     == NULL     && (resolve_scope & eSymbolContextBlock    ) && m_flags.IsClear(eSymbolContextBlock      )) ||
+                (m_sc.symbol    == NULL     && (resolve_scope & eSymbolContextSymbol   ) && m_flags.IsClear(eSymbolContextSymbol     )) ||
+                (!m_sc.line_entry.IsValid() && (resolve_scope & eSymbolContextLineEntry) && m_flags.IsClear(eSymbolContextLineEntry  )))
+            {
+                // We might be resolving less information than what is already
+                // in our current symbol context so resolve into a temporary 
+                // symbol context "sc" so we don't clear out data we have 
+                // already found in "m_sc"
+                SymbolContext sc;
+                // Set flags that indicate what we have tried to resolve
+                const uint32_t resolved = m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, resolve_scope, sc);
+                if (resolved & eSymbolContextCompUnit)  m_sc.comp_unit  = sc.comp_unit;
+                if (resolved & eSymbolContextFunction)  m_sc.function   = sc.function;
+                if (resolved & eSymbolContextBlock)     m_sc.block      = sc.block;
+                if (resolved & eSymbolContextSymbol)    m_sc.symbol     = sc.symbol;
+                if (resolved & eSymbolContextLineEntry) m_sc.line_entry = sc.line_entry;
+            }
+        }
+        else
+        {
+            // If we don't have a module, then we can't have the compile unit,
+            // function, block, line entry or symbol, so we can safely call
+            // ResolveSymbolContextForAddress with our symbol context member m_sc.
+            m_thread.GetProcess().GetTarget().GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc);
+        }
+
+        // If the target was requested add that:
+        if (m_sc.target_sp.get() == NULL)
+            m_sc.target_sp = CalculateProcess()->GetTarget().GetSP();
+
+        // Update our internal flags so we remember what we have tried to locate so
+        // we don't have to keep trying when more calls to this function are made.
+        m_flags.Set(resolve_scope);
+    }
+
+    // Return the symbol context with everything that was possible to resolve
+    // resolved.
+    return m_sc;
+}
+
+
+VariableList *
+StackFrame::GetVariableList ()
+{
+    if (m_flags.IsClear(RESOLVED_VARIABLES))
+    {
+        m_flags.Set(RESOLVED_VARIABLES);
+
+        GetSymbolContext(eSymbolContextFunction);
+        if (m_sc.function)
+        {
+            bool get_child_variables = true;
+            bool can_create = true;
+            m_variable_list_sp = m_sc.function->GetBlocks(can_create).GetVariableList (Block::RootID, get_child_variables, can_create);
+        }
+    }
+    return m_variable_list_sp.get();
+}
+
+
+bool
+StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr)
+{
+    if (m_flags.IsClear(GOT_FRAME_BASE))
+    {
+        if (m_sc.function)
+        {
+            m_frame_base.Clear();
+            m_frame_base_error.Clear();
+
+            m_flags.Set(GOT_FRAME_BASE);
+            ExecutionContext exe_ctx (&m_thread.GetProcess(), &m_thread, this);
+            Value expr_value;
+            if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, expr_value, &m_frame_base_error) < 0)
+            {
+                // We should really have an error if evaluate returns, but in case
+                // we don't, lets set the error to something at least.
+                if (m_frame_base_error.Success())
+                    m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed.");
+            }
+            else
+            {
+                m_frame_base = expr_value.ResolveValue(&exe_ctx, NULL);
+            }
+        }
+        else
+        {
+            m_frame_base_error.SetErrorString ("No function in symbol context.");
+        }
+    }
+
+    if (m_frame_base_error.Success())
+        frame_base = m_frame_base;
+
+    if (error_ptr)
+        *error_ptr = m_frame_base_error;
+    return m_frame_base_error.Success();
+}
+
+RegisterContext *
+StackFrame::GetRegisterContext ()
+{
+    if (m_reg_context_sp.get() == NULL)
+        m_reg_context_sp.reset (m_thread.CreateRegisterContextForFrame (this));
+    return m_reg_context_sp.get();
+}
+
+bool
+StackFrame::HasDebugInformation ()
+{
+    GetSymbolContext(eSymbolContextLineEntry);
+    return m_sc.line_entry.IsValid();
+}
+
+ValueObjectList &
+StackFrame::GetValueObjectList()
+{
+    return m_value_object_list;
+}
+
+
+Target *
+StackFrame::CalculateTarget ()
+{
+    return m_thread.CalculateTarget();
+}
+
+Process *
+StackFrame::CalculateProcess ()
+{
+    return m_thread.CalculateProcess();
+}
+
+Thread *
+StackFrame::CalculateThread ()
+{
+    return &m_thread;
+}
+
+StackFrame *
+StackFrame::CalculateStackFrame ()
+{
+    return this;
+}
+
+
+void
+StackFrame::Calculate (ExecutionContext &exe_ctx)
+{
+    m_thread.Calculate (exe_ctx);
+    exe_ctx.frame = this;
+}
+
+void
+StackFrame::Dump (Stream *strm, bool show_frame_index)
+{
+    if (strm == NULL)
+        return;
+
+    if (show_frame_index)
+        strm->Printf("frame #%u: ", GetID());
+    strm->Printf("pc = 0x%0*llx", m_thread.GetProcess().GetAddressByteSize() * 2, GetRegisterContext()->GetPC());
+    SymbolContext sc (GetSymbolContext(eSymbolContextEverything));
+    strm->PutCString(", where = ");
+    sc.DumpStopContext(strm, &m_thread.GetProcess(), GetPC());
+}
+
diff --git a/source/Target/StackFrameList.cpp b/source/Target/StackFrameList.cpp
new file mode 100644
index 0000000..8615f71
--- /dev/null
+++ b/source/Target/StackFrameList.cpp
@@ -0,0 +1,135 @@
+//===-- StackFrameList.cpp --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Target/StackFrameList.h"
+#include "lldb/Target/StackFrame.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// StackFrameList constructor
+//----------------------------------------------------------------------
+StackFrameList::StackFrameList() :
+    m_mutex (Mutex::eMutexTypeRecursive),
+    m_frames (),
+    m_current_frame_idx (0)
+{
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+StackFrameList::~StackFrameList()
+{
+}
+
+
+uint32_t
+StackFrameList::GetNumFrames() const
+{
+    Mutex::Locker locker (m_mutex);
+    return m_frames.size();
+}
+
+// After we have determined the number of frames, we can set the count here
+// and have the frame info be generated on demand.
+void
+StackFrameList::SetNumFrames(uint32_t count)
+{
+    Mutex::Locker locker (m_mutex);
+    return m_frames.resize(count);
+}
+
+StackFrameSP
+StackFrameList::GetFrameAtIndex (uint32_t idx) const
+{
+    StackFrameSP frame_sp;
+    {
+        Mutex::Locker locker (m_mutex);
+        if (idx < m_frames.size())
+            frame_sp = m_frames[idx];
+    }
+    return frame_sp;
+}
+
+bool
+StackFrameList::SetFrameAtIndex (uint32_t idx, StackFrameSP &frame_sp)
+{
+    Mutex::Locker locker (m_mutex);
+    if (idx >= m_frames.size())
+        m_frames.resize(idx + 1);
+    // Make sure allocation succeeded by checking bounds again
+    if (idx < m_frames.size())
+    {
+        m_frames[idx] = frame_sp;
+        return true;
+    }
+    return false;   // resize failed, out of memory?
+}
+
+uint32_t
+StackFrameList::GetCurrentFrameIndex () const
+{
+    Mutex::Locker locker (m_mutex);
+    return m_current_frame_idx;
+}
+
+
+uint32_t
+StackFrameList::SetCurrentFrame (lldb_private::StackFrame *frame)
+{
+    Mutex::Locker locker (m_mutex);
+    const_iterator pos,
+                   begin = m_frames.begin(),
+                   end = m_frames.end();
+    for (pos = begin; pos != end; ++pos)
+    {
+        if (pos->get() == frame)
+        {
+            m_current_frame_idx = std::distance (begin, pos);
+            return m_current_frame_idx;
+        }
+    }
+    m_current_frame_idx = 0;
+    return m_current_frame_idx;
+}
+
+// Mark a stack frame as the current frame using the frame index
+void
+StackFrameList::SetCurrentFrameByIndex (uint32_t idx)
+{
+    Mutex::Locker locker (m_mutex);
+    m_current_frame_idx = idx;
+}
+
+// The thread has been run, reset the number stack frames to zero so we can
+// determine how many frames we have lazily.
+void
+StackFrameList::Clear ()
+{
+    Mutex::Locker locker (m_mutex);
+    m_frames.clear();
+}
+
+void
+StackFrameList::InvalidateFrames (uint32_t start_idx)
+{
+    Mutex::Locker locker (m_mutex);
+    size_t num_frames = m_frames.size();
+    while (start_idx < num_frames)
+    {
+        m_frames[start_idx].reset();
+        ++start_idx;
+    }
+}
diff --git a/source/Target/StackID.cpp b/source/Target/StackID.cpp
new file mode 100644
index 0000000..6f903ae
--- /dev/null
+++ b/source/Target/StackID.cpp
@@ -0,0 +1,110 @@
+//===-- StackID.cpp ---------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/StackID.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// StackID constructor
+//----------------------------------------------------------------------
+StackID::StackID() :
+    m_start_address(),
+    m_cfa()
+{
+}
+
+//----------------------------------------------------------------------
+// StackID constructor with args
+//----------------------------------------------------------------------
+StackID::StackID (const Address& start_address, lldb::addr_t cfa) :
+    m_start_address (start_address),
+    m_cfa (cfa)
+{
+}
+
+StackID::StackID (lldb::addr_t cfa) :
+    m_start_address (),
+    m_cfa (cfa)
+{
+}
+
+//----------------------------------------------------------------------
+// StackID copy constructor
+//----------------------------------------------------------------------
+StackID::StackID(const StackID& rhs) :
+    m_start_address (rhs.m_start_address),
+    m_cfa (rhs.m_cfa)
+{
+}
+
+//----------------------------------------------------------------------
+// StackID assignment operator
+//----------------------------------------------------------------------
+const StackID&
+StackID::operator=(const StackID& rhs)
+{
+    if (this != &rhs)
+    {
+        m_start_address = rhs.m_start_address;
+        m_cfa = rhs.m_cfa;
+    }
+    return *this;
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+StackID::~StackID()
+{
+}
+
+
+const Address&
+StackID::GetStartAddress() const
+{
+    return m_start_address;
+}
+
+void
+StackID::SetStartAddress(const Address& start_address)
+{
+    m_start_address = start_address;
+}
+
+lldb::addr_t
+StackID::GetCallFrameAddress() const
+{
+    return m_cfa;
+}
+
+
+bool
+lldb_private::operator== (const StackID& lhs, const StackID& rhs)
+{
+    return lhs.GetCallFrameAddress() == rhs.GetCallFrameAddress() && lhs.GetStartAddress() == rhs.GetStartAddress();
+}
+
+bool
+lldb_private::operator!= (const StackID& lhs, const StackID& rhs)
+{
+    return lhs.GetCallFrameAddress() != rhs.GetCallFrameAddress() || lhs.GetStartAddress() != rhs.GetStartAddress();
+}
+
+bool
+lldb_private::operator< (const StackID& lhs, const StackID& rhs)
+{
+    return lhs.GetCallFrameAddress() < rhs.GetCallFrameAddress();
+}
+
diff --git a/source/Target/Target.cpp b/source/Target/Target.cpp
new file mode 100644
index 0000000..48f2ea7
--- /dev/null
+++ b/source/Target/Target.cpp
@@ -0,0 +1,707 @@
+//===-- Target.cpp ----------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/Target.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Breakpoint/BreakpointResolver.h"
+#include "lldb/Breakpoint/BreakpointResolverAddress.h"
+#include "lldb/Breakpoint/BreakpointResolverFileLine.h"
+#include "lldb/Breakpoint/BreakpointResolverName.h"
+#include "lldb/Core/Event.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Timer.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Host/Host.h"
+#include "lldb/lldb-private-log.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Core/Debugger.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// Target constructor
+//----------------------------------------------------------------------
+Target::Target() :
+    Broadcaster("Target"),
+    m_images(),
+    m_breakpoint_list (false),
+    m_internal_breakpoint_list (true),
+    m_process_sp(),
+    m_triple(),
+    m_search_filter_sp(),
+    m_image_search_paths (ImageSearchPathsChanged, this),
+    m_scratch_ast_context_ap(NULL)
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT);
+    if (log)
+        log->Printf ("%p Target::Target()", this);
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+Target::~Target()
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT);
+    if (log)
+        log->Printf ("%p Target::~Target()", this);
+    DeleteCurrentProcess ();
+}
+
+void
+Target::Dump (Stream *s)
+{
+    s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
+    s->Indent();
+    s->PutCString("Target\n");
+    s->IndentMore();
+    m_images.Dump(s);
+    m_breakpoint_list.Dump(s);
+    m_internal_breakpoint_list.Dump(s);
+//  if (m_process_sp.get())
+//      m_process_sp->Dump(s);
+    s->IndentLess();
+}
+
+void
+Target::DeleteCurrentProcess ()
+{
+    if (m_process_sp.get())
+    {
+        if (m_process_sp->IsAlive())
+            m_process_sp->Destroy();
+        else
+            m_process_sp->Finalize();
+
+        // Do any cleanup of the target we need to do between process instances.
+        // NB It is better to do this before destroying the process in case the
+        // clean up needs some help from the process.
+        m_breakpoint_list.ClearAllBreakpointSites();
+        m_internal_breakpoint_list.ClearAllBreakpointSites();
+        m_process_sp.reset();
+    }
+}
+
+const lldb::ProcessSP &
+Target::CreateProcess (Listener &listener, const char *plugin_name)
+{
+    DeleteCurrentProcess ();
+    m_process_sp.reset(Process::FindPlugin(*this, plugin_name, listener));
+    return m_process_sp;
+}
+
+const lldb::ProcessSP &
+Target::GetProcessSP () const
+{
+    return m_process_sp;
+}
+
+lldb::TargetSP
+Target::GetSP()
+{
+    return Debugger::GetSharedInstance().GetTargetList().GetTargetSP(this);
+}
+
+BreakpointList &
+Target::GetBreakpointList(bool internal)
+{
+    if (internal)
+        return m_internal_breakpoint_list;
+    else
+        return m_breakpoint_list;
+}
+
+const BreakpointList &
+Target::GetBreakpointList(bool internal) const
+{
+    if (internal)
+        return m_internal_breakpoint_list;
+    else
+        return m_breakpoint_list;
+}
+
+BreakpointSP
+Target::GetBreakpointByID (break_id_t break_id)
+{
+    BreakpointSP bp_sp;
+
+    if (LLDB_BREAK_ID_IS_INTERNAL (break_id))
+        bp_sp = m_internal_breakpoint_list.FindBreakpointByID (break_id);
+    else
+        bp_sp = m_breakpoint_list.FindBreakpointByID (break_id);
+
+    return bp_sp;
+}
+
+BreakpointSP
+Target::CreateBreakpoint (const FileSpec *containingModule, const FileSpec &file, uint32_t line_no, bool check_inlines, bool internal)
+{
+    SearchFilterSP filter_sp(GetSearchFilterForModule (containingModule));
+    BreakpointResolverSP resolver_sp(new BreakpointResolverFileLine (NULL, file, line_no, check_inlines));
+    return CreateBreakpoint (filter_sp, resolver_sp, internal);
+}
+
+
+BreakpointSP
+Target::CreateBreakpoint (lldb::addr_t load_addr, bool internal)
+{
+    BreakpointSP bp_sp;
+    Address so_addr;
+    // Attempt to resolve our load address if possible, though it is ok if
+    // it doesn't resolve to section/offset.
+
+    Process *process = GetProcessSP().get();
+    if (process && process->ResolveLoadAddress(load_addr, so_addr))
+        bp_sp = CreateBreakpoint(so_addr, internal);
+    return bp_sp;
+}
+
+BreakpointSP
+Target::CreateBreakpoint (Address &addr, bool internal)
+{
+    TargetSP target_sp = this->GetSP();
+    SearchFilterSP filter_sp(new SearchFilter (target_sp));
+    BreakpointResolverSP resolver_sp (new BreakpointResolverAddress (NULL, addr));
+    return CreateBreakpoint (filter_sp, resolver_sp, internal);
+}
+
+BreakpointSP
+Target::CreateBreakpoint (FileSpec *containingModule, const char *func_name, bool internal)
+{
+    SearchFilterSP filter_sp(GetSearchFilterForModule (containingModule));
+    BreakpointResolverSP resolver_sp (new BreakpointResolverName (NULL, func_name));
+    return CreateBreakpoint (filter_sp, resolver_sp, internal);
+}
+
+
+SearchFilterSP
+Target::GetSearchFilterForModule (const FileSpec *containingModule)
+{
+    SearchFilterSP filter_sp;
+    lldb::TargetSP target_sp = this->GetSP();
+    if (containingModule != NULL)
+    {
+        // TODO: We should look into sharing module based search filters
+        // across many breakpoints like we do for the simple target based one
+        filter_sp.reset (new SearchFilterByModule (target_sp, *containingModule));
+    }
+    else
+    {
+        if (m_search_filter_sp.get() == NULL)
+            m_search_filter_sp.reset (new SearchFilter (target_sp));
+        filter_sp = m_search_filter_sp;
+    }
+    return filter_sp;
+}
+
+BreakpointSP
+Target::CreateBreakpoint (FileSpec *containingModule, RegularExpression &func_regex, bool internal)
+{
+    SearchFilterSP filter_sp(GetSearchFilterForModule (containingModule));
+    BreakpointResolverSP resolver_sp(new BreakpointResolverName (NULL, func_regex));
+
+    return CreateBreakpoint (filter_sp, resolver_sp, internal);
+}
+
+BreakpointSP
+Target::CreateBreakpoint (SearchFilterSP &filter_sp, BreakpointResolverSP &resolver_sp, bool internal)
+{
+    BreakpointSP bp_sp;
+    if (filter_sp && resolver_sp)
+    {
+        bp_sp.reset(new Breakpoint (*this, filter_sp, resolver_sp));
+        resolver_sp->SetBreakpoint (bp_sp.get());
+
+        if (internal)
+            m_internal_breakpoint_list.Add (bp_sp);
+        else
+            m_breakpoint_list.Add (bp_sp);
+
+        Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
+        if (log)
+        {
+            StreamString s;
+            bp_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
+            log->Printf ("Target::%s (internal = %s) => break_id = %s\n", __FUNCTION__, internal ? "yes" : "no", s.GetData());
+        }
+
+        // Broadcast the breakpoint creation event.
+        if (!internal && EventTypeHasListeners(eBroadcastBitBreakpointChanged))
+        {
+            BroadcastEvent (eBroadcastBitBreakpointChanged,
+                            new Breakpoint::BreakpointEventData (Breakpoint::BreakpointEventData::eBreakpointAdded, bp_sp));
+        }
+
+        bp_sp->ResolveBreakpoint();
+    }
+    return bp_sp;
+}
+
+void
+Target::RemoveAllBreakpoints (bool internal_also)
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
+    if (log)
+        log->Printf ("Target::%s (internal_also = %s)\n", __FUNCTION__, internal_also ? "yes" : "no");
+
+    m_breakpoint_list.RemoveAll();
+    if (internal_also)
+        m_internal_breakpoint_list.RemoveAll();
+}
+
+void
+Target::DisableAllBreakpoints (bool internal_also)
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
+    if (log)
+        log->Printf ("Target::%s (internal_also = %s)\n", __FUNCTION__, internal_also ? "yes" : "no");
+
+    m_breakpoint_list.SetEnabledAll (false);
+    if (internal_also)
+        m_internal_breakpoint_list.SetEnabledAll (false);
+}
+
+void
+Target::EnableAllBreakpoints (bool internal_also)
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
+    if (log)
+        log->Printf ("Target::%s (internal_also = %s)\n", __FUNCTION__, internal_also ? "yes" : "no");
+
+    m_breakpoint_list.SetEnabledAll (true);
+    if (internal_also)
+        m_internal_breakpoint_list.SetEnabledAll (true);
+}
+
+bool
+Target::RemoveBreakpointByID (break_id_t break_id)
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
+    if (log)
+        log->Printf ("Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__, break_id, LLDB_BREAK_ID_IS_INTERNAL (break_id) ? "yes" : "no");
+
+    if (DisableBreakpointByID (break_id))
+    {
+        if (LLDB_BREAK_ID_IS_INTERNAL (break_id))
+            m_internal_breakpoint_list.Remove(break_id);
+        else
+            m_breakpoint_list.Remove(break_id);
+        return true;
+    }
+    return false;
+}
+
+bool
+Target::DisableBreakpointByID (break_id_t break_id)
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
+    if (log)
+        log->Printf ("Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__, break_id, LLDB_BREAK_ID_IS_INTERNAL (break_id) ? "yes" : "no");
+
+    BreakpointSP bp_sp;
+
+    if (LLDB_BREAK_ID_IS_INTERNAL (break_id))
+        bp_sp = m_internal_breakpoint_list.FindBreakpointByID (break_id);
+    else
+        bp_sp = m_breakpoint_list.FindBreakpointByID (break_id);
+    if (bp_sp)
+    {
+        bp_sp->SetEnabled (false);
+        return true;
+    }
+    return false;
+}
+
+bool
+Target::EnableBreakpointByID (break_id_t break_id)
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
+    if (log)
+        log->Printf ("Target::%s (break_id = %i, internal = %s)\n",
+                     __FUNCTION__,
+                     break_id,
+                     LLDB_BREAK_ID_IS_INTERNAL (break_id) ? "yes" : "no");
+
+    BreakpointSP bp_sp;
+
+    if (LLDB_BREAK_ID_IS_INTERNAL (break_id))
+        bp_sp = m_internal_breakpoint_list.FindBreakpointByID (break_id);
+    else
+        bp_sp = m_breakpoint_list.FindBreakpointByID (break_id);
+
+    if (bp_sp)
+    {
+        bp_sp->SetEnabled (true);
+        return true;
+    }
+    return false;
+}
+
+ModuleSP
+Target::GetExecutableModule ()
+{
+    ModuleSP executable_sp;
+    if (m_images.GetSize() > 0)
+        executable_sp = m_images.GetModuleAtIndex(0);
+    return executable_sp;
+}
+
+void
+Target::SetExecutableModule (ModuleSP& executable_sp, bool get_dependent_files)
+{
+    m_images.Clear();
+    m_scratch_ast_context_ap.reset();
+    
+    if (executable_sp.get())
+    {
+        Timer scoped_timer (__PRETTY_FUNCTION__,
+                            "Target::SetExecutableModule (executable = '%s/%s')",
+                            executable_sp->GetFileSpec().GetDirectory().AsCString(),
+                            executable_sp->GetFileSpec().GetFilename().AsCString());
+
+        m_images.Append(executable_sp); // The first image is our exectuable file
+
+        ArchSpec exe_arch = executable_sp->GetArchitecture();
+        FileSpecList dependent_files;
+        ObjectFile * executable_objfile = executable_sp->GetObjectFile();
+        if (executable_objfile == NULL)
+        {
+
+            FileSpec bundle_executable(executable_sp->GetFileSpec());
+            if (Host::ResolveExecutableInBundle (&bundle_executable))
+            {
+                ModuleSP bundle_exe_module_sp(GetSharedModule(bundle_executable,
+                                                              exe_arch));
+                SetExecutableModule (bundle_exe_module_sp, get_dependent_files);
+                if (bundle_exe_module_sp->GetObjectFile() != NULL)
+                    executable_sp = bundle_exe_module_sp;
+                return;
+            }
+        }
+
+        if (executable_objfile)
+        {
+            executable_objfile->GetDependentModules(dependent_files);
+            for (uint32_t i=0; i<dependent_files.GetSize(); i++)
+            {
+                ModuleSP image_module_sp(GetSharedModule(dependent_files.GetFileSpecPointerAtIndex(i),
+                                                         exe_arch));
+                if (image_module_sp.get())
+                {
+                    //image_module_sp->Dump(&s);// REMOVE THIS, DEBUG ONLY
+                    ObjectFile *objfile = image_module_sp->GetObjectFile();
+                    if (objfile)
+                        objfile->GetDependentModules(dependent_files);
+                }
+            }
+        }
+        
+        // Now see if we know the target triple, and if so, create our scratch AST context:
+        ConstString target_triple;
+        if (GetTargetTriple(target_triple))
+        {
+            m_scratch_ast_context_ap.reset (new ClangASTContext(target_triple.GetCString()));
+        }
+    }
+}
+
+
+ModuleList&
+Target::GetImages ()
+{
+    return m_images;
+}
+
+ArchSpec
+Target::GetArchitecture () const
+{
+    ArchSpec arch;
+    if (m_images.GetSize() > 0)
+    {
+        Module *exe_module = m_images.GetModulePointerAtIndex(0);
+        if (exe_module)
+            arch = exe_module->GetArchitecture();
+    }
+    return arch;
+}
+
+
+
+bool
+Target::GetTargetTriple(ConstString &triple)
+{
+    triple.Clear();
+
+    if (m_triple)
+    {
+        triple = m_triple;
+    }
+    else
+    {
+        Module *exe_module = GetExecutableModule().get();
+        if (exe_module)
+        {
+            ObjectFile *objfile = exe_module->GetObjectFile();
+            if (objfile)
+            {
+                objfile->GetTargetTriple(m_triple);
+                triple = m_triple;
+            }
+        }
+    }
+    return !triple.IsEmpty();
+}
+
+void
+Target::ModuleAdded (ModuleSP &module_sp)
+{
+    // A module is being added to this target for the first time
+    ModuleList module_list;
+    module_list.Append(module_sp);
+    ModulesDidLoad (module_list);
+}
+
+void
+Target::ModuleUpdated (ModuleSP &old_module_sp, ModuleSP &new_module_sp)
+{
+    // A module is being added to this target for the first time
+    ModuleList module_list;
+    module_list.Append (old_module_sp);
+    ModulesDidUnload (module_list);
+    module_list.Clear ();
+    module_list.Append (new_module_sp);
+    ModulesDidLoad (module_list);
+}
+
+void
+Target::ModulesDidLoad (ModuleList &module_list)
+{
+    m_breakpoint_list.UpdateBreakpoints (module_list, true);
+    // TODO: make event data that packages up the module_list
+    BroadcastEvent (eBroadcastBitModulesLoaded, NULL);
+}
+
+void
+Target::ModulesDidUnload (ModuleList &module_list)
+{
+    m_breakpoint_list.UpdateBreakpoints (module_list, false);
+    // TODO: make event data that packages up the module_list
+    BroadcastEvent (eBroadcastBitModulesUnloaded, NULL);
+}
+
+size_t
+Target::ReadMemory
+(
+    lldb::AddressType addr_type,
+    lldb::addr_t addr,
+    void *dst,
+    size_t dst_len,
+    Error &error,
+    ObjectFile* objfile
+)
+{
+    size_t bytes_read = 0;
+    error.Clear();
+    switch (addr_type)
+    {
+    case eAddressTypeFile:
+        if (objfile)
+        {
+            if (m_process_sp.get())
+            {
+                // If we have an execution context with a process, lets try and
+                // resolve the file address in "objfile" and read it from the
+                // process
+                Address so_addr(addr, objfile->GetSectionList());
+                lldb::addr_t load_addr = so_addr.GetLoadAddress(m_process_sp.get());
+                if (load_addr == LLDB_INVALID_ADDRESS)
+                {
+                    if (objfile->GetFileSpec())
+                        error.SetErrorStringWithFormat("0x%llx can't be resolved, %s in not currently loaded.\n", addr, objfile->GetFileSpec().GetFilename().AsCString());
+                    else
+                        error.SetErrorStringWithFormat("0x%llx can't be resolved.\n", addr, objfile->GetFileSpec().GetFilename().AsCString());
+                }
+                else
+                {
+                    bytes_read = m_process_sp->ReadMemory(load_addr, dst, dst_len, error);
+                    if (bytes_read != dst_len)
+                    {
+                        if (error.Success())
+                        {
+                            if (bytes_read == 0)
+                                error.SetErrorStringWithFormat("Read memory from 0x%llx failed.\n", load_addr);
+                            else
+                                error.SetErrorStringWithFormat("Only %zu of %zu bytes were read from memory at 0x%llx.\n", bytes_read, dst_len, load_addr);
+                        }
+                    }
+                }
+            }
+            else
+            {
+                // Try and read the file based address from the object file's
+                // section data.
+            }
+        }
+        break;
+
+    case eAddressTypeLoad:
+        if (m_process_sp.get())
+        {
+            bytes_read = m_process_sp->ReadMemory(addr, dst, dst_len, error);
+            if (bytes_read != dst_len)
+            {
+                if (error.Success())
+                {
+                    if (bytes_read == 0)
+                        error.SetErrorStringWithFormat("Read memory from 0x%llx failed.\n", addr);
+                    else
+                        error.SetErrorStringWithFormat("Only %zu of %zu bytes were read from memory at 0x%llx.\n", bytes_read, dst_len, addr);
+                }
+            }
+        }
+        else
+            error.SetErrorStringWithFormat("Need valid process to read load address.\n");
+        break;
+
+    case eAddressTypeHost:
+        // The address is an address in this process, so just copy it
+        ::memcpy (dst, (uint8_t*)NULL + addr, dst_len);
+        break;
+
+    default:
+        error.SetErrorStringWithFormat ("Unsupported lldb::AddressType value (%i).\n", addr_type);
+        break;
+    }
+    return bytes_read;
+}
+
+
+ModuleSP
+Target::GetSharedModule
+(
+    const FileSpec& file_spec,
+    const ArchSpec& arch,
+    const UUID *uuid_ptr,
+    const ConstString *object_name,
+    off_t object_offset,
+    Error *error_ptr
+)
+{
+    // Don't pass in the UUID so we can tell if we have a stale value in our list
+    ModuleSP old_module_sp; // This will get filled in if we have a new version of the library
+    bool did_create_module = false;
+    ModuleSP module_sp;
+
+    // If there are image search path entries, try to use them first to acquire a suitable image.
+
+    Error error;
+
+    if (m_image_search_paths.GetSize())
+    {
+        FileSpec transformed_spec;        
+        if (m_image_search_paths.RemapPath (file_spec.GetDirectory(), transformed_spec.GetDirectory()))
+        {
+            transformed_spec.GetFilename() = file_spec.GetFilename();
+            error = ModuleList::GetSharedModule (transformed_spec, arch, uuid_ptr, object_name, object_offset, module_sp, &old_module_sp, &did_create_module);
+        }
+    }
+
+    // If a module hasn't been found yet, use the unmodified path.
+
+    if (!module_sp)
+    {
+        error = (ModuleList::GetSharedModule (file_spec, arch, uuid_ptr, object_name, object_offset, module_sp, &old_module_sp, &did_create_module));
+    }
+
+    if (module_sp)
+    {
+        m_images.Append (module_sp);
+        if (did_create_module)
+        {
+            if (old_module_sp && m_images.GetIndexForModule (old_module_sp.get()) != LLDB_INVALID_INDEX32)
+                ModuleUpdated(old_module_sp, module_sp);
+            else
+                ModuleAdded(module_sp);
+        }
+    }
+    if (error_ptr)
+        *error_ptr = error;
+    return module_sp;
+}
+
+
+Target *
+Target::CalculateTarget ()
+{
+    return this;
+}
+
+Process *
+Target::CalculateProcess ()
+{
+    return NULL;
+}
+
+Thread *
+Target::CalculateThread ()
+{
+    return NULL;
+}
+
+StackFrame *
+Target::CalculateStackFrame ()
+{
+    return NULL;
+}
+
+void
+Target::Calculate (ExecutionContext &exe_ctx)
+{
+    exe_ctx.target = this;
+    exe_ctx.process = NULL; // Do NOT fill in process...
+    exe_ctx.thread = NULL;
+    exe_ctx.frame = NULL;
+}
+
+PathMappingList &
+Target::GetImageSearchPathList ()
+{
+    return m_image_search_paths;
+}
+
+void
+Target::ImageSearchPathsChanged 
+(
+    const PathMappingList &path_list,
+    void *baton
+)
+{
+    Target *target = (Target *)baton;
+    if (target->m_images.GetSize() > 1)
+    {
+        ModuleSP exe_module_sp (target->GetExecutableModule());
+        if (exe_module_sp)
+        {
+            target->m_images.Clear();
+            target->SetExecutableModule (exe_module_sp, true);
+        }
+    }
+}
+
+ClangASTContext *
+Target::GetScratchClangASTContext()
+{
+    return m_scratch_ast_context_ap.get();
+}
diff --git a/source/Target/TargetList.cpp b/source/Target/TargetList.cpp
new file mode 100644
index 0000000..d929400
--- /dev/null
+++ b/source/Target/TargetList.cpp
@@ -0,0 +1,342 @@
+//===-- TargetList.cpp ------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Broadcaster.h"
+#include "lldb/Core/Event.h"
+#include "lldb/Core/State.h"
+#include "lldb/Core/Timer.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/TargetList.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+
+//----------------------------------------------------------------------
+// TargetList constructor
+//----------------------------------------------------------------------
+TargetList::TargetList() :
+    Broadcaster("TargetList"),
+    m_target_list(),
+    m_target_list_mutex (Mutex::eMutexTypeRecursive),
+    m_current_target_idx (0)
+{
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+TargetList::~TargetList()
+{
+    Mutex::Locker locker(m_target_list_mutex);
+    m_target_list.clear();
+}
+
+Error
+TargetList::CreateTarget
+(
+    const FileSpec& file,
+    const ArchSpec& arch,
+    const UUID *uuid_ptr,
+    bool get_dependent_files,
+    TargetSP &target_sp
+)
+{
+    Timer scoped_timer (__PRETTY_FUNCTION__,
+                        "TargetList::CreateTarget (file = '%s/%s', arch = '%s', uuid = %p)",
+                        file.GetDirectory().AsCString(),
+                        file.GetFilename().AsCString(),
+                        arch.AsCString(),
+                        uuid_ptr);
+    ModuleSP exe_module_sp;
+    FileSpec resolved_file(file);
+    if (!Host::ResolveExecutableInBundle (&resolved_file))
+        resolved_file = file;
+
+    Error error = ModuleList::GetSharedModule(resolved_file, 
+                                              arch, 
+                                              uuid_ptr, 
+                                              NULL, 
+                                              0, 
+                                              exe_module_sp, 
+                                              NULL, 
+                                              NULL);
+    if (exe_module_sp)
+    {
+        target_sp.reset(new Target);
+        target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
+
+        if (target_sp.get())
+        {
+            Mutex::Locker locker(m_target_list_mutex);
+            m_current_target_idx = m_target_list.size();
+            m_target_list.push_back(target_sp);
+        }
+
+//        target_sp.reset(new Target);
+//        // Let the target resolve any funky bundle paths before we try and get
+//        // the object file...
+//        target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
+//        if (exe_module_sp->GetObjectFile() == NULL)
+//        {
+//            error.SetErrorStringWithFormat("%s%s%s: doesn't contain architecture %s",
+//                                           file.GetDirectory().AsCString(),
+//                                           file.GetDirectory() ? "/" : "",
+//                                           file.GetFilename().AsCString(),
+//                                           arch.AsCString());
+//        }
+//        else
+//        {
+//            if (target_sp.get())
+//            {
+//                error.Clear();
+//                Mutex::Locker locker(m_target_list_mutex);
+//                m_current_target_idx = m_target_list.size();
+//                m_target_list.push_back(target_sp);
+//            }
+//        }
+    }
+    else
+    {
+        target_sp.reset();
+    }
+
+    return error;
+}
+
+bool
+TargetList::DeleteTarget (TargetSP &target_sp)
+{
+    Mutex::Locker locker(m_target_list_mutex);
+    collection::iterator pos, end = m_target_list.end();
+
+    for (pos = m_target_list.begin(); pos != end; ++pos)
+    {
+        if (pos->get() == target_sp.get())
+        {
+            m_target_list.erase(pos);
+            return true;
+        }
+    }
+    return false;
+}
+
+
+TargetSP
+TargetList::FindTargetWithExecutableAndArchitecture
+(
+    const FileSpec &exe_file_spec,
+    const ArchSpec *exe_arch_ptr
+) const
+{
+    Mutex::Locker locker (m_target_list_mutex);
+    TargetSP target_sp;
+    bool full_match = exe_file_spec.GetDirectory();
+
+    collection::const_iterator pos, end = m_target_list.end();
+    for (pos = m_target_list.begin(); pos != end; ++pos)
+    {
+        ModuleSP module_sp ((*pos)->GetExecutableModule());
+
+        if (module_sp)
+        {
+            if (FileSpec::Equal (exe_file_spec, module_sp->GetFileSpec(), full_match))
+            {
+                if (exe_arch_ptr)
+                {
+                    if (*exe_arch_ptr != module_sp->GetArchitecture())
+                        continue;
+                }
+                target_sp = *pos;
+                break;
+            }
+        }
+    }
+    return target_sp;
+}
+
+TargetSP
+TargetList::FindTargetWithProcessID (lldb::pid_t pid) const
+{
+    Mutex::Locker locker(m_target_list_mutex);
+    TargetSP target_sp;
+    collection::const_iterator pos, end = m_target_list.end();
+    for (pos = m_target_list.begin(); pos != end; ++pos)
+    {
+        Process* process = (*pos)->GetProcessSP().get();
+        if (process && process->GetID() == pid)
+        {
+            target_sp = *pos;
+            break;
+        }
+    }
+    return target_sp;
+}
+
+
+TargetSP
+TargetList::FindTargetWithProcess (Process *process) const
+{
+    TargetSP target_sp;
+    if (process)
+    {
+        Mutex::Locker locker(m_target_list_mutex);
+        collection::const_iterator pos, end = m_target_list.end();
+        for (pos = m_target_list.begin(); pos != end; ++pos)
+        {
+            if (process == (*pos)->GetProcessSP().get())
+            {
+                target_sp = *pos;
+                break;
+            }
+        }
+    }
+    return target_sp;
+}
+
+TargetSP
+TargetList::GetTargetSP (Target *target) const
+{
+    TargetSP target_sp;
+    if (target)
+    {
+        Mutex::Locker locker(m_target_list_mutex);
+        collection::const_iterator pos, end = m_target_list.end();
+        for (pos = m_target_list.begin(); pos != end; ++pos)
+        {
+            if (target == (*pos).get())
+            {
+                target_sp = *pos;
+                break;
+            }
+        }
+    }
+    return target_sp;
+}
+
+uint32_t
+TargetList::SendAsyncInterrupt (lldb::pid_t pid)
+{
+    uint32_t num_async_interrupts_sent = 0;
+
+    if (pid != LLDB_INVALID_PROCESS_ID)
+    {
+        TargetSP target_sp(FindTargetWithProcessID (pid));
+        if (target_sp.get())
+        {
+            Process* process = target_sp->GetProcessSP().get();
+            if (process)
+            {
+                process->BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
+                ++num_async_interrupts_sent;
+            }
+        }
+    }
+    else
+    {
+        // We don't have a valid pid to broadcast to, so broadcast to the target
+        // list's async broadcaster...
+        BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
+    }
+
+    return num_async_interrupts_sent;
+}
+
+uint32_t
+TargetList::SignalIfRunning (lldb::pid_t pid, int signo)
+{
+    uint32_t num_signals_sent = 0;
+    Process *process = NULL;
+    if (pid == LLDB_INVALID_PROCESS_ID)
+    {
+        // Signal all processes with signal
+        Mutex::Locker locker(m_target_list_mutex);
+        collection::iterator pos, end = m_target_list.end();
+        for (pos = m_target_list.begin(); pos != end; ++pos)
+        {
+            process = (*pos)->GetProcessSP().get();
+            if (process)
+            {
+                if (process->IsAlive())
+                {
+                    ++num_signals_sent;
+                    process->Signal (signo);
+                }
+            }
+        }
+    }
+    else
+    {
+        // Signal a specific process with signal
+        TargetSP target_sp(FindTargetWithProcessID (pid));
+        if (target_sp.get())
+        {
+            process = target_sp->GetProcessSP().get();
+            if (process)
+            {
+                if (process->IsAlive())
+                {
+                    ++num_signals_sent;
+                    process->Signal (signo);
+                }
+            }
+        }
+    }
+    return num_signals_sent;
+}
+
+int
+TargetList::GetNumTargets () const
+{
+    Mutex::Locker locker (m_target_list_mutex);
+    return m_target_list.size();
+}
+
+lldb::TargetSP
+TargetList::GetTargetAtIndex (uint32_t idx) const
+{
+    TargetSP target_sp;
+    Mutex::Locker locker (m_target_list_mutex);
+    if (idx < m_target_list.size())
+        target_sp = m_target_list[idx];
+    return target_sp;
+}
+
+uint32_t
+TargetList::SetCurrentTarget (Target* target)
+{
+    Mutex::Locker locker (m_target_list_mutex);
+    collection::const_iterator pos,
+        begin = m_target_list.begin(),
+        end = m_target_list.end();
+    for (pos = begin; pos != end; ++pos)
+    {
+        if (pos->get() == target)
+        {
+            m_current_target_idx = std::distance (begin, pos);
+            return m_current_target_idx;
+        }
+    }
+    m_current_target_idx = 0;
+    return m_current_target_idx;
+}
+
+lldb::TargetSP
+TargetList::GetCurrentTarget ()
+{
+    Mutex::Locker locker (m_target_list_mutex);
+    if (m_current_target_idx >= m_target_list.size())
+        m_current_target_idx = 0;
+    return GetTargetAtIndex (m_current_target_idx);
+}
diff --git a/source/Target/Thread.cpp b/source/Target/Thread.cpp
new file mode 100644
index 0000000..2f852cc
--- /dev/null
+++ b/source/Target/Thread.cpp
@@ -0,0 +1,1121 @@
+//===-- Thread.cpp ----------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-private-log.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Target/DynamicLoader.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+#include "lldb/Target/ThreadPlanCallFunction.h"
+#include "lldb/Target/ThreadPlanContinue.h"
+#include "lldb/Target/ThreadPlanBase.h"
+#include "lldb/Target/ThreadPlanStepInstruction.h"
+#include "lldb/Target/ThreadPlanStepOut.h"
+#include "lldb/Target/ThreadPlanStepOverBreakpoint.h"
+#include "lldb/Target/ThreadPlanStepThrough.h"
+#include "lldb/Target/ThreadPlanStepInRange.h"
+#include "lldb/Target/ThreadPlanStepOverRange.h"
+#include "lldb/Target/ThreadPlanRunToAddress.h"
+#include "lldb/Target/ThreadPlanStepUntil.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+Thread::Thread (Process &process, lldb::tid_t tid) :
+    UserID (tid),
+    m_index_id (process.GetNextThreadIndexID ()),
+    m_reg_context_sp (),
+    m_process (process),
+    m_state (eStateUnloaded),
+    m_plan_stack (),
+    m_immediate_plan_stack(),
+    m_completed_plan_stack(),
+    m_state_mutex (Mutex::eMutexTypeRecursive),
+    m_frames (),
+    m_current_frame_idx (0),
+    m_resume_signal (LLDB_INVALID_SIGNAL_NUMBER),
+    m_resume_state (eStateRunning)
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT);
+    if (log)
+        log->Printf ("%p Thread::Thread(tid = 0x%4.4x)", this, GetID());
+
+    QueueFundamentalPlan(true);
+}
+
+
+Thread::~Thread()
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT);
+    if (log)
+        log->Printf ("%p Thread::~Thread(tid = 0x%4.4x)", this, GetID());
+}
+
+int
+Thread::GetResumeSignal () const
+{
+    return m_resume_signal;
+}
+
+void
+Thread::SetResumeSignal (int signal)
+{
+    m_resume_signal = signal;
+}
+
+StateType
+Thread::GetResumeState () const
+{
+    return m_resume_state;
+}
+
+void
+Thread::SetResumeState (StateType state)
+{
+    m_resume_state = state;
+}
+
+Thread::StopInfo::StopInfo(Thread *thread) :
+    m_reason (eStopReasonInvalid),
+    m_description (),
+    m_thread (thread),
+    m_details ()
+{
+    m_description[0] = '\0';
+}
+
+Thread::StopInfo::~StopInfo()
+{
+}
+
+
+void
+Thread::StopInfo::Clear()
+{
+    m_reason = eStopReasonInvalid;
+    m_completed_plan_sp.reset();
+    m_description[0] = '\0';
+    ::bzero (&m_details, sizeof(m_details));
+}
+
+StopReason
+Thread::StopInfo::GetStopReason() const
+{
+    return m_reason;
+}
+
+const char *
+Thread::StopInfo::GetStopDescription() const
+{
+    if (m_description[0])
+        return m_description;
+    return NULL;
+}
+
+void
+Thread::StopInfo::SetStopDescription(const char *desc)
+{
+    if (desc && desc[0])
+    {
+        ::snprintf (m_description, sizeof(m_description), "%s", desc);
+    }
+    else
+    {
+        m_description[0] = '\0';
+    }
+}
+
+void
+Thread::StopInfo::SetThread (Thread* thread)
+{
+    m_thread = thread;
+}
+
+Thread *
+Thread::StopInfo::GetThread ()
+{
+    return m_thread;
+}
+
+lldb::user_id_t
+Thread::StopInfo::GetBreakpointSiteID() const
+{
+    if (m_reason == eStopReasonBreakpoint)
+        return m_details.breakpoint.bp_site_id;
+    return LLDB_INVALID_BREAK_ID;
+}
+
+void
+Thread::StopInfo::SetStopReasonWithBreakpointSiteID (lldb::user_id_t bp_site_id)
+{
+    m_reason = eStopReasonBreakpoint;
+    m_details.breakpoint.bp_site_id = bp_site_id;
+}
+
+lldb::user_id_t
+Thread::StopInfo::GetWatchpointID() const
+{
+    if (m_reason == eStopReasonWatchpoint)
+        return m_details.watchpoint.watch_id;
+    return LLDB_INVALID_WATCH_ID;
+}
+
+void
+Thread::StopInfo::SetStopReasonWithWatchpointID (lldb::user_id_t watch_id)
+{
+    m_reason = eStopReasonWatchpoint;
+    m_details.watchpoint.watch_id = watch_id;
+}
+
+
+int
+Thread::StopInfo::GetSignal() const
+{
+    if (m_reason == eStopReasonSignal)
+        return m_details.signal.signo;
+    return 0;
+}
+
+lldb::user_id_t
+Thread::StopInfo::GetPlanID() const
+{
+    if (m_reason == eStopReasonPlanComplete)
+        return m_completed_plan_sp->GetID();
+    return LLDB_INVALID_UID;
+}
+
+void
+Thread::StopInfo::SetStopReasonWithSignal (int signo)
+{
+    m_reason = eStopReasonSignal;
+    m_details.signal.signo = signo;
+}
+
+void
+Thread::StopInfo::SetStopReasonToTrace ()
+{
+    m_reason = eStopReasonTrace;
+}
+
+uint32_t
+Thread::StopInfo::GetExceptionType() const
+{
+    if (m_reason == eStopReasonException)
+        return m_details.exception.type;
+    return 0;
+}
+
+size_t
+Thread::StopInfo::GetExceptionDataCount() const
+{
+    if (m_reason == eStopReasonException)
+        return m_details.exception.data_count;
+    return 0;
+}
+
+void
+Thread::StopInfo::SetStopReasonWithException (uint32_t exc_type, size_t exc_data_count)
+{
+    m_reason = eStopReasonException;
+    m_details.exception.type = exc_type;
+    m_details.exception.data_count = exc_data_count;
+}
+
+void
+Thread::StopInfo::SetStopReasonWithPlan (ThreadPlanSP &thread_plan_sp)
+{
+    m_reason = eStopReasonPlanComplete;
+    m_completed_plan_sp = thread_plan_sp;
+}
+
+void
+Thread::StopInfo::SetStopReasonToNone ()
+{
+    Clear();
+    m_reason = eStopReasonNone;
+}
+
+lldb::addr_t
+Thread::StopInfo::GetExceptionDataAtIndex (uint32_t idx) const
+{
+    if (m_reason == eStopReasonException && idx < m_details.exception.data_count)
+        return m_details.exception.data[idx];
+    return 0;
+
+}
+
+
+bool
+Thread::StopInfo::SetExceptionDataAtIndex (uint32_t idx, lldb::addr_t data)
+{
+    if (m_reason == eStopReasonException && idx < m_details.exception.data_count)
+    {
+        m_details.exception.data[idx] = data;
+        return true;
+    }
+    return false;
+}
+
+void
+Thread::StopInfo::Dump (Stream *s) const
+{
+    if (m_description[0])
+        s->Printf("%s", m_description);
+    else
+    {
+        switch (m_reason)
+        {
+        case eStopReasonInvalid:
+            s->PutCString("invalid");
+            break;
+
+        case eStopReasonNone:
+            s->PutCString("none");
+            break;
+
+        case eStopReasonTrace:
+            s->PutCString("trace");
+            break;
+
+        case eStopReasonBreakpoint:
+            {
+                bool no_details = true;
+                s->PutCString ("breakpoint ");
+                if (m_thread)
+                {
+                    BreakpointSiteSP bp_site_sp = m_thread->GetProcess().GetBreakpointSiteList().FindByID(m_details.breakpoint.bp_site_id);
+                    if (bp_site_sp)
+                    {
+                        bp_site_sp->GetDescription(s, lldb::eDescriptionLevelBrief);
+                        no_details = false;
+                    }
+                }
+
+                if (no_details)
+                    s->Printf ("site id: %d", m_details.breakpoint.bp_site_id);
+            }
+            break;
+
+        case eStopReasonWatchpoint:
+            s->Printf("watchpoint (site id = %u)", m_details.watchpoint.watch_id);
+            break;
+
+        case eStopReasonSignal:
+            {
+                s->Printf("signal: signo = %i", m_details.signal.signo);
+                const char * signal_name = m_thread->GetProcess().GetUnixSignals().GetSignalAsCString (m_details.signal.signo);
+                if (signal_name)
+                    s->Printf(" (%s)", signal_name);
+            }
+            break;
+
+        case eStopReasonException:
+            {
+                s->Printf("exception: type = 0x%8.8x, data_count = %zu", m_details.exception.type, m_details.exception.data_count);
+                uint32_t i;
+                for (i=0; i<m_details.exception.data_count; ++i)
+                {
+                    s->Printf(", data[%u] = 0x%8.8llx", i, m_details.exception.data[i]);
+                }
+            }
+            break;
+
+        case eStopReasonPlanComplete:
+            {
+                m_completed_plan_sp->GetDescription (s, lldb::eDescriptionLevelBrief);
+            }
+            break;
+        }
+    }
+}
+
+bool
+Thread::GetStopInfo (Thread::StopInfo *stop_info)
+{
+    stop_info->SetThread(this);
+    ThreadPlanSP completed_plan = GetCompletedPlan();
+    if (completed_plan != NULL)
+    {
+        stop_info->Clear ();
+        stop_info->SetStopReasonWithPlan (completed_plan);
+        return true;
+    }
+    else
+        return GetRawStopReason (stop_info);
+}
+
+bool
+Thread::ThreadStoppedForAReason (void)
+{
+    Thread::StopInfo stop_info;
+    stop_info.SetThread(this);
+    if (GetRawStopReason (&stop_info))
+    {
+        StopReason reason = stop_info.GetStopReason();
+        if (reason == eStopReasonInvalid || reason == eStopReasonNone)
+            return false;
+        else
+            return true;
+    }
+    else
+        return false;
+}
+
+StateType
+Thread::GetState() const
+{
+    // If any other threads access this we will need a mutex for it
+    Mutex::Locker locker(m_state_mutex);
+    return m_state;
+}
+
+void
+Thread::SetState(StateType state)
+{
+    Mutex::Locker locker(m_state_mutex);
+    m_state = state;
+}
+
+void
+Thread::WillStop()
+{
+    ThreadPlan *current_plan = GetCurrentPlan();
+
+    // FIXME: I may decide to disallow threads with no plans.  In which
+    // case this should go to an assert.
+
+    if (!current_plan)
+        return;
+
+    current_plan->WillStop();
+}
+
+void
+Thread::SetupForResume ()
+{
+    if (GetResumeState() != eStateSuspended)
+    {
+    
+        // If we're at a breakpoint push the step-over breakpoint plan.  Do this before
+        // telling the current plan it will resume, since we might change what the current
+        // plan is.
+
+        lldb::addr_t pc = GetRegisterContext()->GetPC();
+        BreakpointSiteSP bp_site_sp = GetProcess().GetBreakpointSiteList().FindByAddress(pc);
+        if (bp_site_sp && bp_site_sp->IsEnabled())
+        {
+            // Note, don't assume there's a ThreadPlanStepOverBreakpoint, the target may not require anything
+            // special to step over a breakpoint.
+            
+            ThreadPlan *cur_plan = GetCurrentPlan();
+            ThreadPlanStepOverBreakpoint *step_over_bp = dynamic_cast<ThreadPlanStepOverBreakpoint *> (cur_plan);
+            if (step_over_bp == NULL)
+            {
+
+                ThreadPlanSP step_bp_plan_sp (new ThreadPlanStepOverBreakpoint (*this));
+                if (step_bp_plan_sp)
+                {
+                    if (GetCurrentPlan()->RunState() != eStateStepping)
+                    {
+                        ThreadPlanSP continue_plan_sp (new ThreadPlanContinue(*this, false, eVoteNo, eVoteNoOpinion));
+                        continue_plan_sp->SetPrivate (true);
+                        QueueThreadPlan (continue_plan_sp, false);
+                    }
+                    step_bp_plan_sp->SetPrivate (true);
+                    QueueThreadPlan (step_bp_plan_sp, false);
+                }
+            }
+        }
+    }
+}
+
+bool
+Thread::WillResume (StateType resume_state)
+{
+    // At this point clear the completed plan stack.
+    m_completed_plan_stack.clear();
+    m_discarded_plan_stack.clear();
+
+    // If this thread stopped with a signal, work out what its resume state should
+    // be.  Note if the thread resume state is already set, then don't override it,
+    // the user must have asked us to resume with some other signal.
+
+    if (GetResumeSignal() == LLDB_INVALID_SIGNAL_NUMBER)
+    {
+        Thread::StopInfo stop_info;
+        GetRawStopReason(&stop_info);
+
+        StopReason reason = stop_info.GetStopReason();
+        if (reason == eStopReasonSignal)
+        {
+            UnixSignals &signals = GetProcess().GetUnixSignals();
+            int32_t signo = stop_info.GetSignal();
+            if (!signals.GetShouldSuppress(signo))
+            {
+                SetResumeSignal(signo);
+            }
+        }
+    }
+    
+    // Tell all the plans that we are about to resume in case they need to clear any state.
+    // We distinguish between the plan on the top of the stack and the lower
+    // plans in case a plan needs to do any special business before it runs.
+    
+    ThreadPlan *plan_ptr = GetCurrentPlan();
+    plan_ptr->WillResume(resume_state, true);
+
+    while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL)
+    {
+        plan_ptr->WillResume (resume_state, false);
+    }
+    return true;
+}
+
+void
+Thread::DidResume ()
+{
+    SetResumeSignal (LLDB_INVALID_SIGNAL_NUMBER);
+}
+
+bool
+Thread::ShouldStop (Event* event_ptr)
+{
+    ThreadPlan *current_plan = GetCurrentPlan();
+    bool should_stop = true;
+
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
+    if (log)
+    {
+        StreamString s;
+        DumpThreadPlans(&s);
+        log->PutCString (s.GetData());
+    }
+
+    if (current_plan->PlanExplainsStop())
+    {
+        while (1)
+        {
+            should_stop = current_plan->ShouldStop(event_ptr);
+            if (current_plan->MischiefManaged())
+            {
+                if (should_stop)
+                    current_plan->WillStop();
+
+                // If a Master Plan wants to stop, and wants to stick on the stack, we let it.
+                // Otherwise, see if the plan's parent wants to stop.
+
+                if (should_stop && current_plan->IsMasterPlan() && !current_plan->OkayToDiscard())
+                {
+                    PopPlan();
+                    break;
+                }
+                else
+                {
+
+                    PopPlan();
+
+                    current_plan = GetCurrentPlan();
+                    if (current_plan == NULL)
+                    {
+                        break;
+                    }
+                }
+
+            }
+            else
+            {
+                break;
+            }
+        }
+    }
+    else
+    {
+        // If the current plan doesn't explain the stop, then, find one that
+        // does and let it handle the situation.
+        ThreadPlan *plan_ptr = current_plan;
+        while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL)
+        {
+            if (plan_ptr->PlanExplainsStop())
+            {
+                should_stop = plan_ptr->ShouldStop (event_ptr);
+                break;
+            }
+
+        }
+    }
+
+    return should_stop;
+}
+
+Vote
+Thread::ShouldReportStop (Event* event_ptr)
+{
+    StateType thread_state = GetResumeState ();
+    if (thread_state == eStateSuspended
+            || thread_state == eStateInvalid)
+        return eVoteNoOpinion;
+
+    if (m_completed_plan_stack.size() > 0)
+    {
+        // Don't use GetCompletedPlan here, since that suppresses private plans.
+        return m_completed_plan_stack.back()->ShouldReportStop (event_ptr);
+    }
+    else
+        return GetCurrentPlan()->ShouldReportStop (event_ptr);
+}
+
+Vote
+Thread::ShouldReportRun (Event* event_ptr)
+{
+    StateType thread_state = GetResumeState ();
+    if (thread_state == eStateSuspended
+            || thread_state == eStateInvalid)
+        return eVoteNoOpinion;
+
+    if (m_completed_plan_stack.size() > 0)
+    {
+        // Don't use GetCompletedPlan here, since that suppresses private plans.
+        return m_completed_plan_stack.back()->ShouldReportRun (event_ptr);
+    }
+    else
+        return GetCurrentPlan()->ShouldReportRun (event_ptr);
+}
+
+void
+Thread::PushPlan (ThreadPlanSP &thread_plan_sp)
+{
+    if (thread_plan_sp)
+    {
+        if (thread_plan_sp->IsImmediate())
+            m_immediate_plan_stack.push_back (thread_plan_sp);
+        else
+            m_plan_stack.push_back (thread_plan_sp);
+
+        thread_plan_sp->DidPush();
+
+        Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
+        if (log)
+        {
+            StreamString s;
+            thread_plan_sp->GetDescription (&s, lldb::eDescriptionLevelFull);
+            log->Printf("Pushing plan: \"%s\" for thread: %d immediate: %s.",
+                        s.GetData(),
+                        thread_plan_sp->GetThread().GetID(),
+                        thread_plan_sp->IsImmediate() ? "true" : "false");
+        }
+    }
+}
+
+void
+Thread::PopPlan ()
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
+
+    if (!m_immediate_plan_stack.empty())
+    {
+        ThreadPlanSP &plan = m_immediate_plan_stack.back();
+        if (log)
+        {
+            log->Printf("Popping plan: \"%s\" for thread: %d immediate: true.", plan->GetName(), plan->GetThread().GetID());
+        }
+        plan->WillPop();
+        m_immediate_plan_stack.pop_back();
+    }
+    else if (m_plan_stack.empty())
+        return;
+    else
+    {
+        ThreadPlanSP &plan = m_plan_stack.back();
+        if (log)
+        {
+            log->Printf("Popping plan: \"%s\" for thread: 0x%x immediate: false.", plan->GetName(), plan->GetThread().GetID());
+        }
+        m_completed_plan_stack.push_back (plan);
+        plan->WillPop();
+        m_plan_stack.pop_back();
+    }
+}
+
+void
+Thread::DiscardPlan ()
+{
+    if (m_plan_stack.size() > 1)
+    {
+        ThreadPlanSP &plan = m_plan_stack.back();
+        m_discarded_plan_stack.push_back (plan);
+        plan->WillPop();
+        m_plan_stack.pop_back();
+    }
+}
+
+ThreadPlan *
+Thread::GetCurrentPlan ()
+{
+    if (!m_immediate_plan_stack.empty())
+        return m_immediate_plan_stack.back().get();
+    else if (m_plan_stack.empty())
+        return NULL;
+    else
+        return m_plan_stack.back().get();
+}
+
+ThreadPlanSP
+Thread::GetCompletedPlan ()
+{
+    ThreadPlanSP empty_plan_sp;
+    if (!m_completed_plan_stack.empty())
+    {
+        for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--)
+        {
+            ThreadPlanSP completed_plan_sp;
+            completed_plan_sp = m_completed_plan_stack[i];
+            if (!completed_plan_sp->GetPrivate ())
+            return completed_plan_sp;
+        }
+    }
+    return empty_plan_sp;
+}
+
+bool
+Thread::IsThreadPlanDone (ThreadPlan *plan)
+{
+    ThreadPlanSP empty_plan_sp;
+    if (!m_completed_plan_stack.empty())
+    {
+        for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--)
+        {
+            if (m_completed_plan_stack[i].get() == plan)
+                return true;
+        }
+    }
+    return false;
+}
+
+bool
+Thread::WasThreadPlanDiscarded (ThreadPlan *plan)
+{
+    ThreadPlanSP empty_plan_sp;
+    if (!m_discarded_plan_stack.empty())
+    {
+        for (int i = m_discarded_plan_stack.size() - 1; i >= 0; i--)
+        {
+            if (m_discarded_plan_stack[i].get() == plan)
+                return true;
+        }
+    }
+    return false;
+}
+
+ThreadPlan *
+Thread::GetPreviousPlan (ThreadPlan *current_plan)
+{
+    if (current_plan == NULL)
+        return NULL;
+
+    int stack_size = m_completed_plan_stack.size();
+    for (int i = stack_size - 1; i > 0; i--)
+    {
+        if (current_plan == m_completed_plan_stack[i].get())
+            return m_completed_plan_stack[i-1].get();
+    }
+
+    if (stack_size > 0 && m_completed_plan_stack[0].get() == current_plan)
+    {
+        if (m_immediate_plan_stack.size() > 0)
+            return m_immediate_plan_stack.back().get();
+        else if (m_plan_stack.size() > 0)
+            return m_plan_stack.back().get();
+        else
+            return NULL;
+    }
+
+    stack_size = m_immediate_plan_stack.size();
+    for (int i = stack_size - 1; i > 0; i--)
+    {
+        if (current_plan == m_immediate_plan_stack[i].get())
+            return m_immediate_plan_stack[i-1].get();
+    }
+    if (stack_size > 0 && m_immediate_plan_stack[0].get() == current_plan)
+    {
+        if (m_plan_stack.size() > 0)
+            return m_plan_stack.back().get();
+        else
+            return NULL;
+    }
+
+    stack_size = m_plan_stack.size();
+    for (int i = stack_size - 1; i > 0; i--)
+    {
+        if (current_plan == m_plan_stack[i].get())
+            return m_plan_stack[i-1].get();
+    }
+    return NULL;
+}
+
+void
+Thread::QueueThreadPlan (ThreadPlanSP &thread_plan_sp, bool abort_other_plans)
+{
+    if (abort_other_plans)
+       DiscardThreadPlans(true);
+
+    PushPlan (thread_plan_sp);
+}
+
+void
+Thread::DiscardThreadPlans(bool force)
+{
+    // FIXME: It is not always safe to just discard plans.  Some, like the step over
+    // breakpoint trap can't be discarded in general (though you can if you plan to
+    // force a return from a function, for instance.
+    // For now I'm just not clearing immediate plans, but I need a way for plans to
+    // say they really need to be kept on, and then a way to override that.  Humm...
+
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
+    if (log)
+    {
+        log->Printf("Discarding thread plans for thread: 0x%x: force %d.", GetID(), force);
+    }
+
+    if (force)
+    {
+        int stack_size = m_plan_stack.size();
+        for (int i = stack_size - 1; i > 0; i--)
+        {
+            DiscardPlan();
+        }
+        return;
+    }
+
+    while (1)
+    {
+
+        int master_plan_idx;
+        bool discard;
+
+        // Find the first master plan, see if it wants discarding, and if yes discard up to it.
+        for (master_plan_idx = m_plan_stack.size() - 1; master_plan_idx >= 0; master_plan_idx--)
+        {
+            if (m_plan_stack[master_plan_idx]->IsMasterPlan())
+            {
+                discard = m_plan_stack[master_plan_idx]->OkayToDiscard();
+                break;
+            }
+        }
+
+        if (discard)
+        {
+            // First pop all the dependent plans:
+            for (int i = m_plan_stack.size() - 1; i > master_plan_idx; i--)
+            {
+
+                // FIXME: Do we need a finalize here, or is the rule that "PrepareForStop"
+                // for the plan leaves it in a state that it is safe to pop the plan
+                // with no more notice?
+                DiscardPlan();
+            }
+
+            // Now discard the master plan itself.
+            // The bottom-most plan never gets discarded.  "OkayToDiscard" for it means
+            // discard it's dependent plans, but not it...
+            if (master_plan_idx > 0)
+            {
+                DiscardPlan();
+            }
+        }
+        else
+        {
+            // If the master plan doesn't want to get discarded, then we're done.
+            break;
+        }
+
+    }
+    // FIXME: What should we do about the immediate plans?
+}
+
+ThreadPlan *
+Thread::QueueFundamentalPlan (bool abort_other_plans)
+{
+    ThreadPlanSP thread_plan_sp (new ThreadPlanBase(*this));
+    QueueThreadPlan (thread_plan_sp, abort_other_plans);
+    return thread_plan_sp.get();
+}
+
+ThreadPlan *
+Thread::QueueThreadPlanForStepSingleInstruction (bool step_over, bool abort_other_plans, bool stop_other_threads)
+{
+    ThreadPlanSP thread_plan_sp (new ThreadPlanStepInstruction (*this, step_over, stop_other_threads, eVoteNoOpinion, eVoteNoOpinion));
+    QueueThreadPlan (thread_plan_sp, abort_other_plans);
+    return thread_plan_sp.get();
+}
+
+ThreadPlan *
+Thread::QueueThreadPlanForStepRange (bool abort_other_plans, StepType type, const AddressRange &range, const SymbolContext &addr_context, lldb::RunMode stop_other_threads)
+{
+    ThreadPlanSP thread_plan_sp;
+    if (type == eStepTypeInto)
+        thread_plan_sp.reset (new ThreadPlanStepInRange (*this, range, addr_context, stop_other_threads));
+    else
+        thread_plan_sp.reset (new ThreadPlanStepOverRange (*this, range, addr_context, stop_other_threads));
+
+    QueueThreadPlan (thread_plan_sp, abort_other_plans);
+    return thread_plan_sp.get();
+}
+
+
+ThreadPlan *
+Thread::QueueThreadPlanForStepOverBreakpointPlan (bool abort_other_plans)
+{
+    ThreadPlanSP thread_plan_sp (new ThreadPlanStepOverBreakpoint (*this));
+    QueueThreadPlan (thread_plan_sp, abort_other_plans);
+    return thread_plan_sp.get();
+}
+
+ThreadPlan *
+Thread::QueueThreadPlanForStepOut (bool abort_other_plans, SymbolContext *addr_context, bool first_insn,
+        bool stop_other_threads, Vote stop_vote, Vote run_vote)
+{
+    ThreadPlanSP thread_plan_sp (new ThreadPlanStepOut (*this, addr_context, first_insn, stop_other_threads, stop_vote, run_vote));
+    QueueThreadPlan (thread_plan_sp, abort_other_plans);
+    return thread_plan_sp.get();
+}
+
+ThreadPlan *
+Thread::QueueThreadPlanForStepThrough (bool abort_other_plans, bool stop_other_threads)
+{
+    ThreadPlanSP thread_plan_sp(GetProcess().GetDynamicLoader()->GetStepThroughTrampolinePlan (*this, stop_other_threads));
+    if (thread_plan_sp.get() == NULL)
+    {
+        thread_plan_sp.reset(new ThreadPlanStepThrough (*this, stop_other_threads));
+        if (thread_plan_sp && !thread_plan_sp->ValidatePlan (NULL))
+            return false;
+    }
+    QueueThreadPlan (thread_plan_sp, abort_other_plans);
+    return thread_plan_sp.get();
+}
+
+ThreadPlan *
+Thread::QueueThreadPlanForContinue (bool abort_other_plans, bool stop_other_threads, Vote stop_vote, Vote run_vote, bool immediate)
+{
+    ThreadPlanSP thread_plan_sp (new ThreadPlanContinue (*this, stop_other_threads, stop_vote, run_vote, immediate));
+    QueueThreadPlan (thread_plan_sp, abort_other_plans);
+    return thread_plan_sp.get();
+}
+
+ThreadPlan *
+Thread::QueueThreadPlanForCallFunction (bool abort_other_plans,
+                                        Address& function,
+                                        lldb::addr_t arg,
+                                        bool stop_other_threads,
+                                        bool discard_on_error)
+{
+    ThreadPlanSP thread_plan_sp (new ThreadPlanCallFunction (*this, function, arg, stop_other_threads, discard_on_error));
+    QueueThreadPlan (thread_plan_sp, abort_other_plans);
+    return thread_plan_sp.get();
+}
+
+ThreadPlan *
+Thread::QueueThreadPlanForCallFunction (bool abort_other_plans,
+                                        Address& function,
+                                        ValueList &args,
+                                        bool stop_other_threads,
+                                        bool discard_on_error)
+{
+    ThreadPlanSP thread_plan_sp (new ThreadPlanCallFunction (*this, function, args, stop_other_threads, discard_on_error));
+    QueueThreadPlan (thread_plan_sp, abort_other_plans);
+    return thread_plan_sp.get();
+}
+
+ThreadPlan *
+Thread::QueueThreadPlanForRunToAddress (bool abort_other_plans,
+                                        Address &target_addr,
+                                        bool stop_other_threads)
+{
+    ThreadPlanSP thread_plan_sp (new ThreadPlanRunToAddress (*this, target_addr, stop_other_threads));
+    QueueThreadPlan (thread_plan_sp, abort_other_plans);
+    return thread_plan_sp.get();
+}
+
+ThreadPlan *
+Thread::QueueThreadPlanForStepUntil (bool abort_other_plans,
+                                       lldb::addr_t *address_list,
+                                       size_t num_addresses,
+                                       bool stop_other_threads)
+{
+    ThreadPlanSP thread_plan_sp (new ThreadPlanStepUntil (*this, address_list, num_addresses, stop_other_threads));
+    QueueThreadPlan (thread_plan_sp, abort_other_plans);
+    return thread_plan_sp.get();
+
+}
+
+uint32_t
+Thread::GetIndexID () const
+{
+    return m_index_id;
+}
+
+void
+Thread::DumpThreadPlans (lldb_private::Stream *s) const
+{
+    uint32_t stack_size = m_plan_stack.size();
+    s->Printf ("Plan Stack: %d elements.\n", stack_size);
+    for (int i = stack_size - 1; i > 0; i--)
+    {
+        s->Printf ("Element %d: ", i);
+        s->IndentMore();
+        m_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
+        s->IndentLess();
+        s->EOL();
+    }
+
+    stack_size = m_immediate_plan_stack.size();
+    s->Printf ("Immediate Plan Stack: %d elements.\n", stack_size);
+    for (int i = stack_size - 1; i > 0; i--)
+    {
+        s->Printf ("Element %d: ", i);
+        s->IndentMore();
+        m_immediate_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
+        s->IndentLess();
+        s->EOL();
+    }
+
+    stack_size = m_completed_plan_stack.size();
+    s->Printf ("Completed Plan Stack: %d elements.\n", stack_size);
+    for (int i = stack_size - 1; i > 0; i--)
+    {
+        s->Printf ("Element %d: ", i);
+        s->IndentMore();
+        m_completed_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
+        s->IndentLess();
+        s->EOL();
+    }
+
+    stack_size = m_discarded_plan_stack.size();
+    s->Printf ("Discarded Plan Stack: %d elements.\n", stack_size);
+    for (int i = stack_size - 1; i > 0; i--)
+    {
+        s->Printf ("Element %d: ", i);
+        s->IndentMore();
+        m_discarded_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
+        s->IndentLess();
+        s->EOL();
+    }
+
+}
+
+Target *
+Thread::CalculateTarget ()
+{
+    return m_process.CalculateTarget();
+}
+
+Process *
+Thread::CalculateProcess ()
+{
+    return &m_process;
+}
+
+Thread *
+Thread::CalculateThread ()
+{
+    return this;
+}
+
+StackFrame *
+Thread::CalculateStackFrame ()
+{
+    return NULL;
+}
+
+void
+Thread::Calculate (ExecutionContext &exe_ctx)
+{
+    m_process.Calculate (exe_ctx);
+    exe_ctx.thread = this;
+    exe_ctx.frame = NULL;
+}
+
+lldb::StackFrameSP
+Thread::GetCurrentFrame ()
+{
+    return GetStackFrameAtIndex (m_frames.GetCurrentFrameIndex());
+}
+
+uint32_t
+Thread::SetCurrentFrame (lldb_private::StackFrame *frame)
+{
+    return m_frames.SetCurrentFrame(frame);
+}
+
+void
+Thread::SetCurrentFrameByIndex (uint32_t frame_idx)
+{
+    m_frames.SetCurrentFrameByIndex(frame_idx);
+}
+
+void
+Thread::DumpInfo
+(
+    Stream &strm,
+    bool show_stop_reason,
+    bool show_name,
+    bool show_queue,
+    uint32_t frame_idx
+)
+{
+    strm.Printf("thread #%u: tid = 0x%4.4x", GetIndexID(), GetID());
+
+    if (frame_idx != LLDB_INVALID_INDEX32)
+    {
+        StackFrameSP frame_sp(GetStackFrameAtIndex (frame_idx));
+        if (frame_sp)
+        {
+            strm.PutCString(", ");
+            frame_sp->Dump (&strm, false);
+        }
+    }
+
+    if (show_stop_reason)
+    {
+        Thread::StopInfo thread_stop_info;
+        if (GetStopInfo(&thread_stop_info))
+        {
+            if (thread_stop_info.GetStopReason() != eStopReasonNone)
+            {
+                strm.PutCString(", stop reason = ");
+                thread_stop_info.Dump(&strm);
+            }
+        }
+    }
+
+    if (show_name)
+    {
+        const char *name = GetName();
+        if (name && name[0])
+            strm.Printf(", name = %s", name);
+    }
+
+    if (show_queue)
+    {
+        const char *queue = GetQueueName();
+        if (queue && queue[0])
+            strm.Printf(", queue = %s", queue);
+    }
+}
+
+lldb::ThreadSP
+Thread::GetSP ()
+{
+    return m_process.GetThreadList().GetThreadSPForThreadPtr(this);
+}
diff --git a/source/Target/ThreadList.cpp b/source/Target/ThreadList.cpp
new file mode 100644
index 0000000..6bc2271
--- /dev/null
+++ b/source/Target/ThreadList.cpp
@@ -0,0 +1,460 @@
+//===-- ThreadList.cpp ------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdlib.h>
+
+#include <algorithm>
+
+#include "lldb/Target/ThreadList.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+#include "lldb/Target/Process.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+ThreadList::ThreadList (Process *process) :
+    m_process (process),
+    m_stop_id (0),
+    m_threads(),
+    m_threads_mutex (Mutex::eMutexTypeRecursive),
+    m_current_tid (LLDB_INVALID_THREAD_ID)
+{
+}
+
+ThreadList::ThreadList (const ThreadList &rhs) :
+    m_process (),
+    m_stop_id (),
+    m_threads (),
+    m_threads_mutex (Mutex::eMutexTypeRecursive),
+    m_current_tid ()
+{
+    // Use the assignment operator since it uses the mutex
+    *this = rhs;
+}
+
+const ThreadList&
+ThreadList::operator = (const ThreadList& rhs)
+{
+    if (this != &rhs)
+    {
+        // Lock both mutexes to make sure neither side changes anyone on us
+        // while the assignement occurs
+        Mutex::Locker locker_this(m_threads_mutex);
+        Mutex::Locker locker_rhs(rhs.m_threads_mutex);
+        m_process = rhs.m_process;
+        m_stop_id = rhs.m_stop_id;
+        m_threads = rhs.m_threads;
+        m_current_tid = rhs.m_current_tid;
+    }
+    return *this;
+}
+
+
+ThreadList::~ThreadList()
+{
+}
+
+
+uint32_t
+ThreadList::GetStopID () const
+{
+    return m_stop_id;
+}
+
+void
+ThreadList::SetStopID (uint32_t stop_id)
+{
+    m_stop_id = stop_id;
+}
+
+
+void
+ThreadList::AddThread (ThreadSP &thread_sp)
+{
+    Mutex::Locker locker(m_threads_mutex);
+    m_threads.push_back(thread_sp);
+}
+
+uint32_t
+ThreadList::GetSize (bool can_update)
+{
+    Mutex::Locker locker(m_threads_mutex);
+    if (can_update)
+        m_process->UpdateThreadListIfNeeded();
+    return m_threads.size();
+}
+
+ThreadSP
+ThreadList::GetThreadAtIndex (uint32_t idx, bool can_update)
+{
+    Mutex::Locker locker(m_threads_mutex);
+    if (can_update)
+        m_process->UpdateThreadListIfNeeded();
+
+    ThreadSP thread_sp;
+    if (idx < m_threads.size())
+        thread_sp = m_threads[idx];
+    return thread_sp;
+}
+
+ThreadSP
+ThreadList::FindThreadByID (lldb::tid_t tid, bool can_update)
+{
+    Mutex::Locker locker(m_threads_mutex);
+
+    if (can_update)
+        m_process->UpdateThreadListIfNeeded();
+
+    ThreadSP thread_sp;
+    uint32_t idx = 0;
+    const uint32_t num_threads = m_threads.size();
+    for (idx = 0; idx < num_threads; ++idx)
+    {
+        if (m_threads[idx]->GetID() == tid)
+        {
+            thread_sp = m_threads[idx];
+            break;
+        }
+    }
+    return thread_sp;
+}
+
+ThreadSP
+ThreadList::GetThreadSPForThreadPtr (Thread *thread_ptr)
+{
+    ThreadSP thread_sp;
+    if (thread_ptr)
+    {
+        Mutex::Locker locker(m_threads_mutex);
+
+        uint32_t idx = 0;
+        const uint32_t num_threads = m_threads.size();
+        for (idx = 0; idx < num_threads; ++idx)
+        {
+            if (m_threads[idx].get() == thread_ptr)
+            {
+                thread_sp = m_threads[idx];
+                break;
+            }
+        }
+    }
+    return thread_sp;
+}
+
+
+
+ThreadSP
+ThreadList::FindThreadByIndexID (uint32_t index_id, bool can_update)
+{
+    Mutex::Locker locker(m_threads_mutex);
+
+    if (can_update)
+        m_process->UpdateThreadListIfNeeded();
+
+    ThreadSP thread_sp;
+    const uint32_t num_threads = m_threads.size();
+    for (uint32_t idx = 0; idx < num_threads; ++idx)
+    {
+        if (m_threads[idx]->GetIndexID() == index_id)
+        {
+            thread_sp = m_threads[idx];
+            break;
+        }
+    }
+    return thread_sp;
+}
+
+bool
+ThreadList::ShouldStop (Event *event_ptr)
+{
+    Mutex::Locker locker(m_threads_mutex);
+
+    // Running events should never stop, obviously...
+
+
+    bool should_stop = false;
+    m_process->UpdateThreadListIfNeeded();
+
+    collection::iterator pos, end = m_threads.end();
+
+    // Run through the threads and ask whether we should stop.  Don't ask
+    // suspended threads, however, it makes more sense for them to preserve their
+    // state across the times the process runs but they don't get a chance to.
+    for (pos = m_threads.begin(); pos != end; ++pos)
+    {
+        ThreadSP thread_sp(*pos);
+        if ((thread_sp->ThreadStoppedForAReason())
+            && (thread_sp->GetResumeState () != eStateSuspended))
+        {
+            should_stop |= thread_sp->ShouldStop(event_ptr);
+        }
+    }
+    if (should_stop)
+    {
+        for (pos = m_threads.begin(); pos != end; ++pos)
+        {
+            ThreadSP thread_sp(*pos);
+            thread_sp->WillStop ();
+        }
+    }
+
+    return should_stop;
+}
+
+Vote
+ThreadList::ShouldReportStop (Event *event_ptr)
+{
+    Vote result = eVoteNoOpinion;
+    m_process->UpdateThreadListIfNeeded();
+    collection::iterator pos, end = m_threads.end();
+
+    // Run through the threads and ask whether we should report this event.
+    // For stopping, a YES vote wins over everything.  A NO vote wins over NO opinion.
+    for (pos = m_threads.begin(); pos != end; ++pos)
+    {
+        ThreadSP thread_sp(*pos);
+        if (thread_sp->ThreadStoppedForAReason() && (thread_sp->GetResumeState () != eStateSuspended))
+        {
+            switch (thread_sp->ShouldReportStop (event_ptr))
+            {
+                case eVoteNoOpinion:
+                    continue;
+                case eVoteYes:
+                    result = eVoteYes;
+                    break;
+                case eVoteNo:
+                    if (result == eVoteNoOpinion)
+                        result = eVoteNo;
+                    break;
+            }
+        }
+    }
+    return result;
+}
+
+Vote
+ThreadList::ShouldReportRun (Event *event_ptr)
+{
+    Vote result = eVoteNoOpinion;
+    m_process->UpdateThreadListIfNeeded();
+    collection::iterator pos, end = m_threads.end();
+
+    // Run through the threads and ask whether we should report this event.
+    // The rule is NO vote wins over everything, a YES vote wins over no opinion.
+
+    for (pos = m_threads.begin(); pos != end; ++pos)
+    {
+        ThreadSP thread_sp(*pos);
+        if (thread_sp->GetResumeState () != eStateSuspended)
+
+        switch (thread_sp->ShouldReportRun (event_ptr))
+        {
+            case eVoteNoOpinion:
+                continue;
+            case eVoteYes:
+                if (result == eVoteNoOpinion)
+                    result = eVoteYes;
+                break;
+            case eVoteNo:
+                result = eVoteNo;
+                break;
+        }
+    }
+    return result;
+}
+
+void
+ThreadList::Clear()
+{
+    m_stop_id = 0;
+    m_threads.clear();
+    m_current_tid = LLDB_INVALID_THREAD_ID;
+}
+
+void
+ThreadList::RefreshStateAfterStop ()
+{
+    Mutex::Locker locker(m_threads_mutex);
+
+    m_process->UpdateThreadListIfNeeded();
+
+    collection::iterator pos, end = m_threads.end();
+    for (pos = m_threads.begin(); pos != end; ++pos)
+        (*pos)->RefreshStateAfterStop ();
+}
+
+void
+ThreadList::DiscardThreadPlans ()
+{
+    // You don't need to update the thread list here, because only threads
+    // that you currently know about have any thread plans.
+    Mutex::Locker locker(m_threads_mutex);
+
+    collection::iterator pos, end = m_threads.end();
+    for (pos = m_threads.begin(); pos != end; ++pos)
+        (*pos)->DiscardThreadPlans (true);
+
+}
+
+bool
+ThreadList::WillResume ()
+{
+    // Run through the threads and perform their momentary actions.
+    // But we only do this for threads that are running, user suspended
+    // threads stay where they are.
+    bool success = true;
+
+    Mutex::Locker locker(m_threads_mutex);
+    m_process->UpdateThreadListIfNeeded();
+
+    collection::iterator pos, end = m_threads.end();
+    
+    // Give all the threads a last chance to set up their state before we
+    // negotiate who is actually going to get a chance to run...
+
+    for (pos = m_threads.begin(); pos != end; ++pos)
+        (*pos)->SetupForResume ();
+    
+    // Now go through the threads and see if any thread wants to run just itself.
+    // if so then pick one and run it.
+    ThreadList run_me_only_list (m_process);
+    
+    run_me_only_list.SetStopID(m_process->GetStopID());
+
+    ThreadSP immediate_thread_sp;
+    bool run_only_current_thread = false;
+
+    for (pos = m_threads.begin(); pos != end; ++pos)
+    {
+        ThreadSP thread_sp(*pos);
+        if (thread_sp->GetCurrentPlan()->IsImmediate())
+        {
+            // We first do all the immediate plans, so if we find one, set
+            // immediate_thread_sp and break out, and we'll pick it up first thing
+            // when we're negotiating which threads get to run.
+            immediate_thread_sp = thread_sp;
+            break;
+        }
+        else if (thread_sp->GetResumeState() != eStateSuspended &&
+                 thread_sp->GetCurrentPlan()->StopOthers())
+        {
+            // You can't say "stop others" and also want yourself to be suspended.
+            assert (thread_sp->GetCurrentPlan()->RunState() != eStateSuspended);
+
+            if (thread_sp == GetCurrentThread())
+            {
+                run_only_current_thread = true;
+                run_me_only_list.Clear();
+                run_me_only_list.AddThread (thread_sp);
+                break;
+            }
+
+            run_me_only_list.AddThread (thread_sp);
+        }
+
+    }
+
+    if (immediate_thread_sp)
+    {
+        for (pos = m_threads.begin(); pos != end; ++pos)
+        {
+            ThreadSP thread_sp(*pos);
+            if (thread_sp.get() == immediate_thread_sp.get())
+                thread_sp->WillResume(thread_sp->GetCurrentPlan()->RunState());
+            else
+                thread_sp->WillResume (eStateSuspended);
+        }
+    }
+    else if (run_me_only_list.GetSize (false) == 0)
+    {
+        // Everybody runs as they wish:
+        for (pos = m_threads.begin(); pos != end; ++pos)
+        {
+            ThreadSP thread_sp(*pos);
+            thread_sp->WillResume(thread_sp->GetCurrentPlan()->RunState());
+        }
+    }
+    else
+    {
+        ThreadSP thread_to_run;
+
+        if (run_only_current_thread)
+        {
+            thread_to_run = GetCurrentThread();
+        }
+        else if (run_me_only_list.GetSize (false) == 1)
+        {
+            thread_to_run = run_me_only_list.GetThreadAtIndex (0);
+        }
+        else
+        {
+            int random_thread = (int)
+                    ((run_me_only_list.GetSize (false) * (double) rand ()) / (RAND_MAX + 1.0));
+            thread_to_run = run_me_only_list.GetThreadAtIndex (random_thread);
+        }
+
+        for (pos = m_threads.begin(); pos != end; ++pos)
+        {
+            ThreadSP thread_sp(*pos);
+            if (thread_sp == thread_to_run)
+                thread_sp->WillResume(thread_sp->GetCurrentPlan()->RunState());
+            else
+                thread_sp->WillResume (eStateSuspended);
+        }
+    }
+
+    return success;
+}
+
+void
+ThreadList::DidResume ()
+{
+    collection::iterator pos, end = m_threads.end();
+    for (pos = m_threads.begin(); pos != end; ++pos)
+    {
+        // Don't clear out threads that aren't going to get a chance to run, rather
+        // leave their state for the next time around.
+        ThreadSP thread_sp(*pos);
+        if (thread_sp->GetResumeState() != eStateSuspended)
+            thread_sp->DidResume ();
+    }
+}
+
+ThreadSP
+ThreadList::GetCurrentThread ()
+{
+    Mutex::Locker locker(m_threads_mutex);
+    return FindThreadByID(m_current_tid);
+}
+
+bool
+ThreadList::SetCurrentThreadByID (lldb::tid_t tid)
+{
+    Mutex::Locker locker(m_threads_mutex);
+    if  (FindThreadByID(tid).get())
+        m_current_tid = tid;
+    else
+        m_current_tid = LLDB_INVALID_THREAD_ID;
+
+    return m_current_tid != LLDB_INVALID_THREAD_ID;
+}
+
+bool
+ThreadList::SetCurrentThreadByIndexID (uint32_t index_id)
+{
+    Mutex::Locker locker(m_threads_mutex);
+    ThreadSP thread_sp (FindThreadByIndexID(index_id));
+    if  (thread_sp.get())
+        m_current_tid = thread_sp->GetID();
+    else
+        m_current_tid = LLDB_INVALID_THREAD_ID;
+
+    return m_current_tid != LLDB_INVALID_THREAD_ID;
+}
+
diff --git a/source/Target/ThreadPlan.cpp b/source/Target/ThreadPlan.cpp
new file mode 100644
index 0000000..c9005c1
--- /dev/null
+++ b/source/Target/ThreadPlan.cpp
@@ -0,0 +1,185 @@
+//===-- ThreadPlan.cpp ------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/ThreadPlan.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Target/Thread.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/State.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// ThreadPlan constructor
+//----------------------------------------------------------------------
+ThreadPlan::ThreadPlan(const char *name, Thread &thread, Vote stop_vote, Vote run_vote) :
+    m_name (name),
+    m_thread (thread),
+    m_plan_complete(false),
+    m_plan_complete_mutex (Mutex::eMutexTypeRecursive),
+    m_plan_private (false),
+    m_stop_vote (stop_vote),
+    m_run_vote (run_vote),
+    m_okay_to_discard (false)
+{
+    SetID (GetNextID());
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+ThreadPlan::~ThreadPlan()
+{
+}
+
+const char *
+ThreadPlan::GetName () const
+{
+    return m_name.c_str();
+}
+
+Thread &
+ThreadPlan::GetThread()
+{
+    return m_thread;
+}
+
+
+const Thread &
+ThreadPlan::GetThread() const
+{
+    return m_thread;
+}
+
+bool
+ThreadPlan::IsPlanComplete ()
+{
+    Mutex::Locker (m_plan_complete_mutex);
+    return m_plan_complete;
+}
+
+void
+ThreadPlan::SetPlanComplete ()
+{
+    Mutex::Locker (m_plan_complete_mutex);
+    m_plan_complete = true;
+}
+
+bool
+ThreadPlan::MischiefManaged ()
+{
+    Mutex::Locker (m_plan_complete_mutex);
+    m_plan_complete = true;
+    return true;
+}
+
+Vote
+ThreadPlan::ShouldReportStop (Event *event_ptr)
+{
+    if (m_stop_vote == eVoteNoOpinion)
+    {
+        ThreadPlan *prev_plan = GetPreviousPlan ();
+        if (prev_plan)
+            return prev_plan->ShouldReportStop (event_ptr);
+    }
+    return m_stop_vote;
+}
+
+Vote
+ThreadPlan::ShouldReportRun (Event *event_ptr)
+{
+    if (m_run_vote == eVoteNoOpinion)
+    {
+        ThreadPlan *prev_plan = GetPreviousPlan ();
+        if (prev_plan)
+            return prev_plan->ShouldReportRun (event_ptr);
+    }
+    return m_run_vote;
+}
+
+bool
+ThreadPlan::StopOthers ()
+{
+    ThreadPlan *prev_plan;
+    prev_plan = GetPreviousPlan ();
+    if (prev_plan == NULL)
+        return false;
+    else
+        return prev_plan->StopOthers();
+}
+
+bool
+ThreadPlan::WillResume (StateType resume_state, bool current_plan)
+{
+    if (current_plan)
+    {
+        Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
+
+        if (log)
+            log->Printf("About to resume the \"%s\" plan - state: %s - stop others: %d.", 
+                        m_name.c_str(), StateAsCString(resume_state), StopOthers());
+    }
+    return true;
+}
+
+lldb::user_id_t
+ThreadPlan::GetNextID()
+{
+    static uint32_t g_nextPlanID = 0;
+    return ++g_nextPlanID;
+}
+
+void
+ThreadPlan::DidPush()
+{
+}
+
+void
+ThreadPlan::WillPop()
+{
+}
+
+void
+ThreadPlan::PushPlan (ThreadPlanSP &thread_plan_sp)
+{
+    m_thread.PushPlan (thread_plan_sp);
+}
+
+ThreadPlan *
+ThreadPlan::GetPreviousPlan ()
+{
+    return m_thread.GetPreviousPlan (this);
+}
+
+void
+ThreadPlan::SetPrivate (bool input)
+{
+    m_plan_private = input;
+}
+
+bool
+ThreadPlan::GetPrivate (void)
+{
+    return m_plan_private;
+}
+
+bool
+ThreadPlan::OkayToDiscard()
+{
+    if (!IsMasterPlan())
+        return true;
+    else
+        return m_okay_to_discard;
+}
+
diff --git a/source/Target/ThreadPlanBase.cpp b/source/Target/ThreadPlanBase.cpp
new file mode 100644
index 0000000..283f3be
--- /dev/null
+++ b/source/Target/ThreadPlanBase.cpp
@@ -0,0 +1,202 @@
+//===-- ThreadPlanBase.cpp --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/ThreadPlanBase.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+//
+#include "lldb/Breakpoint/StoppointCallbackContext.h"
+#include "lldb/Breakpoint/BreakpointSite.h"
+#include "lldb/Breakpoint/BreakpointLocation.h"
+#include "lldb/Breakpoint/Breakpoint.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/ThreadPlanContinue.h"
+#include "lldb/Target/ThreadPlanStepOverBreakpoint.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// ThreadPlanBase: This one always stops, and never has anything particular
+// to do.
+// FIXME: The "signal handling" policies should probably go here.
+//----------------------------------------------------------------------
+
+ThreadPlanBase::ThreadPlanBase (Thread &thread) :
+    ThreadPlan("base plan", thread, eVoteYes, eVoteNoOpinion)
+{
+
+}
+
+ThreadPlanBase::~ThreadPlanBase ()
+{
+
+}
+
+void
+ThreadPlanBase::GetDescription (Stream *s, lldb::DescriptionLevel level)
+{
+    s->Printf ("Base thread plan.");
+}
+
+bool
+ThreadPlanBase::ValidatePlan (Stream *error)
+{
+    return true;
+}
+
+bool
+ThreadPlanBase::PlanExplainsStop ()
+{
+    return true;
+}
+
+bool
+ThreadPlanBase::ShouldStop (Event *event_ptr)
+{
+    m_stop_vote = eVoteYes;
+    m_run_vote = eVoteYes;
+
+    Thread::StopInfo stop_info;
+    if (m_thread.GetStopInfo(&stop_info))
+    {
+        StopReason reason = stop_info.GetStopReason();
+        switch (reason)
+        {
+            case eStopReasonInvalid:
+            case eStopReasonNone:
+            {
+                m_run_vote = eVoteNo;
+                m_stop_vote = eVoteNo;
+                return false;
+            }
+            case eStopReasonBreakpoint:
+            {
+                // The base plan checks for breakpoint hits.
+
+                BreakpointSiteSP bp_site_sp;
+                //RegisterContext *reg_ctx = m_thread.GetRegisterContext();
+                //lldb::addr_t pc = reg_ctx->GetPC();
+                bp_site_sp = m_thread.GetProcess().GetBreakpointSiteList().FindByID (stop_info.GetBreakpointSiteID());
+
+                if (bp_site_sp && bp_site_sp->IsEnabled())
+                {
+                    // We want to step over the breakpoint and then continue.  So push these two plans.
+
+                    StoppointCallbackContext hit_context(event_ptr, &m_thread.GetProcess(), &m_thread, m_thread.GetStackFrameAtIndex(0).get());
+                    bool should_stop = m_thread.GetProcess().GetBreakpointSiteList().ShouldStop(&hit_context, bp_site_sp->GetID());
+
+                    if (!should_stop)
+                    {
+                        // If we aren't going to stop at this breakpoint, and it is internal, don't report this stop or the subsequent
+                        // running event.  Otherwise we will post the stopped & running, but the stopped event will get marked
+                        // with "restarted" so the UI will know to wait and expect the consequent "running".
+                        uint32_t i;
+                        bool is_wholly_internal = true;
+
+                        for (i = 0; i < bp_site_sp->GetNumberOfOwners(); i++)
+                        {
+                            if (!bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint().IsInternal())
+                            {
+                                is_wholly_internal = false;
+                                break;
+                            }
+                        }
+                        if (is_wholly_internal)
+                        {
+                            m_stop_vote = eVoteNo;
+                            m_run_vote = eVoteNo;
+                        }
+                        else
+                        {
+                            m_stop_vote = eVoteYes;
+                            m_run_vote = eVoteYes;
+                        }
+
+                    }
+                    else
+                    {
+                        // If we are going to stop for a breakpoint, then unship the other plans
+                        // at this point.  Don't force the discard, however, so Master plans can stay
+                        // in place if they want to.
+                        m_thread.DiscardThreadPlans(false);
+                    }
+
+                    return should_stop;
+                }
+            }
+            case eStopReasonException:
+                // If we crashed, discard thread plans and stop.  Don't force the discard, however,
+                // since on rerun the target may clean up this exception and continue normally from there.
+                m_thread.DiscardThreadPlans(false);
+                return true;
+            case eStopReasonSignal:
+            {
+                // Check the signal handling, and if we are stopping for the signal,
+                // discard the plans and stop.
+                UnixSignals &signals = m_thread.GetProcess().GetUnixSignals();
+                uint32_t signo = stop_info.GetSignal();
+                if (signals.GetShouldStop(signo))
+                {
+                    m_thread.DiscardThreadPlans(false);
+                    return true;
+                }
+                else
+                {
+                    // We're not going to stop, but while we are here, let's figure out
+                    // whether to report this.
+                    if (signals.GetShouldNotify(signo))
+                        m_stop_vote = eVoteYes;
+                    else
+                        m_stop_vote = eVoteNo;
+
+                    return false;
+                }
+            }
+            default:
+                return true;
+        }
+
+    }
+
+    // If there's no explicit reason to stop, then we will continue.
+    return false;
+}
+
+bool
+ThreadPlanBase::StopOthers ()
+{
+    return false;
+}
+
+StateType
+ThreadPlanBase::RunState ()
+{
+    return eStateRunning;
+}
+
+bool
+ThreadPlanBase::WillStop ()
+{
+    return true;
+}
+
+// The base plan is never done.
+bool
+ThreadPlanBase::MischiefManaged ()
+{
+    // The base plan is never done.
+    return false;
+}
+
diff --git a/source/Target/ThreadPlanCallFunction.cpp b/source/Target/ThreadPlanCallFunction.cpp
new file mode 100644
index 0000000..4b3533a
--- /dev/null
+++ b/source/Target/ThreadPlanCallFunction.cpp
@@ -0,0 +1,250 @@
+//===-- ThreadPlanCallFunction.cpp ------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/ThreadPlanCallFunction.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private-log.h"
+#include "lldb/Core/Address.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlanRunToAddress.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// ThreadPlanCallFunction: Plan to call a single function
+//----------------------------------------------------------------------
+
+ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
+                                                Address &function,
+                                                lldb::addr_t arg,
+                                                bool stop_other_threads,
+                                                bool discard_on_error) :
+    ThreadPlan ("Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion),
+    m_valid(false),
+    m_process(thread.GetProcess()),
+    m_arg_addr (arg),
+    m_args (NULL),
+    m_thread(thread),
+    m_stop_other_threads(stop_other_threads)
+{
+
+    SetOkayToDiscard (discard_on_error);
+
+    Process& process = thread.GetProcess();
+    Target& target = process.GetTarget();
+    const ABI *abi = process.GetABI();
+
+    if (!abi)
+        return;
+
+    lldb::addr_t spBelowRedZone = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize();
+    
+    SymbolContextList contexts;
+    SymbolContext context;
+    ModuleSP executableModuleSP (target.GetExecutableModule());
+
+    if (!executableModuleSP ||
+        !executableModuleSP->FindSymbolsWithNameAndType(ConstString ("start"), eSymbolTypeCode, contexts))
+        return;
+    
+    contexts.GetContextAtIndex(0, context);
+    
+    m_start_addr = context.symbol->GetValue();
+    lldb::addr_t StartLoadAddr = m_start_addr.GetLoadAddress(&process);
+
+    if (!thread.SaveFrameZeroState(m_register_backup))
+        return;
+
+    m_function_addr = function;
+    lldb::addr_t FunctionLoadAddr = m_function_addr.GetLoadAddress(&process);
+        
+    if (!abi->PrepareTrivialCall(thread, 
+                                 spBelowRedZone, 
+                                 FunctionLoadAddr, 
+                                 StartLoadAddr, 
+                                 m_arg_addr))
+        return;
+    
+    m_valid = true;    
+}
+
+ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
+                                                Address &function,
+                                                ValueList &args,
+                                                bool stop_other_threads,
+                                                bool discard_on_error) :
+    ThreadPlan ("Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion),
+    m_valid(false),
+    m_process(thread.GetProcess()),
+    m_arg_addr (0),
+    m_args (&args),
+    m_thread(thread),
+    m_stop_other_threads(stop_other_threads)
+{
+    
+    SetOkayToDiscard (discard_on_error);
+    
+    Process& process = thread.GetProcess();
+    Target& target = process.GetTarget();
+    const ABI *abi = process.GetABI();
+    
+    if(!abi)
+        return;
+    
+    lldb::addr_t spBelowRedZone = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize();
+    
+    SymbolContextList contexts;
+    SymbolContext context;
+    ModuleSP executableModuleSP (target.GetExecutableModule());
+    
+    if (!executableModuleSP ||
+        !executableModuleSP->FindSymbolsWithNameAndType(ConstString ("start"), eSymbolTypeCode, contexts))
+        return;
+    
+    contexts.GetContextAtIndex(0, context);
+    
+    m_start_addr = context.symbol->GetValue();
+    lldb::addr_t StartLoadAddr = m_start_addr.GetLoadAddress(&process);
+    
+    if(!thread.SaveFrameZeroState(m_register_backup))
+        return;
+    
+    m_function_addr = function;
+    lldb::addr_t FunctionLoadAddr = m_function_addr.GetLoadAddress(&process);
+    
+    if (!abi->PrepareNormalCall(thread, 
+                                spBelowRedZone, 
+                                FunctionLoadAddr, 
+                                StartLoadAddr, 
+                                *m_args))
+        return;
+    
+    m_valid = true;    
+}
+
+ThreadPlanCallFunction::~ThreadPlanCallFunction ()
+{
+}
+
+void
+ThreadPlanCallFunction::GetDescription (Stream *s, lldb::DescriptionLevel level)
+{
+    if (level == lldb::eDescriptionLevelBrief)
+    {
+        s->Printf("Function call thread plan");
+    }
+    else
+    {
+        if (m_args)
+            s->Printf("Thread plan to call 0x%llx with parsed arguments", m_function_addr.GetLoadAddress(&m_process), m_arg_addr);
+        else
+            s->Printf("Thread plan to call 0x%llx void * argument at: 0x%llx", m_function_addr.GetLoadAddress(&m_process), m_arg_addr);
+    }
+}
+
+bool
+ThreadPlanCallFunction::ValidatePlan (Stream *error)
+{
+    if (!m_valid)
+        return false;
+
+    return true;
+}
+
+bool
+ThreadPlanCallFunction::PlanExplainsStop ()
+{
+    if (!m_subplan_sp)
+        return false;
+    else
+        return m_subplan_sp->PlanExplainsStop();
+}
+
+bool
+ThreadPlanCallFunction::ShouldStop (Event *event_ptr)
+{
+    if (PlanExplainsStop())
+    {
+        m_thread.RestoreSaveFrameZero(m_register_backup);
+        m_thread.ClearStackFrames();
+        SetPlanComplete();
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+bool
+ThreadPlanCallFunction::StopOthers ()
+{
+    return m_stop_other_threads;
+}
+
+void
+ThreadPlanCallFunction::SetStopOthers (bool new_value)
+{
+    if (m_subplan_sp)
+    {
+        ThreadPlanRunToAddress *address_plan = static_cast<ThreadPlanRunToAddress *>(m_subplan_sp.get());
+        address_plan->SetStopOthers(new_value);
+    }
+    m_stop_other_threads = new_value;
+}
+
+StateType
+ThreadPlanCallFunction::RunState ()
+{
+    return eStateRunning;
+}
+
+void
+ThreadPlanCallFunction::DidPush ()
+{
+    m_subplan_sp.reset(new ThreadPlanRunToAddress(m_thread, m_start_addr, m_stop_other_threads));
+    
+    m_thread.QueueThreadPlan(m_subplan_sp, false);
+
+}
+
+bool
+ThreadPlanCallFunction::WillStop ()
+{
+    return true;
+}
+
+bool
+ThreadPlanCallFunction::MischiefManaged ()
+{
+    if (IsPlanComplete())
+    {
+        Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
+
+        if (log)
+            log->Printf("Completed call function plan.");
+
+        ThreadPlan::MischiefManaged ();
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
diff --git a/source/Target/ThreadPlanContinue.cpp b/source/Target/ThreadPlanContinue.cpp
new file mode 100644
index 0000000..63d8a33
--- /dev/null
+++ b/source/Target/ThreadPlanContinue.cpp
@@ -0,0 +1,120 @@
+//===-- ThreadPlanContinue.cpp ----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/ThreadPlanContinue.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private-log.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Stream.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// ThreadPlanContinue: Continue plan
+//----------------------------------------------------------------------
+
+ThreadPlanContinue::ThreadPlanContinue (Thread &thread, bool stop_others, Vote stop_vote, Vote run_vote, bool immediate) :
+    ThreadPlan ("Continue after previous plan", thread, stop_vote, run_vote),
+    m_stop_others (stop_others),
+    m_did_run (false),
+    m_immediate (immediate)
+{
+}
+
+ThreadPlanContinue::~ThreadPlanContinue ()
+{
+}
+
+void
+ThreadPlanContinue::GetDescription (Stream *s, lldb::DescriptionLevel level)
+{
+    if (level == lldb::eDescriptionLevelBrief)
+        s->Printf ("continue");
+    else
+    {
+        s->Printf ("Continue from the previous plan");
+    }
+}
+
+bool
+ThreadPlanContinue::ValidatePlan (Stream *error)
+{
+    // Since we read the instruction we're stepping over from the thread,
+    // this plan will always work.
+    return true;
+}
+
+bool
+ThreadPlanContinue::PlanExplainsStop ()
+{
+    return true;
+}
+
+bool
+ThreadPlanContinue::ShouldStop (Event *event_ptr)
+{
+    return false;
+}
+
+bool
+ThreadPlanContinue::IsImmediate () const
+{
+    return m_immediate;
+    return false;
+}
+
+bool
+ThreadPlanContinue::StopOthers ()
+{
+    return m_stop_others;
+}
+
+StateType
+ThreadPlanContinue::RunState ()
+{
+    return eStateRunning;
+}
+
+bool
+ThreadPlanContinue::WillResume (StateType resume_state, bool current_plan)
+{
+    ThreadPlan::WillResume (resume_state, current_plan);
+    if (current_plan)
+    {
+        m_did_run = true;
+    }
+    return true;
+}
+
+bool
+ThreadPlanContinue::WillStop ()
+{
+    return true;
+}
+
+bool
+ThreadPlanContinue::MischiefManaged ()
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
+
+    if (m_did_run)
+    {
+        if (log)
+            log->Printf("Completed continue plan.");
+        ThreadPlan::MischiefManaged ();
+        return true;
+    }
+    else
+        return false;
+}
diff --git a/source/Target/ThreadPlanRunToAddress.cpp b/source/Target/ThreadPlanRunToAddress.cpp
new file mode 100644
index 0000000..0544ea5
--- /dev/null
+++ b/source/Target/ThreadPlanRunToAddress.cpp
@@ -0,0 +1,176 @@
+//===-- ThreadPlanRunToAddress.cpp ------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/ThreadPlanRunToAddress.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private-log.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/RegisterContext.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// ThreadPlanRunToAddress: Continue plan
+//----------------------------------------------------------------------
+
+ThreadPlanRunToAddress::ThreadPlanRunToAddress
+(
+    Thread &thread,
+    Address &address,
+    bool stop_others
+) :
+    ThreadPlan ("Run to breakpoint plan", thread, eVoteNoOpinion, eVoteNoOpinion),
+    m_stop_others (stop_others),
+    m_address (LLDB_INVALID_ADDRESS),
+    m_break_id (LLDB_INVALID_BREAK_ID)
+{
+    m_address = address.GetLoadAddress(&m_thread.GetProcess());
+    SetInitialBreakpoint();
+}
+
+ThreadPlanRunToAddress::ThreadPlanRunToAddress
+(
+    Thread &thread,
+    lldb::addr_t address,
+    bool stop_others
+) :
+    ThreadPlan ("Run to breakpoint plan", thread, eVoteNoOpinion, eVoteNoOpinion),
+    m_stop_others (stop_others),
+    m_address (address),
+    m_break_id (LLDB_INVALID_BREAK_ID)
+{
+    SetInitialBreakpoint();
+}
+
+void
+ThreadPlanRunToAddress::SetInitialBreakpoint ()
+{
+    Breakpoint *breakpoint;
+    breakpoint = m_thread.GetProcess().GetTarget().CreateBreakpoint (m_address, true).get();
+    if (breakpoint != NULL)
+    {
+        m_break_id = breakpoint->GetID();
+        breakpoint->SetThreadID(m_thread.GetID());
+    }
+}
+
+ThreadPlanRunToAddress::~ThreadPlanRunToAddress ()
+{
+    if (m_break_id != LLDB_INVALID_BREAK_ID)
+    {
+        m_thread.GetProcess().GetTarget().RemoveBreakpointByID (m_break_id);
+    }
+}
+
+void
+ThreadPlanRunToAddress::GetDescription (Stream *s, lldb::DescriptionLevel level)
+{
+    if (level == lldb::eDescriptionLevelBrief)
+    {
+        s->Printf ("run to address: ");
+        s->Address (m_address, sizeof (addr_t));
+    }
+    else
+    {
+        s->Printf ("Run to address: ");
+        s->Address(m_address, sizeof (addr_t));
+        s->Printf (" using breakpoint: %d - ", m_break_id);
+        Breakpoint *breakpoint = m_thread.GetProcess().GetTarget().GetBreakpointByID (m_break_id).get();
+        if (breakpoint)
+            breakpoint->Dump (s);
+        else
+            s->Printf ("but the breakpoint has been deleted.");
+    }
+}
+
+bool
+ThreadPlanRunToAddress::ValidatePlan (Stream *error)
+{
+    // If we couldn't set the breakpoint for some reason, then this won't
+    // work.
+    if(m_break_id == LLDB_INVALID_BREAK_ID)
+        return false;
+    else
+        return true;
+}
+
+bool
+ThreadPlanRunToAddress::PlanExplainsStop ()
+{
+    return AtOurAddress();
+}
+
+bool
+ThreadPlanRunToAddress::ShouldStop (Event *event_ptr)
+{
+    return false;
+}
+
+bool
+ThreadPlanRunToAddress::StopOthers ()
+{
+    return m_stop_others;
+}
+
+void
+ThreadPlanRunToAddress::SetStopOthers (bool new_value)
+{
+    m_stop_others = new_value;
+}
+
+StateType
+ThreadPlanRunToAddress::RunState ()
+{
+    return eStateRunning;
+}
+
+bool
+ThreadPlanRunToAddress::WillStop ()
+{
+    return true;
+}
+
+bool
+ThreadPlanRunToAddress::MischiefManaged ()
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
+
+    if (AtOurAddress())
+    {
+        // Remove the breakpoint
+        if (m_break_id != LLDB_INVALID_BREAK_ID)
+        {
+            m_thread.GetProcess().GetTarget().RemoveBreakpointByID (m_break_id);
+            m_break_id = LLDB_INVALID_BREAK_ID;
+        }
+
+        if (log)
+            log->Printf("Completed run to address plan.");
+        ThreadPlan::MischiefManaged ();
+        return true;
+    }
+    else
+        return false;
+}
+
+bool
+ThreadPlanRunToAddress::AtOurAddress ()
+{
+    lldb::addr_t current_address = m_thread.GetRegisterContext()->GetPC();
+    return m_address == current_address;
+}
diff --git a/source/Target/ThreadPlanShouldStopHere.cpp b/source/Target/ThreadPlanShouldStopHere.cpp
new file mode 100644
index 0000000..493ab63
--- /dev/null
+++ b/source/Target/ThreadPlanShouldStopHere.cpp
@@ -0,0 +1,53 @@
+//===-- ThreadPlanShouldStopHere.cpp ----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlanShouldStopHere.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+
+//----------------------------------------------------------------------
+// ThreadPlanShouldStopHere constructor
+//----------------------------------------------------------------------
+ThreadPlanShouldStopHere::ThreadPlanShouldStopHere(ThreadPlan *owner, ThreadPlanShouldStopHereCallback callback, void *baton) :
+    m_callback (callback),
+    m_baton (baton),
+    m_owner (owner),
+    m_flags (ThreadPlanShouldStopHere::eNone)
+{
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+ThreadPlanShouldStopHere::~ThreadPlanShouldStopHere()
+{
+}
+
+void
+ThreadPlanShouldStopHere::SetShouldStopHereCallback (ThreadPlanShouldStopHereCallback callback, void *baton)
+{
+    m_callback = callback;
+    m_baton = baton;
+}
+
+ThreadPlan *
+ThreadPlanShouldStopHere::InvokeShouldStopHereCallback ()
+{
+    if (m_callback)
+        return m_callback (m_owner, m_flags, m_baton);
+    else
+        return NULL;
+}
\ No newline at end of file
diff --git a/source/Target/ThreadPlanStepInRange.cpp b/source/Target/ThreadPlanStepInRange.cpp
new file mode 100644
index 0000000..f62fdb8
--- /dev/null
+++ b/source/Target/ThreadPlanStepInRange.cpp
@@ -0,0 +1,154 @@
+//===-- ThreadPlanStepInRange.cpp -------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/ThreadPlanStepInRange.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+
+#include "lldb/lldb-private-log.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlanStepOut.h"
+#include "lldb/Target/ThreadPlanStepThrough.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+uint32_t ThreadPlanStepInRange::s_default_flag_values = ThreadPlanShouldStopHere::eAvoidNoDebug;
+
+//----------------------------------------------------------------------
+// ThreadPlanStepInRange: Step through a stack range, either stepping over or into
+// based on the value of \a type.
+//----------------------------------------------------------------------
+
+ThreadPlanStepInRange::ThreadPlanStepInRange
+(
+    Thread &thread,
+    const AddressRange &range,
+    const SymbolContext &addr_context,
+    lldb::RunMode stop_others
+) :
+    ThreadPlanStepRange ("Step Range stepping in", thread, range, addr_context, stop_others),
+    ThreadPlanShouldStopHere (this, ThreadPlanStepInRange::DefaultShouldStopHereCallback, NULL)
+{
+    SetFlagsToDefault ();
+}
+
+ThreadPlanStepInRange::~ThreadPlanStepInRange ()
+{
+}
+
+void
+ThreadPlanStepInRange::GetDescription (Stream *s, lldb::DescriptionLevel level)
+{
+    if (level == lldb::eDescriptionLevelBrief)
+        s->Printf("step in");
+    else
+    {
+        s->Printf ("Stepping through range (stepping into functions): ");
+        m_address_range.Dump (s, &m_thread.GetProcess(), Address::DumpStyleLoadAddress);
+    }
+}
+
+bool
+ThreadPlanStepInRange::ShouldStop (Event *event_ptr)
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
+    m_no_more_plans = false;
+    
+    if (log)
+    {
+        StreamString s;
+        s.Address (m_thread.GetRegisterContext()->GetPC(), m_thread.GetProcess().GetAddressByteSize());
+        log->Printf("ThreadPlanStepInRange reached %s.", s.GetData());
+    }
+
+    // If we're still in the range, keep going.
+    if (InRange())
+        return false;
+
+    // If we're in an older frame then we should stop.
+    if (FrameIsOlder())
+        return true;
+        
+    // See if we are in a place we should step through (i.e. a trampoline of some sort):
+    // One tricky bit here is that some stubs don't push a frame, so we have to check
+    // both the case of a frame that is younger, or the same as this frame.  
+    // However, if the frame is the same, and we are still in the symbol we started
+    // in, the we don't need to do this.  This first check isn't strictly necessary,
+    // but it is more efficient.
+    
+    if (!FrameIsYounger() && InSymbol())
+    {
+        SetPlanComplete();
+        return true;
+    }
+    
+    ThreadPlan* new_plan = NULL;
+
+    bool stop_others;
+    if (m_stop_others == lldb::eOnlyThisThread)
+        stop_others = true;
+    else
+        stop_others = false;
+        
+    new_plan = m_thread.QueueThreadPlanForStepThrough (false, stop_others);
+    // If not, give the "should_stop" callback a chance to push a plan to get us out of here.
+    // But only do that if we actually have stepped in.
+    if (!new_plan && FrameIsYounger())
+        new_plan = InvokeShouldStopHereCallback();
+
+    if (new_plan == NULL)
+    {
+        m_no_more_plans = true;
+        SetPlanComplete();
+        return true;
+    }
+    else
+    {
+        m_no_more_plans = false;
+        return false;
+    }
+}
+
+void
+ThreadPlanStepInRange::SetFlagsToDefault ()
+{
+    GetFlags().Set(ThreadPlanStepInRange::s_default_flag_values);
+}
+
+void
+ThreadPlanStepInRange::SetDefaultFlagValue (uint32_t new_value)
+{
+    // TODO: Should we test this for sanity?
+    ThreadPlanStepInRange::s_default_flag_values = new_value;
+}
+
+ThreadPlan *
+ThreadPlanStepInRange::DefaultShouldStopHereCallback (ThreadPlan *current_plan, Flags &flags, void *baton)
+{
+    if (flags.IsSet(eAvoidNoDebug))
+    {
+        StackFrame *frame = current_plan->GetThread().GetStackFrameAtIndex(0).get();
+
+        if (!frame->HasDebugInformation())
+        {
+            // FIXME: Make sure the ThreadPlanForStepOut does the right thing with inlined functions.
+            return current_plan->GetThread().QueueThreadPlanForStepOut (false, NULL, true, current_plan->StopOthers(), eVoteNo, eVoteNoOpinion);
+        }
+    }
+
+    return NULL;
+}
diff --git a/source/Target/ThreadPlanStepInstruction.cpp b/source/Target/ThreadPlanStepInstruction.cpp
new file mode 100644
index 0000000..41c4373
--- /dev/null
+++ b/source/Target/ThreadPlanStepInstruction.cpp
@@ -0,0 +1,191 @@
+//===-- ThreadPlanStepInstruction.cpp ---------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#include "lldb/Target/ThreadPlanStepInstruction.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private-log.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Process.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// ThreadPlanStepInstruction: Step over the current instruction
+//----------------------------------------------------------------------
+
+ThreadPlanStepInstruction::ThreadPlanStepInstruction
+(
+    Thread &thread,
+    bool step_over,
+    bool stop_other_threads,
+    Vote stop_vote,
+    Vote run_vote
+) :
+    ThreadPlan ("Step over single instruction", thread, stop_vote, run_vote),
+    m_instruction_addr (0),
+    m_step_over (step_over),
+    m_stack_depth(0),
+    m_stop_other_threads (stop_other_threads)
+{
+    m_instruction_addr = m_thread.GetRegisterContext()->GetPC(0);
+    m_stack_depth = m_thread.GetStackFrameCount();
+}
+
+ThreadPlanStepInstruction::~ThreadPlanStepInstruction ()
+{
+}
+
+void
+ThreadPlanStepInstruction::GetDescription (Stream *s, lldb::DescriptionLevel level)
+{
+    if (level == lldb::eDescriptionLevelBrief)
+    {
+        if (m_step_over)
+            s->Printf ("instruction step over");
+        else
+            s->Printf ("instruction step into");
+    }
+    else
+    {
+        s->Printf ("Stepping one instruction past ");
+        s->Address(m_instruction_addr, sizeof (addr_t));
+        if (m_step_over)
+            s->Printf(" stepping over calls");
+        else
+            s->Printf(" stepping into calls");
+    }
+}
+
+bool
+ThreadPlanStepInstruction::ValidatePlan (Stream *error)
+{
+    // Since we read the instruction we're stepping over from the thread,
+    // this plan will always work.
+    return true;
+}
+
+bool
+ThreadPlanStepInstruction::PlanExplainsStop ()
+{
+    Thread::StopInfo info;
+    if (m_thread.GetStopInfo (&info))
+    {
+        StopReason reason = info.GetStopReason();
+        if (reason == eStopReasonTrace || reason ==eStopReasonNone)
+            return true;
+        else
+            return false;
+    }
+    return false;
+}
+
+bool
+ThreadPlanStepInstruction::ShouldStop (Event *event_ptr)
+{
+    if (m_step_over)
+    {
+        Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
+        if (m_thread.GetStackFrameCount() <= m_stack_depth)
+        {
+            if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr)
+            {
+                SetPlanComplete();
+                return true;
+            }
+            else
+                return false;
+        }
+        else
+        {
+            // We've stepped in, step back out again:
+            StackFrame *return_frame = m_thread.GetStackFrameAtIndex(1).get();
+            if (return_frame)
+            {
+                if (log)
+                {
+                    StreamString s;
+                    s.PutCString ("Stepped in to: ");
+                    addr_t stop_addr = m_thread.GetStackFrameAtIndex(0)->GetPC().GetLoadAddress(&m_thread.GetProcess());
+                    s.Address (stop_addr, m_thread.GetProcess().GetAddressByteSize());
+                    s.PutCString (" stepping out to: ");
+                    addr_t return_addr = return_frame->GetPC().GetLoadAddress(&m_thread.GetProcess());
+                    s.Address (return_addr, m_thread.GetProcess().GetAddressByteSize());
+                    log->Printf("%s.", s.GetData());
+                }
+                m_thread.QueueThreadPlanForStepOut(false, NULL, true, m_stop_other_threads, eVoteNo, eVoteNoOpinion);
+                return false;
+            }
+            else
+            {
+                if (log)
+                    log->Printf("Could not find previous frame, stopping.");
+                SetPlanComplete();
+                return true;
+            }
+
+        }
+
+    }
+    else
+    {
+        if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr)
+        {
+            SetPlanComplete();
+            return true;
+        }
+        else
+            return false;
+    }
+}
+
+bool
+ThreadPlanStepInstruction::StopOthers ()
+{
+    return m_stop_other_threads;
+}
+
+StateType
+ThreadPlanStepInstruction::RunState ()
+{
+    return eStateStepping;
+}
+
+bool
+ThreadPlanStepInstruction::WillStop ()
+{
+    return true;
+}
+
+bool
+ThreadPlanStepInstruction::MischiefManaged ()
+{
+    if (IsPlanComplete())
+    {
+        Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
+        if (log)
+            log->Printf("Completed single instruction step plan.");
+        ThreadPlan::MischiefManaged ();
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
diff --git a/source/Target/ThreadPlanStepOut.cpp b/source/Target/ThreadPlanStepOut.cpp
new file mode 100644
index 0000000..e05a8a4
--- /dev/null
+++ b/source/Target/ThreadPlanStepOut.cpp
@@ -0,0 +1,228 @@
+//===-- ThreadPlanStepOut.cpp -----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/ThreadPlanStepOut.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Breakpoint/Breakpoint.h"
+#include "lldb/lldb-private-log.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// ThreadPlanStepOut: Step out of the current frame
+//----------------------------------------------------------------------
+
+ThreadPlanStepOut::ThreadPlanStepOut
+(
+    Thread &thread,
+    SymbolContext *context,
+    bool first_insn,
+    bool stop_others,
+    Vote stop_vote,
+    Vote run_vote
+) :
+    ThreadPlan ("Step out", thread, stop_vote, run_vote),
+    m_step_from_context (context),
+    m_step_from_insn (LLDB_INVALID_ADDRESS),
+    m_return_addr (LLDB_INVALID_ADDRESS),
+    m_first_insn (first_insn),
+    m_return_bp_id(LLDB_INVALID_BREAK_ID),
+    m_stop_others (stop_others)
+{
+    m_step_from_insn = m_thread.GetRegisterContext()->GetPC(0);
+
+    // Find the return address and set a breakpoint there:
+    // FIXME - can we do this more securely if we know first_insn?
+
+    StackFrame *return_frame = m_thread.GetStackFrameAtIndex(1).get();
+    if (return_frame)
+    {
+        m_return_addr = return_frame->GetPC().GetLoadAddress(&m_thread.GetProcess());
+        Breakpoint *return_bp = m_thread.GetProcess().GetTarget().CreateBreakpoint (m_return_addr, true).get();
+        if (return_bp != NULL)
+        {
+            return_bp->SetThreadID(m_thread.GetID());
+            m_return_bp_id = return_bp->GetID();
+        }
+        else
+        {
+            m_return_bp_id = LLDB_INVALID_BREAK_ID;
+        }
+    }
+
+    m_stack_depth = m_thread.GetStackFrameCount();
+}
+
+ThreadPlanStepOut::~ThreadPlanStepOut ()
+{
+    if (m_return_bp_id != LLDB_INVALID_BREAK_ID)
+        m_thread.GetProcess().GetTarget().RemoveBreakpointByID(m_return_bp_id);
+}
+
+void
+ThreadPlanStepOut::GetDescription (Stream *s, lldb::DescriptionLevel level)
+{
+    if (level == lldb::eDescriptionLevelBrief)
+        s->Printf ("step out");
+    else
+    {
+        s->Printf ("Stepping out from address 0x%llx to return address 0x%llx using breakpoint site %d",
+                   (uint64_t)m_step_from_insn,
+                   (uint64_t)m_return_addr,
+                   m_return_bp_id);
+    }
+}
+
+bool
+ThreadPlanStepOut::ValidatePlan (Stream *error)
+{
+    if (m_return_bp_id == LLDB_INVALID_BREAK_ID)
+        return false;
+    else
+        return true;
+}
+
+bool
+ThreadPlanStepOut::PlanExplainsStop ()
+{
+    // We don't explain signals or breakpoints (breakpoints that handle stepping in or
+    // out will be handled by a child plan.
+    Thread::StopInfo info;
+    if (m_thread.GetStopInfo (&info))
+    {
+        StopReason reason = info.GetStopReason();
+
+        switch (reason)
+        {
+            case eStopReasonBreakpoint:
+            {
+                // If this is OUR breakpoint, we're fine, otherwise we don't know why this happened...
+                BreakpointSiteSP this_site = m_thread.GetProcess().GetBreakpointSiteList().FindByID (info.GetBreakpointSiteID());
+                if (!this_site)
+                    return false;
+
+                if (this_site->IsBreakpointAtThisSite (m_return_bp_id))
+                {
+                    // If there was only one owner, then we're done.  But if we also hit some
+                    // user breakpoint on our way out, we should mark ourselves as done, but
+                    // also not claim to explain the stop, since it is more important to report
+                    // the user breakpoint than the step out completion.
+
+                    if (this_site->GetNumberOfOwners() == 1)
+                        return true;
+                    else
+                    {
+                        SetPlanComplete();
+                        return false;
+                    }
+                }
+                else
+                    return false;
+            }
+            case eStopReasonWatchpoint:
+            case eStopReasonSignal:
+            case eStopReasonException:
+                return false;
+            default:
+                return true;
+        }
+    }
+    return true;
+}
+
+bool
+ThreadPlanStepOut::ShouldStop (Event *event_ptr)
+{
+    if (IsPlanComplete()
+        || m_thread.GetRegisterContext()->GetPC() == m_return_addr
+        || m_stack_depth > m_thread.GetStackFrameCount())
+    {
+        SetPlanComplete();
+        return true;
+    }
+    else
+        return false;
+}
+
+bool
+ThreadPlanStepOut::StopOthers ()
+{
+    return m_stop_others;
+}
+
+StateType
+ThreadPlanStepOut::RunState ()
+{
+    return eStateRunning;
+}
+
+bool
+ThreadPlanStepOut::WillResume (StateType resume_state, bool current_plan)
+{
+    ThreadPlan::WillResume (resume_state, current_plan);
+    if (m_return_bp_id == LLDB_INVALID_BREAK_ID)
+        return false;
+
+    if (current_plan)
+    {
+        Breakpoint *return_bp = m_thread.GetProcess().GetTarget().GetBreakpointByID(m_return_bp_id).get();
+        if (return_bp != NULL)
+            return_bp->SetEnabled (true);
+    }
+    return true;
+}
+
+bool
+ThreadPlanStepOut::WillStop ()
+{
+    Breakpoint *return_bp = m_thread.GetProcess().GetTarget().GetBreakpointByID(m_return_bp_id).get();
+    if (return_bp != NULL)
+        return_bp->SetEnabled (false);
+    return true;
+}
+
+bool
+ThreadPlanStepOut::MischiefManaged ()
+{
+    if (m_return_bp_id == LLDB_INVALID_BREAK_ID)
+    {
+        // If I couldn't set this breakpoint, then I'm just going to jettison myself.
+        return true;
+    }
+    else if (IsPlanComplete())
+    {
+        // Did I reach my breakpoint?  If so I'm done.
+        //
+        // I also check the stack depth, since if we've blown past the breakpoint for some
+        // reason and we're now stopping for some other reason altogether, then we're done
+        // with this step out operation.
+
+        Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
+        if (log)
+            log->Printf("Completed step out plan.");
+        m_thread.GetProcess().GetTarget().RemoveBreakpointByID (m_return_bp_id);
+        m_return_bp_id = LLDB_INVALID_BREAK_ID;
+        ThreadPlan::MischiefManaged ();
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
diff --git a/source/Target/ThreadPlanStepOverBreakpoint.cpp b/source/Target/ThreadPlanStepOverBreakpoint.cpp
new file mode 100644
index 0000000..2b8b06d
--- /dev/null
+++ b/source/Target/ThreadPlanStepOverBreakpoint.cpp
@@ -0,0 +1,130 @@
+//===-- ThreadPlanStepOverBreakpoint.cpp ------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/ThreadPlanStepOverBreakpoint.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private-log.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// ThreadPlanStepOverBreakpoint: Single steps over a breakpoint bp_site_sp at the pc.
+//----------------------------------------------------------------------
+
+ThreadPlanStepOverBreakpoint::ThreadPlanStepOverBreakpoint (Thread &thread) :
+    ThreadPlan ("Step over breakpoint trap",
+                thread,
+                eVoteNo,
+                eVoteNoOpinion),  // We need to report the run since this happens
+                            // first in the thread plan stack when stepping
+                            // over a breakpoint
+    m_breakpoint_addr (LLDB_INVALID_ADDRESS)
+{
+    m_breakpoint_addr = m_thread.GetRegisterContext()->GetPC();
+    m_breakpoint_site_id =  m_thread.GetProcess().GetBreakpointSiteList().FindIDByAddress (m_breakpoint_addr);
+
+}
+
+ThreadPlanStepOverBreakpoint::~ThreadPlanStepOverBreakpoint ()
+{
+}
+
+void
+ThreadPlanStepOverBreakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level)
+{
+    s->Printf("Single stepping past breakpoint site %d at 0x%llx", m_breakpoint_site_id, (uint64_t)m_breakpoint_addr);
+}
+
+bool
+ThreadPlanStepOverBreakpoint::ValidatePlan (Stream *error)
+{
+    return true;
+}
+
+bool
+ThreadPlanStepOverBreakpoint::PlanExplainsStop ()
+{
+    return true;
+}
+
+bool
+ThreadPlanStepOverBreakpoint::ShouldStop (Event *event_ptr)
+{
+    return false;
+}
+
+bool
+ThreadPlanStepOverBreakpoint::StopOthers ()
+{
+    return true;
+}
+
+StateType
+ThreadPlanStepOverBreakpoint::RunState ()
+{
+    return eStateStepping;
+}
+
+bool
+ThreadPlanStepOverBreakpoint::WillResume (StateType resume_state, bool current_plan)
+{
+    ThreadPlan::WillResume (resume_state, current_plan);
+
+    if (current_plan)
+    {
+        BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByAddress (m_breakpoint_addr));
+        if (bp_site_sp  && bp_site_sp->IsEnabled())
+            m_thread.GetProcess().DisableBreakpoint (bp_site_sp.get());
+    }
+    return true;
+}
+
+bool
+ThreadPlanStepOverBreakpoint::WillStop ()
+{
+    BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByAddress (m_breakpoint_addr));
+    if (bp_site_sp)
+        m_thread.GetProcess().EnableBreakpoint (bp_site_sp.get());
+    return true;
+}
+
+bool
+ThreadPlanStepOverBreakpoint::MischiefManaged ()
+{
+    lldb::addr_t pc_addr = m_thread.GetRegisterContext()->GetPC();
+
+    if (pc_addr == m_breakpoint_addr)
+    {
+        // If we are still at the PC of our breakpoint, then for some reason we didn't
+        // get a chance to run.
+        return false;
+    }
+    else
+    {
+        Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
+        if (log)
+            log->Printf("Completed step over breakpoint plan.");
+        // Otherwise, re-enable the breakpoint we were stepping over, and we're done.
+        BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByAddress (m_breakpoint_addr));
+        if (bp_site_sp)
+            m_thread.GetProcess().EnableBreakpoint (bp_site_sp.get());
+        ThreadPlan::MischiefManaged ();
+        return true;
+    }
+}
+
diff --git a/source/Target/ThreadPlanStepOverRange.cpp b/source/Target/ThreadPlanStepOverRange.cpp
new file mode 100644
index 0000000..ea56412
--- /dev/null
+++ b/source/Target/ThreadPlanStepOverRange.cpp
@@ -0,0 +1,119 @@
+//===-- ThreadPlanStepOverRange.cpp -----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/ThreadPlanStepOverRange.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+
+#include "lldb/lldb-private-log.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlanStepOut.h"
+#include "lldb/Target/ThreadPlanStepThrough.h"
+
+using namespace lldb_private;
+
+
+//----------------------------------------------------------------------
+// ThreadPlanStepOverRange: Step through a stack range, either stepping over or into
+// based on the value of \a type.
+//----------------------------------------------------------------------
+
+ThreadPlanStepOverRange::ThreadPlanStepOverRange
+(
+    Thread &thread,
+    const AddressRange &range,
+    const SymbolContext &addr_context,
+    lldb::RunMode stop_others,
+    bool okay_to_discard
+) :
+    ThreadPlanStepRange ("Step range stepping over", thread, range, addr_context, stop_others)
+{
+    SetOkayToDiscard (okay_to_discard);
+}
+
+ThreadPlanStepOverRange::~ThreadPlanStepOverRange ()
+{
+}
+
+void
+ThreadPlanStepOverRange::GetDescription (Stream *s, lldb::DescriptionLevel level)
+{
+    if (level == lldb::eDescriptionLevelBrief)
+        s->Printf("step over");
+    else
+    {
+        s->Printf ("stepping through range (stepping over functions): ");
+        m_address_range.Dump (s, &m_thread.GetProcess(), Address::DumpStyleLoadAddress);
+    }
+}
+
+bool
+ThreadPlanStepOverRange::ShouldStop (Event *event_ptr)
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
+
+    if (log)
+    {
+        StreamString s;
+        s.Address (m_thread.GetRegisterContext()->GetPC(), m_thread.GetProcess().GetAddressByteSize());
+        log->Printf("ThreadPlanStepOverRange reached %s.", s.GetData());
+    }
+    
+    // If we're still in the range, keep going.
+    if (InRange())
+        return false;
+
+    // If we're out of the range but in the same frame or in our caller's frame
+    // then we should stop.
+    // When stepping out we only step if we are forcing running one thread.
+    bool stop_others;
+    if (m_stop_others == lldb::eOnlyThisThread)
+        stop_others = true;
+    else 
+        stop_others = false;
+
+    ThreadPlan* new_plan = NULL;
+
+    if (FrameIsOlder())
+        return true;
+    else if (FrameIsYounger())
+    {
+        new_plan = m_thread.QueueThreadPlanForStepOut (false, NULL, true, stop_others, lldb::eVoteNo, lldb::eVoteNoOpinion);
+    }
+    else if (!InSymbol())
+    {
+        // This one is a little tricky.  Sometimes we may be in a stub or something similar,
+        // in which case we need to get out of there.  But if we are in a stub then it's 
+        // likely going to be hard to get out from here.  It is probably easiest to step into the
+        // stub, and then it will be straight-forward to step out.        
+        new_plan = m_thread.QueueThreadPlanForStepThrough (false, stop_others);
+    }
+
+    if (new_plan == NULL)
+        m_no_more_plans = true;
+    else
+        m_no_more_plans = false;
+
+    if (new_plan == NULL)
+    {
+        // For efficiencies sake, we know we're done here so we don't have to do this
+        // calculation again in MischiefManaged.
+        SetPlanComplete();
+        return true;
+    }
+    else
+        return false;
+}
diff --git a/source/Target/ThreadPlanStepRange.cpp b/source/Target/ThreadPlanStepRange.cpp
new file mode 100644
index 0000000..edf80a5
--- /dev/null
+++ b/source/Target/ThreadPlanStepRange.cpp
@@ -0,0 +1,263 @@
+//===-- ThreadPlanStepRange.cpp ---------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/ThreadPlanStepRange.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+
+#include "lldb/lldb-private-log.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/Symbol/Symbol.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+
+//----------------------------------------------------------------------
+// ThreadPlanStepRange: Step through a stack range, either stepping over or into
+// based on the value of \a type.
+//----------------------------------------------------------------------
+
+ThreadPlanStepRange::ThreadPlanStepRange (const char *name, Thread &thread, const AddressRange &range, const SymbolContext &addr_context, lldb::RunMode stop_others) :
+    ThreadPlan (name, thread, eVoteNoOpinion, eVoteNoOpinion),
+    m_address_range (range),
+    m_addr_context (addr_context),
+    m_stop_others (stop_others),
+    m_stack_depth (0),
+    m_no_more_plans (false),
+    m_stack_id (),
+    m_first_run_event (true)
+{
+    m_stack_depth = m_thread.GetStackFrameCount();
+    m_stack_id = m_thread.GetStackFrameAtIndex(0)->GetStackID();
+}
+
+ThreadPlanStepRange::~ThreadPlanStepRange ()
+{
+}
+
+bool
+ThreadPlanStepRange::ValidatePlan (Stream *error)
+{
+    return true;
+}
+
+bool
+ThreadPlanStepRange::PlanExplainsStop ()
+{
+    // We don't explain signals or breakpoints (breakpoints that handle stepping in or
+    // out will be handled by a child plan.
+    Thread::StopInfo info;
+    if (m_thread.GetStopInfo (&info))
+    {
+        StopReason reason = info.GetStopReason();
+
+        switch (reason)
+        {
+            case eStopReasonBreakpoint:
+            case eStopReasonWatchpoint:
+            case eStopReasonSignal:
+            case eStopReasonException:
+                return false;
+            default:
+                return true;
+        }
+    }
+    return true;
+}
+
+Vote
+ThreadPlanStepRange::ShouldReportStop (Event *event_ptr)
+{
+    if (IsPlanComplete())
+        return eVoteYes;
+    else
+        return eVoteNo;
+}
+
+bool
+ThreadPlanStepRange::InRange ()
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
+    bool ret_value = false;
+
+    lldb::addr_t pc_load_addr = m_thread.GetRegisterContext()->GetPC();
+
+    ret_value = m_address_range.ContainsLoadAddress(pc_load_addr, &m_thread.GetProcess());
+    
+    if (!ret_value)
+    {
+        // See if we've just stepped to another part of the same line number...
+        StackFrame *frame = m_thread.GetStackFrameAtIndex(0).get();
+        
+        SymbolContext new_context(frame->GetSymbolContext(eSymbolContextEverything));
+        if (m_addr_context.line_entry.IsValid() && new_context.line_entry.IsValid())
+        {
+           if ((m_addr_context.line_entry.file == new_context.line_entry.file)
+               && (m_addr_context.line_entry.line == new_context.line_entry.line))
+            {
+                m_addr_context = new_context;
+                m_address_range = m_addr_context.line_entry.range;
+                ret_value = true;
+                if (log)
+                {
+                    StreamString s;
+                    m_address_range.Dump (&s, &m_thread.GetProcess(), Address::DumpStyleLoadAddress);
+
+                    log->Printf ("Step range plan stepped to another range of same line: %s", s.GetData());
+                }
+            }
+        }
+        
+    }
+
+    if (!ret_value && log)
+        log->Printf ("Step range plan out of range to 0x%llx", pc_load_addr);
+
+    return ret_value;
+}
+
+bool
+ThreadPlanStepRange::InSymbol()
+{
+    lldb::addr_t cur_pc = m_thread.GetRegisterContext()->GetPC();
+    Process *process = m_thread.CalculateProcess();
+    
+    if (m_addr_context.function != NULL)
+    {
+        return m_addr_context.function->GetAddressRange().ContainsLoadAddress (cur_pc, process);
+    }
+    else if (m_addr_context.symbol != NULL)
+    {
+        return m_addr_context.symbol->GetAddressRangeRef().ContainsLoadAddress (cur_pc, process);
+    }
+    return false;
+}
+
+// FIXME: This should also handle inlining if we aren't going to do inlining in the
+// main stack.
+//
+// Ideally we should remember the whole stack frame list, and then compare that
+// to the current list.
+
+bool
+ThreadPlanStepRange::FrameIsYounger ()
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
+    uint32_t current_depth = m_thread.GetStackFrameCount();
+    if (current_depth == m_stack_depth)
+    {
+        if (log)
+            log->Printf ("Step range FrameIsYounger still in start function.");
+        return false;
+    }
+    else if (current_depth < m_stack_depth)
+    {
+        if (log)
+            log->Printf ("Step range FrameIsYounger stepped out: start depth: %d current depth %d.", m_stack_depth, current_depth);
+        return false;
+    }
+    else
+    {
+        if (log)
+            log->Printf ("Step range FrameIsYounger stepped in: start depth: %d current depth %d.", m_stack_depth, current_depth);
+        return true;
+    }
+}
+
+bool
+ThreadPlanStepRange::FrameIsOlder ()
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
+    uint32_t current_depth = m_thread.GetStackFrameCount();
+    if (current_depth == m_stack_depth)
+    {
+        if (log)
+            log->Printf ("Step range FrameIsOlder still in start function.");
+        return false;
+    }
+    else if (current_depth < m_stack_depth)
+    {
+        if (log)
+            log->Printf ("Step range FrameIsOlder stepped out: start depth: %d current depth %d.", m_stack_depth, current_depth);
+        return true;
+    }
+    else
+    {
+        if (log)
+            log->Printf ("Step range FrameIsOlder stepped in: start depth: %d current depth %d.", m_stack_depth, current_depth);
+        return false;
+    }
+}
+
+bool
+ThreadPlanStepRange::StopOthers ()
+{
+    if (m_stop_others == lldb::eOnlyThisThread
+        || m_stop_others == lldb::eOnlyDuringStepping)
+        return true;
+    else
+        return false;
+}
+
+bool
+ThreadPlanStepRange::WillStop ()
+{
+    return true;
+}
+
+StateType
+ThreadPlanStepRange::RunState ()
+{
+    return eStateStepping;
+}
+
+bool
+ThreadPlanStepRange::MischiefManaged ()
+{
+    bool done = true;
+    if (!IsPlanComplete())
+    {
+        if (InRange())
+        {
+            done = false;
+        }
+        else if (!FrameIsOlder())
+        {
+            if (m_no_more_plans)
+                done = true;
+            else
+                done = false;
+        }
+        else
+            done = true;
+    }
+
+    if (done)
+    {
+        Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
+        if (log)
+            log->Printf("Completed step through range plan.");
+        ThreadPlan::MischiefManaged ();
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+
+}
diff --git a/source/Target/ThreadPlanStepThrough.cpp b/source/Target/ThreadPlanStepThrough.cpp
new file mode 100644
index 0000000..5e614e5
--- /dev/null
+++ b/source/Target/ThreadPlanStepThrough.cpp
@@ -0,0 +1,137 @@
+//===-- ThreadPlanStepThrough.cpp -------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/ThreadPlanStepThrough.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private-log.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Target/DynamicLoader.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// ThreadPlanStepThrough: If the current instruction is a trampoline, step through it
+// If it is the beginning of the prologue of a function, step through that as well.
+// FIXME: At present only handles DYLD trampolines.
+//----------------------------------------------------------------------
+
+ThreadPlanStepThrough::ThreadPlanStepThrough (Thread &thread, bool stop_others) :
+    ThreadPlan ("Step through trampolines and prologues", thread, eVoteNoOpinion, eVoteNoOpinion),
+    m_start_address (0),
+    m_stop_others (stop_others)
+{
+    m_start_address = GetThread().GetRegisterContext()->GetPC(0);
+}
+
+ThreadPlanStepThrough::~ThreadPlanStepThrough ()
+{
+}
+
+void
+ThreadPlanStepThrough::GetDescription (Stream *s, lldb::DescriptionLevel level)
+{
+    if (level == lldb::eDescriptionLevelBrief)
+        s->Printf ("Step through");
+    else
+    {
+        s->Printf ("Stepping through trampoline code from: ");
+        s->Address(m_start_address, sizeof (addr_t));
+    }
+}
+
+bool
+ThreadPlanStepThrough::ValidatePlan (Stream *error)
+{
+    if (HappyToStopHere())
+        return false;
+    else
+        return true;
+}
+
+bool
+ThreadPlanStepThrough::PlanExplainsStop ()
+{
+    return true;
+}
+
+bool
+ThreadPlanStepThrough::ShouldStop (Event *event_ptr)
+{
+    return true;
+}
+
+bool
+ThreadPlanStepThrough::StopOthers ()
+{
+    return m_stop_others;
+}
+
+StateType
+ThreadPlanStepThrough::RunState ()
+{
+    return eStateStepping;
+}
+
+bool
+ThreadPlanStepThrough::WillResume (StateType resume_state, bool current_plan)
+{
+    ThreadPlan::WillResume(resume_state, current_plan);
+    if (current_plan)
+    {
+        ThreadPlanSP sub_plan_sp(m_thread.GetProcess().GetDynamicLoader()->GetStepThroughTrampolinePlan (m_thread, m_stop_others));
+        if (sub_plan_sp != NULL)
+            PushPlan (sub_plan_sp);
+    }
+    return true;
+}
+
+bool
+ThreadPlanStepThrough::WillStop ()
+{
+    return true;
+}
+
+bool
+ThreadPlanStepThrough::MischiefManaged ()
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
+
+    // Stop if we're happy with the place we've landed...
+
+    if (!HappyToStopHere())
+    {
+        // If we are still at the PC we were trying to step over.
+        return false;
+    }
+    else
+    {
+        if (log)
+            log->Printf("Completed step through step plan.");
+        ThreadPlan::MischiefManaged ();
+        return true;
+    }
+}
+
+bool
+ThreadPlanStepThrough::HappyToStopHere()
+{
+    // This should again ask the various trampolines whether we are still at a
+    // trampoline point, and if so, continue through the possibly nested trampolines.
+
+    return true;
+}
+
diff --git a/source/Target/ThreadPlanStepUntil.cpp b/source/Target/ThreadPlanStepUntil.cpp
new file mode 100644
index 0000000..3f9cdb5
--- /dev/null
+++ b/source/Target/ThreadPlanStepUntil.cpp
@@ -0,0 +1,360 @@
+//===-- ThreadPlanStepUntil.cpp ---------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//m_should_stop
+
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/ThreadPlanStepUntil.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Breakpoint/Breakpoint.h"
+#include "lldb/lldb-private-log.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// ThreadPlanStepUntil: Run until we reach a given line number or step out of the current frame
+//----------------------------------------------------------------------
+
+ThreadPlanStepUntil::ThreadPlanStepUntil
+(
+    Thread &thread,
+    lldb::addr_t *address_list,
+    size_t num_addresses,
+    bool stop_others
+) :
+    ThreadPlan ("Step out", thread, eVoteNoOpinion, eVoteNoOpinion),
+    m_step_from_insn (LLDB_INVALID_ADDRESS),
+    m_return_addr (LLDB_INVALID_ADDRESS),
+    m_return_bp_id(LLDB_INVALID_BREAK_ID),
+    m_stepped_out(false),
+    m_should_stop(false),
+    m_explains_stop(false),
+    m_ran_analyze (false),
+    m_stop_others (stop_others)
+{
+
+    SetOkayToDiscard(true);
+    // Stash away our "until" addresses:
+    Target &target = m_thread.GetProcess().GetTarget();
+
+    m_step_from_insn = m_thread.GetRegisterContext()->GetPC(0);
+    lldb::user_id_t thread_id = m_thread.GetID();
+
+    // Find the return address and set a breakpoint there:
+    // FIXME - can we do this more securely if we know first_insn?
+
+    StackFrame *return_frame = m_thread.GetStackFrameAtIndex(1).get();
+    m_return_addr = return_frame->GetPC().GetLoadAddress(&m_thread.GetProcess());
+    Breakpoint *return_bp = target.CreateBreakpoint (m_return_addr, true).get();
+    if (return_bp != NULL)
+    {
+        return_bp->SetThreadID(thread_id);
+        m_return_bp_id = return_bp->GetID();
+    }
+    else
+    {
+        m_return_bp_id = LLDB_INVALID_BREAK_ID;
+    }
+
+    m_stack_depth = m_thread.GetStackFrameCount();
+
+    // Now set breakpoints on all our return addresses:
+    for (int i = 0; i < num_addresses; i++)
+    {
+        Breakpoint *until_bp = target.CreateBreakpoint (address_list[i], true).get();
+        if (until_bp != NULL)
+        {
+            until_bp->SetThreadID(thread_id);
+            m_until_points[address_list[i]] = until_bp->GetID();
+        }
+        else
+        {
+            m_until_points[address_list[i]] = LLDB_INVALID_BREAK_ID;
+        }
+    }
+}
+
+ThreadPlanStepUntil::~ThreadPlanStepUntil ()
+{
+    Clear();
+}
+
+void
+ThreadPlanStepUntil::Clear()
+{
+    Target &target = m_thread.GetProcess().GetTarget();
+    if (m_return_bp_id != LLDB_INVALID_BREAK_ID)
+    {
+        target.RemoveBreakpointByID(m_return_bp_id);
+        m_return_bp_id = LLDB_INVALID_BREAK_ID;
+    }
+
+    until_collection::iterator pos, end = m_until_points.end();
+    for (pos = m_until_points.begin(); pos != end; pos++)
+    {
+        target.RemoveBreakpointByID((*pos).second);
+    }
+    m_until_points.clear();
+}
+
+void
+ThreadPlanStepUntil::GetDescription (Stream *s, lldb::DescriptionLevel level)
+{
+    if (level == lldb::eDescriptionLevelBrief)
+    {
+        s->Printf ("step until");
+        if (m_stepped_out)
+            s->Printf (" - stepped out");
+    }
+    else
+    {
+        if (m_until_points.size() == 1)
+            s->Printf ("Stepping from address 0x%llx until we reach 0x%llx using breakpoint %d",
+                       (uint64_t)m_step_from_insn,
+                       (uint64_t) (*m_until_points.begin()).first,
+                       (*m_until_points.begin()).second);
+        else
+        {
+            until_collection::iterator pos, end = m_until_points.end();
+            s->Printf ("Stepping from address 0x%llx until we reach one of:",
+                       (uint64_t)m_step_from_insn);
+            for (pos = m_until_points.begin(); pos != end; pos++)
+            {
+                s->Printf ("\n\t0x%llx (bp: %d)", (uint64_t) (*pos).first, (*pos).second);
+            }
+        }
+        s->Printf(" stepped out address is 0x%lx.", (uint64_t) m_return_addr);
+    }
+}
+
+bool
+ThreadPlanStepUntil::ValidatePlan (Stream *error)
+{
+    if (m_return_bp_id == LLDB_INVALID_BREAK_ID)
+        return false;
+    else
+    {
+        until_collection::iterator pos, end = m_until_points.end();
+        for (pos = m_until_points.begin(); pos != end; pos++)
+        {
+            if (!LLDB_BREAK_ID_IS_VALID ((*pos).second))
+                return false;
+        }
+        return true;
+    }
+}
+
+void
+ThreadPlanStepUntil::AnalyzeStop()
+{
+    if (m_ran_analyze)
+        return;
+        
+    Thread::StopInfo info;
+    m_should_stop = true;
+    m_explains_stop = false;
+    
+    if (m_thread.GetStopInfo (&info))
+    {
+        StopReason reason = info.GetStopReason();
+
+        switch (reason)
+        {
+            case eStopReasonBreakpoint:
+            {
+                // If this is OUR breakpoint, we're fine, otherwise we don't know why this happened...
+                BreakpointSiteSP this_site = m_thread.GetProcess().GetBreakpointSiteList().FindByID (info.GetBreakpointSiteID());
+                if (!this_site)
+                {
+                    m_explains_stop = false;
+                    return;
+                }
+
+                if (this_site->IsBreakpointAtThisSite (m_return_bp_id))
+                {
+                    // If we are at our "step out" breakpoint, and the stack depth has shrunk, then
+                    // this is indeed our stop.
+                    // If the stack depth has grown, then we've hit our step out breakpoint recursively.
+                    // If we are the only breakpoint at that location, then we do explain the stop, and
+                    // we'll just continue.
+                    // If there was another breakpoint here, then we don't explain the stop, but we won't
+                    // mark ourselves Completed, because maybe that breakpoint will continue, and then
+                    // we'll finish the "until".
+                    if (m_stack_depth > m_thread.GetStackFrameCount())
+                    {
+                        m_stepped_out = true;
+                        SetPlanComplete();
+                    }
+                    else
+                        m_should_stop = false;
+
+                    if (this_site->GetNumberOfOwners() == 1)
+                        m_explains_stop = true;
+                    else
+                        m_explains_stop = false;
+                    return;
+                }
+                else
+                {
+                    // Check if we've hit one of our "until" breakpoints.
+                    until_collection::iterator pos, end = m_until_points.end();
+                    for (pos = m_until_points.begin(); pos != end; pos++)
+                    {
+                        if (this_site->IsBreakpointAtThisSite ((*pos).second))
+                        {
+                            // If we're at the right stack depth, then we're done.
+                            if (m_stack_depth == m_thread.GetStackFrameCount())
+                                SetPlanComplete();
+                            else
+                                m_should_stop = false;
+
+                            // Otherwise we've hit this breakpoint recursively.  If we're the
+                            // only breakpoint here, then we do explain the stop, and we'll continue.
+                            // If not then we should let higher plans handle this stop.
+                            if (this_site->GetNumberOfOwners() == 1)
+                                m_explains_stop = true;
+                            else
+                            {
+                                m_should_stop = true;
+                                m_explains_stop = false;
+                            }
+                            return;
+                        }
+                    }
+                }
+                // If we get here we haven't hit any of our breakpoints, so let the higher
+                // plans take care of the stop.
+                m_explains_stop = false;
+                return;
+            }
+            case eStopReasonWatchpoint:
+            case eStopReasonSignal:
+            case eStopReasonException:
+                m_explains_stop = false;
+                break;
+            default:
+                m_explains_stop = true;
+                break;
+        }
+    }
+}
+
+bool
+ThreadPlanStepUntil::PlanExplainsStop ()
+{
+    // We don't explain signals or breakpoints (breakpoints that handle stepping in or
+    // out will be handled by a child plan.
+    AnalyzeStop();
+    return m_explains_stop;
+}
+
+bool
+ThreadPlanStepUntil::ShouldStop (Event *event_ptr)
+{
+    // If we've told our self in ExplainsStop that we plan to continue, then
+    // do so here.  Otherwise, as long as this thread has stopped for a reason,
+    // we will stop.
+
+    Thread::StopInfo stop_info (&m_thread);
+    if (!m_thread.GetStopInfo(&stop_info)
+        || stop_info.GetStopReason() == eStopReasonNone)
+        return false;
+
+    AnalyzeStop();
+    return m_should_stop;
+}
+
+bool
+ThreadPlanStepUntil::StopOthers ()
+{
+    return m_stop_others;
+}
+
+StateType
+ThreadPlanStepUntil::RunState ()
+{
+    return eStateRunning;
+}
+
+bool
+ThreadPlanStepUntil::WillResume (StateType resume_state, bool current_plan)
+{
+    ThreadPlan::WillResume (resume_state, current_plan);
+    if (current_plan)
+    {
+        Target &target = m_thread.GetProcess().GetTarget();
+        Breakpoint *return_bp = target.GetBreakpointByID(m_return_bp_id).get();
+        if (return_bp != NULL)
+            return_bp->SetEnabled (true);
+
+        until_collection::iterator pos, end = m_until_points.end();
+        for (pos = m_until_points.begin(); pos != end; pos++)
+        {
+            Breakpoint *until_bp = target.GetBreakpointByID((*pos).second).get();
+            if (until_bp != NULL)
+                until_bp->SetEnabled (true);
+        }
+    }
+    
+    m_should_stop = true;
+    m_ran_analyze = false;
+    m_explains_stop = false;
+    return true;
+}
+
+bool
+ThreadPlanStepUntil::WillStop ()
+{
+    Target &target = m_thread.GetProcess().GetTarget();
+    Breakpoint *return_bp = target.GetBreakpointByID(m_return_bp_id).get();
+    if (return_bp != NULL)
+        return_bp->SetEnabled (false);
+
+    until_collection::iterator pos, end = m_until_points.end();
+    for (pos = m_until_points.begin(); pos != end; pos++)
+    {
+        Breakpoint *until_bp = target.GetBreakpointByID((*pos).second).get();
+        if (until_bp != NULL)
+            until_bp->SetEnabled (false);
+    }
+    return true;
+}
+
+bool
+ThreadPlanStepUntil::MischiefManaged ()
+{
+
+    // I'm letting "PlanExplainsStop" do all the work, and just reporting that here.
+    bool done = false;
+    if (IsPlanComplete())
+    {
+        Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
+        if (log)
+            log->Printf("Completed step until plan.");
+
+        Clear();
+        done = true;
+    }
+    if (done)
+        ThreadPlan::MischiefManaged ();
+
+    return done;
+
+}
+
diff --git a/source/Target/UnixSignals.cpp b/source/Target/UnixSignals.cpp
new file mode 100644
index 0000000..e6500c5
--- /dev/null
+++ b/source/Target/UnixSignals.cpp
@@ -0,0 +1,310 @@
+//===-- UnixSignals.cpp -----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/UnixSignals.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+
+using namespace lldb_private;
+
+UnixSignals::Signal::Signal (const char *name, bool default_suppress, bool default_stop, bool default_notify) :
+    m_name (name),
+    m_conditions ()
+{
+    m_conditions[Signal::eCondSuppress] = default_suppress;
+    m_conditions[Signal::eCondStop]     = default_stop;
+    m_conditions[Signal::eCondNotify]   = default_notify;
+}
+
+//----------------------------------------------------------------------
+// UnixSignals constructor
+//----------------------------------------------------------------------
+UnixSignals::UnixSignals ()
+{
+    Reset ();
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+UnixSignals::~UnixSignals ()
+{
+}
+
+void
+UnixSignals::Reset ()
+{
+    // This builds one standard set of Unix Signals.  If yours aren't quite in this
+    // order, you can either subclass this class, and use Add & Remove to change them
+    // or you can subclass and build them afresh in your constructor;
+    m_signals.clear();
+
+    AddSignal(1, "SIGHUP",     false, true,  true );    // 1    hangup
+    AddSignal(2, "SIGINT",     true,  true,  true );    // 2    interrupt
+    AddSignal(3, "SIGQUIT",    false, true,  true );    // 3    quit
+    AddSignal(4, "SIGILL",     false, true,  true );    // 4    illegal instruction (not reset when caught)
+    AddSignal(5, "SIGTRAP",    true,  true,  true );    // 5    trace trap (not reset when caught)
+    AddSignal(6, "SIGABRT",    false, true,  true );    // 6    abort()
+    AddSignal(7, "SIGEMT",     false, true,  true );    // 7    pollable event ([XSR] generated, not supported)
+    AddSignal(8, "SIGFPE",     false, true,  true );    // 8    floating point exception
+    AddSignal(9, "SIGKILL",    false, true,  true );    // 9    kill (cannot be caught or ignored)
+    AddSignal(10, "SIGBUS",    false, true,  true );    // 10    bus error
+    AddSignal(11, "SIGSEGV",   false, true,  true );    // 11    segmentation violation
+    AddSignal(12, "SIGSYS",    false, true,  true );    // 12    bad argument to system call
+    AddSignal(13, "SIGPIPE",   false, true,  true );    // 13    write on a pipe with no one to read it
+    AddSignal(14, "SIGALRM",   false, false, true );    // 14    alarm clock
+    AddSignal(15, "SIGTERM",   false, true,  true );    // 15    software termination signal from kill
+    AddSignal(16, "SIGURG",    false, false, false);    // 16    urgent condition on IO channel
+    AddSignal(17, "SIGSTOP",   false, true,  true );    // 17    sendable stop signal not from tty
+    AddSignal(18, "SIGTSTP",   false, true,  true );    // 18    stop signal from tty
+    AddSignal(19, "SIGCONT",   false, true,  true );    // 19    continue a stopped process
+    AddSignal(20, "SIGCHLD",   false, false, true );    // 20    to parent on child stop or exit
+    AddSignal(21, "SIGTTIN",   false, true,  true );    // 21    to readers pgrp upon background tty read
+    AddSignal(22, "SIGTTOU",   false, true,  true );    // 22    like TTIN for output if (tp->t_local&LTOSTOP)
+    AddSignal(23, "SIGIO",     false, false, false);    // 23    input/output possible signal
+    AddSignal(24, "SIGXCPU",   false, true,  true );    // 24    exceeded CPU time limit
+    AddSignal(25, "SIGXFSZ",   false, true,  true );    // 25    exceeded file size limit
+    AddSignal(26, "SIGVTALRM", false, false, false);    // 26    virtual time alarm
+    AddSignal(27, "SIGPROF",   false, false, false);    // 27    profiling time alarm
+    AddSignal(28, "SIGWINCH",  false, false, false);    // 28    window size changes
+    AddSignal(29, "SIGINFO",   false, true,  true );    // 29    information request
+    AddSignal(30, "SIGUSR1",   false, true,  true );    // 30    user defined signal 1
+    AddSignal(31, "SIGUSR2",   false, true,  true );    // 31    user defined signal 2
+}
+void
+UnixSignals::AddSignal (int signo, const char *name, bool default_suppress, bool default_stop, bool default_notify)
+{
+    collection::iterator iter = m_signals.find (signo);
+    struct Signal new_signal (name, default_suppress, default_stop, default_notify);
+
+    if (iter != m_signals.end())
+        m_signals.erase (iter);
+
+    m_signals.insert (iter, collection::value_type (signo, new_signal));
+}
+
+void
+UnixSignals::RemoveSignal (int signo)
+{
+    collection::iterator pos = m_signals.find (signo);
+    if (pos != m_signals.end())
+        m_signals.erase (pos);
+}
+
+UnixSignals::Signal *
+UnixSignals::GetSignalByName (const char *name, int32_t &signo)
+{
+    ConstString const_name (name);
+
+    collection::iterator pos, end = m_signals.end ();
+    for (pos = m_signals.begin (); pos != end; pos++)
+    {
+        if (const_name == (*pos).second.m_name)
+        {
+            signo = (*pos).first;
+            return &((*pos).second);
+        }
+    }
+    return NULL;
+}
+
+
+const UnixSignals::Signal *
+UnixSignals::GetSignalByName (const char *name, int32_t &signo) const
+{
+    ConstString const_name (name);
+
+    collection::const_iterator pos, end = m_signals.end ();
+    for (pos = m_signals.begin (); pos != end; pos++)
+    {
+        if (const_name == (*pos).second.m_name)
+        {
+            signo = (*pos).first;
+            return &((*pos).second);
+        }
+    }
+    return NULL;
+}
+
+const char *
+UnixSignals::GetSignalAsCString (int signo) const
+{
+    collection::const_iterator pos = m_signals.find (signo);
+    if (pos == m_signals.end())
+        return NULL;
+    else
+        return (*pos).second.m_name.GetCString ();
+}
+
+
+bool
+UnixSignals::SignalIsValid (int32_t signo) const
+{
+    return m_signals.find (signo) != m_signals.end();
+}
+
+
+int32_t
+UnixSignals::GetSignalNumberFromName (const char *name) const
+{
+    int32_t signo;
+    const Signal *signal = GetSignalByName (name, signo);
+    if (signal == NULL)
+        return LLDB_INVALID_SIGNAL_NUMBER;
+    else
+        return signo;
+}
+
+int32_t
+UnixSignals::GetFirstSignalNumber () const
+{
+    if (m_signals.empty())
+        return LLDB_INVALID_SIGNAL_NUMBER;
+
+    return (*m_signals.begin ()).first;
+}
+
+int32_t
+UnixSignals::GetNextSignalNumber (int32_t current_signal) const
+{
+    collection::const_iterator pos = m_signals.find (current_signal);
+    collection::const_iterator end = m_signals.end();
+    if (pos == end)
+        return LLDB_INVALID_SIGNAL_NUMBER;
+    else
+    {
+        pos++;
+        if (pos == end)
+            return LLDB_INVALID_SIGNAL_NUMBER;
+        else
+            return (*pos).first;
+    }
+}
+
+const char *
+UnixSignals::GetSignalInfo
+(
+    int32_t signo,
+    bool &should_suppress,
+    bool &should_stop,
+    bool &should_notify
+) const
+{
+    collection::const_iterator pos = m_signals.find (signo);
+    if (pos == m_signals.end())
+        return NULL;
+    else
+    {
+        const Signal &signal = (*pos).second;
+        should_suppress = signal.m_conditions[Signal::eCondSuppress];
+        should_stop     = signal.m_conditions[Signal::eCondStop];
+        should_notify   = signal.m_conditions[Signal::eCondNotify];
+        return signal.m_name.AsCString("");
+    }
+}
+
+bool
+UnixSignals::GetCondition
+(
+    int32_t signo,
+    UnixSignals::Signal::Condition cond_pos
+) const
+{
+    collection::const_iterator pos = m_signals.find (signo);
+    if (pos == m_signals.end())
+        return false;
+    else
+        return (*pos).second.m_conditions[cond_pos];
+}
+
+bool
+UnixSignals::SetCondition (int32_t signo, UnixSignals::Signal::Condition cond_pos, bool value)
+{
+    collection::iterator pos = m_signals.find (signo);
+    if (pos == m_signals.end())
+        return false;
+    else
+    {
+        bool ret_value = (*pos).second.m_conditions[cond_pos];
+        (*pos).second.m_conditions[cond_pos] = value;
+        return ret_value;
+    }
+}
+
+bool
+UnixSignals::SetCondition (const char *signal_name, UnixSignals::Signal::Condition cond_pos, bool value)
+{
+    int32_t signo;
+    Signal *signal = GetSignalByName (signal_name, signo);
+    if (signal == NULL)
+        return false;
+    else
+    {
+        bool ret_value = signal->m_conditions[cond_pos];
+        signal->m_conditions[cond_pos] = value;
+        return ret_value;
+    }
+}
+
+bool
+UnixSignals::GetShouldSuppress (int signo) const
+{
+    return GetCondition (signo, Signal::eCondSuppress);
+}
+
+bool
+UnixSignals::SetShouldSuppress (int signo, bool value)
+{
+    return SetCondition (signo, Signal::eCondSuppress, value);
+}
+
+bool
+UnixSignals::SetShouldSuppress (const char *signal_name, bool value)
+{
+    return SetCondition (signal_name, Signal::eCondSuppress, value);
+}
+
+bool
+UnixSignals::GetShouldStop (int signo) const
+{
+    return GetCondition (signo, Signal::eCondStop);
+}
+
+bool
+UnixSignals::SetShouldStop (int signo, bool value)
+{
+    return SetCondition (signo, Signal::eCondStop, value);
+}
+
+bool
+UnixSignals::SetShouldStop (const char *signal_name, bool value)
+{
+    return SetCondition (signal_name, Signal::eCondStop, value);
+}
+
+bool
+UnixSignals::GetShouldNotify (int signo) const
+{
+    return GetCondition (signo, Signal::eCondNotify);
+}
+
+bool
+UnixSignals::SetShouldNotify (int signo, bool value)
+{
+    return SetCondition (signo, Signal::eCondNotify, value);
+}
+
+bool
+UnixSignals::SetShouldNotify (const char *signal_name, bool value)
+{
+    return SetCondition (signal_name, Signal::eCondNotify, value);
+}