diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp
index 9a04708..f7811f2 100644
--- a/lldb/source/API/SBDebugger.cpp
+++ b/lldb/source/API/SBDebugger.cpp
@@ -15,14 +15,13 @@
 
 #include "lldb/lldb-private.h"
 
-#include "lldb/API/SystemInitializerFull.h"
-#include "lldb/API/SBListener.h"
 #include "lldb/API/SBBroadcaster.h"
 #include "lldb/API/SBCommandInterpreter.h"
 #include "lldb/API/SBCommandReturnObject.h"
 #include "lldb/API/SBError.h"
 #include "lldb/API/SBEvent.h"
 #include "lldb/API/SBFrame.h"
+#include "lldb/API/SBListener.h"
 #include "lldb/API/SBProcess.h"
 #include "lldb/API/SBSourceManager.h"
 #include "lldb/API/SBStream.h"
@@ -30,11 +29,12 @@
 #include "lldb/API/SBTarget.h"
 #include "lldb/API/SBThread.h"
 #include "lldb/API/SBTypeCategory.h"
-#include "lldb/API/SBTypeFormat.h"
 #include "lldb/API/SBTypeFilter.h"
+#include "lldb/API/SBTypeFormat.h"
 #include "lldb/API/SBTypeNameSpecifier.h"
 #include "lldb/API/SBTypeSummary.h"
 #include "lldb/API/SBTypeSynthetic.h"
+#include "lldb/API/SystemInitializerFull.h"
 
 #include "lldb/Core/Debugger.h"
 #include "lldb/Core/State.h"
@@ -48,1335 +48,1090 @@
 #include "lldb/Target/TargetList.h"
 
 #include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/ManagedStatic.h"
 
 using namespace lldb;
 using namespace lldb_private;
 
-static llvm::sys::DynamicLibrary
-LoadPlugin (const lldb::DebuggerSP &debugger_sp, const FileSpec& spec, Error& error)
-{
-    llvm::sys::DynamicLibrary dynlib = llvm::sys::DynamicLibrary::getPermanentLibrary(spec.GetPath().c_str());
-    if (dynlib.isValid())
-    {
-        typedef bool (*LLDBCommandPluginInit) (lldb::SBDebugger& debugger);
-        
-        lldb::SBDebugger debugger_sb(debugger_sp);
-        // This calls the bool lldb::PluginInitialize(lldb::SBDebugger debugger) function.
-        // TODO: mangle this differently for your system - on OSX, the first underscore needs to be removed and the second one stays
-        LLDBCommandPluginInit init_func = (LLDBCommandPluginInit)dynlib.getAddressOfSymbol("_ZN4lldb16PluginInitializeENS_10SBDebuggerE");
-        if (init_func)
-        {
-            if (init_func(debugger_sb))
-                return dynlib;
-            else
-                error.SetErrorString("plug-in refused to load (lldb::PluginInitialize(lldb::SBDebugger) returned false)");
-        }
-        else
-        {
-            error.SetErrorString("plug-in is missing the required initialization: lldb::PluginInitialize(lldb::SBDebugger)");
-        }
+static llvm::sys::DynamicLibrary LoadPlugin(const lldb::DebuggerSP &debugger_sp,
+                                            const FileSpec &spec,
+                                            Error &error) {
+  llvm::sys::DynamicLibrary dynlib =
+      llvm::sys::DynamicLibrary::getPermanentLibrary(spec.GetPath().c_str());
+  if (dynlib.isValid()) {
+    typedef bool (*LLDBCommandPluginInit)(lldb::SBDebugger & debugger);
+
+    lldb::SBDebugger debugger_sb(debugger_sp);
+    // This calls the bool lldb::PluginInitialize(lldb::SBDebugger debugger)
+    // function.
+    // TODO: mangle this differently for your system - on OSX, the first
+    // underscore needs to be removed and the second one stays
+    LLDBCommandPluginInit init_func =
+        (LLDBCommandPluginInit)dynlib.getAddressOfSymbol(
+            "_ZN4lldb16PluginInitializeENS_10SBDebuggerE");
+    if (init_func) {
+      if (init_func(debugger_sb))
+        return dynlib;
+      else
+        error.SetErrorString("plug-in refused to load "
+                             "(lldb::PluginInitialize(lldb::SBDebugger) "
+                             "returned false)");
+    } else {
+      error.SetErrorString("plug-in is missing the required initialization: "
+                           "lldb::PluginInitialize(lldb::SBDebugger)");
     }
+  } else {
+    if (spec.Exists())
+      error.SetErrorString("this file does not represent a loadable dylib");
     else
-    {
-        if (spec.Exists())
-            error.SetErrorString("this file does not represent a loadable dylib");
-        else
-            error.SetErrorString("no such file");
-    }
-    return llvm::sys::DynamicLibrary();
+      error.SetErrorString("no such file");
+  }
+  return llvm::sys::DynamicLibrary();
 }
 
 static llvm::ManagedStatic<SystemLifetimeManager> g_debugger_lifetime;
 
-SBError
-SBInputReader::Initialize(lldb::SBDebugger &sb_debugger,
-                          unsigned long (*)(void *, lldb::SBInputReader *, lldb::InputReaderAction, char const *,
-                                            unsigned long),
-                          void *, lldb::InputReaderGranularity, char const *, char const *, bool)
-{
-    return SBError();
+SBError SBInputReader::Initialize(
+    lldb::SBDebugger &sb_debugger,
+    unsigned long (*)(void *, lldb::SBInputReader *, lldb::InputReaderAction,
+                      char const *, unsigned long),
+    void *, lldb::InputReaderGranularity, char const *, char const *, bool) {
+  return SBError();
 }
 
-void
-SBInputReader::SetIsDone(bool)
-{
-}
+void SBInputReader::SetIsDone(bool) {}
 
-bool
-SBInputReader::IsActive() const
-{
-    return false;
-}
+bool SBInputReader::IsActive() const { return false; }
 
 SBDebugger::SBDebugger() = default;
 
-SBDebugger::SBDebugger(const lldb::DebuggerSP &debugger_sp) :
-    m_opaque_sp(debugger_sp)
-{
-}
+SBDebugger::SBDebugger(const lldb::DebuggerSP &debugger_sp)
+    : m_opaque_sp(debugger_sp) {}
 
-SBDebugger::SBDebugger(const SBDebugger &rhs) :
-    m_opaque_sp (rhs.m_opaque_sp)
-{
-}
+SBDebugger::SBDebugger(const SBDebugger &rhs) : m_opaque_sp(rhs.m_opaque_sp) {}
 
 SBDebugger::~SBDebugger() = default;
 
-SBDebugger &
-SBDebugger::operator = (const SBDebugger &rhs)
-{
-    if (this != &rhs)
-    {
-        m_opaque_sp = rhs.m_opaque_sp;
-    }
-    return *this;
+SBDebugger &SBDebugger::operator=(const SBDebugger &rhs) {
+  if (this != &rhs) {
+    m_opaque_sp = rhs.m_opaque_sp;
+  }
+  return *this;
 }
 
-void
-SBDebugger::Initialize ()
-{
-    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+void SBDebugger::Initialize() {
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
 
-    if (log)
-        log->Printf ("SBDebugger::Initialize ()");
+  if (log)
+    log->Printf("SBDebugger::Initialize ()");
 
-    g_debugger_lifetime->Initialize(llvm::make_unique<SystemInitializerFull>(), LoadPlugin);
+  g_debugger_lifetime->Initialize(llvm::make_unique<SystemInitializerFull>(),
+                                  LoadPlugin);
 }
 
-void
-SBDebugger::Terminate ()
-{
-    g_debugger_lifetime->Terminate();
+void SBDebugger::Terminate() { g_debugger_lifetime->Terminate(); }
+
+void SBDebugger::Clear() {
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+  if (log)
+    log->Printf("SBDebugger(%p)::Clear ()",
+                static_cast<void *>(m_opaque_sp.get()));
+
+  if (m_opaque_sp)
+    m_opaque_sp->ClearIOHandlers();
+
+  m_opaque_sp.reset();
 }
 
-void
-SBDebugger::Clear ()
-{
-    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
-
-    if (log)
-        log->Printf ("SBDebugger(%p)::Clear ()",
-                     static_cast<void*>(m_opaque_sp.get()));
-
-    if (m_opaque_sp)
-        m_opaque_sp->ClearIOHandlers ();
-
-    m_opaque_sp.reset();
+SBDebugger SBDebugger::Create() {
+  return SBDebugger::Create(false, nullptr, nullptr);
 }
 
-SBDebugger
-SBDebugger::Create()
-{
-    return SBDebugger::Create(false, nullptr, nullptr);
+SBDebugger SBDebugger::Create(bool source_init_files) {
+  return SBDebugger::Create(source_init_files, nullptr, nullptr);
 }
 
-SBDebugger
-SBDebugger::Create(bool source_init_files)
-{
-    return SBDebugger::Create (source_init_files, nullptr, nullptr);
-}
-
-SBDebugger
-SBDebugger::Create(bool source_init_files, lldb::LogOutputCallback callback, void *baton)
+SBDebugger SBDebugger::Create(bool source_init_files,
+                              lldb::LogOutputCallback callback, void *baton)
 
 {
-    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
 
-    SBDebugger debugger;
-    
-    // Currently we have issues if this function is called simultaneously on two different
-    // threads. The issues mainly revolve around the fact that the lldb_private::FormatManager
-    // uses global collections and having two threads parsing the .lldbinit files can cause
-    // mayhem. So to get around this for now we need to use a mutex to prevent bad things
-    // from happening.
-    static std::recursive_mutex g_mutex;
-    std::lock_guard<std::recursive_mutex> guard(g_mutex);
+  SBDebugger debugger;
 
-    debugger.reset(Debugger::CreateInstance(callback, baton));
+  // Currently we have issues if this function is called simultaneously on two
+  // different
+  // threads. The issues mainly revolve around the fact that the
+  // lldb_private::FormatManager
+  // uses global collections and having two threads parsing the .lldbinit files
+  // can cause
+  // mayhem. So to get around this for now we need to use a mutex to prevent bad
+  // things
+  // from happening.
+  static std::recursive_mutex g_mutex;
+  std::lock_guard<std::recursive_mutex> guard(g_mutex);
 
-    if (log)
-    {
-        SBStream sstr;
-        debugger.GetDescription (sstr);
-        log->Printf ("SBDebugger::Create () => SBDebugger(%p): %s",
-                     static_cast<void*>(debugger.m_opaque_sp.get()),
-                     sstr.GetData());
-    }
+  debugger.reset(Debugger::CreateInstance(callback, baton));
 
-    SBCommandInterpreter interp = debugger.GetCommandInterpreter();
-    if (source_init_files)
-    {
-        interp.get()->SkipLLDBInitFiles(false);
-        interp.get()->SkipAppInitFiles (false);
-        SBCommandReturnObject result;
-        interp.SourceInitFileInHomeDirectory(result);
-    }
-    else
-    {
-        interp.get()->SkipLLDBInitFiles(true);
-        interp.get()->SkipAppInitFiles (true);
-    }
-    return debugger;
+  if (log) {
+    SBStream sstr;
+    debugger.GetDescription(sstr);
+    log->Printf("SBDebugger::Create () => SBDebugger(%p): %s",
+                static_cast<void *>(debugger.m_opaque_sp.get()),
+                sstr.GetData());
+  }
+
+  SBCommandInterpreter interp = debugger.GetCommandInterpreter();
+  if (source_init_files) {
+    interp.get()->SkipLLDBInitFiles(false);
+    interp.get()->SkipAppInitFiles(false);
+    SBCommandReturnObject result;
+    interp.SourceInitFileInHomeDirectory(result);
+  } else {
+    interp.get()->SkipLLDBInitFiles(true);
+    interp.get()->SkipAppInitFiles(true);
+  }
+  return debugger;
 }
 
-void
-SBDebugger::Destroy (SBDebugger &debugger)
-{
-    Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+void SBDebugger::Destroy(SBDebugger &debugger) {
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
 
-    if (log)
-    {
-        SBStream sstr;
-        debugger.GetDescription (sstr);
-        log->Printf ("SBDebugger::Destroy () => SBDebugger(%p): %s",
-                     static_cast<void*>(debugger.m_opaque_sp.get()),
-                     sstr.GetData());
-    }
+  if (log) {
+    SBStream sstr;
+    debugger.GetDescription(sstr);
+    log->Printf("SBDebugger::Destroy () => SBDebugger(%p): %s",
+                static_cast<void *>(debugger.m_opaque_sp.get()),
+                sstr.GetData());
+  }
 
-    Debugger::Destroy (debugger.m_opaque_sp);
+  Debugger::Destroy(debugger.m_opaque_sp);
 
-    if (debugger.m_opaque_sp.get() != nullptr)
-        debugger.m_opaque_sp.reset();
+  if (debugger.m_opaque_sp.get() != nullptr)
+    debugger.m_opaque_sp.reset();
 }
 
-void
-SBDebugger::MemoryPressureDetected ()
-{
-    // Since this function can be call asynchronously, we allow it to be
-    // non-mandatory. We have seen deadlocks with this function when called
-    // so we need to safeguard against this until we can determine what is
-    // causing the deadlocks.
-    Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
-    
-    const bool mandatory = false;
-    if (log)
-    {
-        log->Printf ("SBDebugger::MemoryPressureDetected (), mandatory = %d", mandatory);
-    }
-    
-    ModuleList::RemoveOrphanSharedModules(mandatory);
+void SBDebugger::MemoryPressureDetected() {
+  // Since this function can be call asynchronously, we allow it to be
+  // non-mandatory. We have seen deadlocks with this function when called
+  // so we need to safeguard against this until we can determine what is
+  // causing the deadlocks.
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+  const bool mandatory = false;
+  if (log) {
+    log->Printf("SBDebugger::MemoryPressureDetected (), mandatory = %d",
+                mandatory);
+  }
+
+  ModuleList::RemoveOrphanSharedModules(mandatory);
 }
 
-bool
-SBDebugger::IsValid() const
-{
-    return m_opaque_sp.get() != nullptr;
+bool SBDebugger::IsValid() const { return m_opaque_sp.get() != nullptr; }
+
+void SBDebugger::SetAsync(bool b) {
+  if (m_opaque_sp)
+    m_opaque_sp->SetAsyncExecution(b);
 }
 
-void
-SBDebugger::SetAsync (bool b)
-{
-    if (m_opaque_sp)
-        m_opaque_sp->SetAsyncExecution(b);
+bool SBDebugger::GetAsync() {
+  return (m_opaque_sp ? m_opaque_sp->GetAsyncExecution() : false);
 }
 
-bool
-SBDebugger::GetAsync()
-{
-    return (m_opaque_sp ? m_opaque_sp->GetAsyncExecution() : false);
+void SBDebugger::SkipLLDBInitFiles(bool b) {
+  if (m_opaque_sp)
+    m_opaque_sp->GetCommandInterpreter().SkipLLDBInitFiles(b);
 }
 
-void
-SBDebugger::SkipLLDBInitFiles (bool b)
-{
-    if (m_opaque_sp)
-        m_opaque_sp->GetCommandInterpreter().SkipLLDBInitFiles (b);
+void SBDebugger::SkipAppInitFiles(bool b) {
+  if (m_opaque_sp)
+    m_opaque_sp->GetCommandInterpreter().SkipAppInitFiles(b);
 }
 
-void
-SBDebugger::SkipAppInitFiles (bool b)
-{
-    if (m_opaque_sp)
-        m_opaque_sp->GetCommandInterpreter().SkipAppInitFiles (b);
-}
-
-// Shouldn't really be settable after initialization as this could cause lots of problems; don't want users
+// Shouldn't really be settable after initialization as this could cause lots of
+// problems; don't want users
 // trying to switch modes in the middle of a debugging session.
-void
-SBDebugger::SetInputFileHandle (FILE *fh, bool transfer_ownership)
-{
-    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+void SBDebugger::SetInputFileHandle(FILE *fh, bool transfer_ownership) {
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
 
-    if (log)
-        log->Printf ("SBDebugger(%p)::SetInputFileHandle (fh=%p, transfer_ownership=%i)",
-                     static_cast<void*>(m_opaque_sp.get()),
-                     static_cast<void*>(fh), transfer_ownership);
+  if (log)
+    log->Printf(
+        "SBDebugger(%p)::SetInputFileHandle (fh=%p, transfer_ownership=%i)",
+        static_cast<void *>(m_opaque_sp.get()), static_cast<void *>(fh),
+        transfer_ownership);
 
-    if (m_opaque_sp)
-        m_opaque_sp->SetInputFileHandle (fh, transfer_ownership);
+  if (m_opaque_sp)
+    m_opaque_sp->SetInputFileHandle(fh, transfer_ownership);
 }
 
-void
-SBDebugger::SetOutputFileHandle (FILE *fh, bool transfer_ownership)
-{
-    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+void SBDebugger::SetOutputFileHandle(FILE *fh, bool transfer_ownership) {
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
 
+  if (log)
+    log->Printf(
+        "SBDebugger(%p)::SetOutputFileHandle (fh=%p, transfer_ownership=%i)",
+        static_cast<void *>(m_opaque_sp.get()), static_cast<void *>(fh),
+        transfer_ownership);
 
-    if (log)
-        log->Printf ("SBDebugger(%p)::SetOutputFileHandle (fh=%p, transfer_ownership=%i)",
-                     static_cast<void*>(m_opaque_sp.get()),
-                     static_cast<void*>(fh), transfer_ownership);
-
-    if (m_opaque_sp)
-        m_opaque_sp->SetOutputFileHandle (fh, transfer_ownership);
+  if (m_opaque_sp)
+    m_opaque_sp->SetOutputFileHandle(fh, transfer_ownership);
 }
 
-void
-SBDebugger::SetErrorFileHandle (FILE *fh, bool transfer_ownership)
-{
-    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+void SBDebugger::SetErrorFileHandle(FILE *fh, bool transfer_ownership) {
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
 
+  if (log)
+    log->Printf(
+        "SBDebugger(%p)::SetErrorFileHandle (fh=%p, transfer_ownership=%i)",
+        static_cast<void *>(m_opaque_sp.get()), static_cast<void *>(fh),
+        transfer_ownership);
 
-    if (log)
-        log->Printf ("SBDebugger(%p)::SetErrorFileHandle (fh=%p, transfer_ownership=%i)",
-                     static_cast<void*>(m_opaque_sp.get()),
-                     static_cast<void*>(fh), transfer_ownership);
-
-    if (m_opaque_sp)
-        m_opaque_sp->SetErrorFileHandle (fh, transfer_ownership);
+  if (m_opaque_sp)
+    m_opaque_sp->SetErrorFileHandle(fh, transfer_ownership);
 }
 
-FILE *
-SBDebugger::GetInputFileHandle ()
-{
-    if (m_opaque_sp)
-    {
-        StreamFileSP stream_file_sp (m_opaque_sp->GetInputFile());
-        if (stream_file_sp)
-            return stream_file_sp->GetFile().GetStream();
-    }
-    return nullptr;
+FILE *SBDebugger::GetInputFileHandle() {
+  if (m_opaque_sp) {
+    StreamFileSP stream_file_sp(m_opaque_sp->GetInputFile());
+    if (stream_file_sp)
+      return stream_file_sp->GetFile().GetStream();
+  }
+  return nullptr;
 }
 
-FILE *
-SBDebugger::GetOutputFileHandle ()
-{
-    if (m_opaque_sp)
-    {
-        StreamFileSP stream_file_sp (m_opaque_sp->GetOutputFile());
-        if (stream_file_sp)
-            return stream_file_sp->GetFile().GetStream();
-    }
-    return nullptr;
+FILE *SBDebugger::GetOutputFileHandle() {
+  if (m_opaque_sp) {
+    StreamFileSP stream_file_sp(m_opaque_sp->GetOutputFile());
+    if (stream_file_sp)
+      return stream_file_sp->GetFile().GetStream();
+  }
+  return nullptr;
 }
 
-FILE *
-SBDebugger::GetErrorFileHandle ()
-{
-    if (m_opaque_sp)
-    {
-        StreamFileSP stream_file_sp(m_opaque_sp->GetErrorFile());
-        if (stream_file_sp)
-            return stream_file_sp->GetFile().GetStream();
-    }
-    return nullptr;
+FILE *SBDebugger::GetErrorFileHandle() {
+  if (m_opaque_sp) {
+    StreamFileSP stream_file_sp(m_opaque_sp->GetErrorFile());
+    if (stream_file_sp)
+      return stream_file_sp->GetFile().GetStream();
+  }
+  return nullptr;
 }
 
-void
-SBDebugger::SaveInputTerminalState()
-{
-    if (m_opaque_sp)
-        m_opaque_sp->SaveInputTerminalState();
+void SBDebugger::SaveInputTerminalState() {
+  if (m_opaque_sp)
+    m_opaque_sp->SaveInputTerminalState();
 }
 
-void
-SBDebugger::RestoreInputTerminalState()
-{
-    if (m_opaque_sp)
-        m_opaque_sp->RestoreInputTerminalState();
-
+void SBDebugger::RestoreInputTerminalState() {
+  if (m_opaque_sp)
+    m_opaque_sp->RestoreInputTerminalState();
 }
-SBCommandInterpreter
-SBDebugger::GetCommandInterpreter ()
-{
-    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+SBCommandInterpreter SBDebugger::GetCommandInterpreter() {
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
 
-    SBCommandInterpreter sb_interpreter;
-    if (m_opaque_sp)
-        sb_interpreter.reset (&m_opaque_sp->GetCommandInterpreter());
+  SBCommandInterpreter sb_interpreter;
+  if (m_opaque_sp)
+    sb_interpreter.reset(&m_opaque_sp->GetCommandInterpreter());
 
-    if (log)
-        log->Printf ("SBDebugger(%p)::GetCommandInterpreter () => SBCommandInterpreter(%p)",
-                     static_cast<void*>(m_opaque_sp.get()),
-                     static_cast<void*>(sb_interpreter.get()));
+  if (log)
+    log->Printf(
+        "SBDebugger(%p)::GetCommandInterpreter () => SBCommandInterpreter(%p)",
+        static_cast<void *>(m_opaque_sp.get()),
+        static_cast<void *>(sb_interpreter.get()));
 
-    return sb_interpreter;
+  return sb_interpreter;
 }
 
-void
-SBDebugger::HandleCommand (const char *command)
-{
-    if (m_opaque_sp)
-    {
-        TargetSP target_sp (m_opaque_sp->GetSelectedTarget());
-        std::unique_lock<std::recursive_mutex> lock;
-        if (target_sp)
-            lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
+void SBDebugger::HandleCommand(const char *command) {
+  if (m_opaque_sp) {
+    TargetSP target_sp(m_opaque_sp->GetSelectedTarget());
+    std::unique_lock<std::recursive_mutex> lock;
+    if (target_sp)
+      lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
 
-        SBCommandInterpreter sb_interpreter(GetCommandInterpreter ());
-        SBCommandReturnObject result;
+    SBCommandInterpreter sb_interpreter(GetCommandInterpreter());
+    SBCommandReturnObject result;
 
-        sb_interpreter.HandleCommand (command, result, false);
+    sb_interpreter.HandleCommand(command, result, false);
 
-        if (GetErrorFileHandle() != nullptr)
-            result.PutError (GetErrorFileHandle());
-        if (GetOutputFileHandle() != nullptr)
-            result.PutOutput (GetOutputFileHandle());
+    if (GetErrorFileHandle() != nullptr)
+      result.PutError(GetErrorFileHandle());
+    if (GetOutputFileHandle() != nullptr)
+      result.PutOutput(GetOutputFileHandle());
 
-        if (!m_opaque_sp->GetAsyncExecution())
-        {
-            SBProcess process(GetCommandInterpreter().GetProcess ());
-            ProcessSP process_sp (process.GetSP());
-            if (process_sp)
-            {
-                EventSP event_sp;
-                ListenerSP lldb_listener_sp = m_opaque_sp->GetListener();
-                while (lldb_listener_sp->GetNextEventForBroadcaster (process_sp.get(), event_sp))
-                {
-                    SBEvent event(event_sp);
-                    HandleProcessEvent (process, event, GetOutputFileHandle(), GetErrorFileHandle());
-                }
-            }
+    if (!m_opaque_sp->GetAsyncExecution()) {
+      SBProcess process(GetCommandInterpreter().GetProcess());
+      ProcessSP process_sp(process.GetSP());
+      if (process_sp) {
+        EventSP event_sp;
+        ListenerSP lldb_listener_sp = m_opaque_sp->GetListener();
+        while (lldb_listener_sp->GetNextEventForBroadcaster(process_sp.get(),
+                                                            event_sp)) {
+          SBEvent event(event_sp);
+          HandleProcessEvent(process, event, GetOutputFileHandle(),
+                             GetErrorFileHandle());
         }
+      }
     }
+  }
 }
 
-SBListener
-SBDebugger::GetListener ()
-{
-    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+SBListener SBDebugger::GetListener() {
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
 
-    SBListener sb_listener;
-    if (m_opaque_sp)
-        sb_listener.reset(m_opaque_sp->GetListener());
+  SBListener sb_listener;
+  if (m_opaque_sp)
+    sb_listener.reset(m_opaque_sp->GetListener());
 
-    if (log)
-        log->Printf ("SBDebugger(%p)::GetListener () => SBListener(%p)",
-                     static_cast<void*>(m_opaque_sp.get()),
-                     static_cast<void*>(sb_listener.get()));
+  if (log)
+    log->Printf("SBDebugger(%p)::GetListener () => SBListener(%p)",
+                static_cast<void *>(m_opaque_sp.get()),
+                static_cast<void *>(sb_listener.get()));
 
-    return sb_listener;
+  return sb_listener;
 }
 
-void
-SBDebugger::HandleProcessEvent (const SBProcess &process, const SBEvent &event, FILE *out, FILE *err)
-{
-    if (!process.IsValid())
-        return;
+void SBDebugger::HandleProcessEvent(const SBProcess &process,
+                                    const SBEvent &event, FILE *out,
+                                    FILE *err) {
+  if (!process.IsValid())
+    return;
 
-    TargetSP target_sp (process.GetTarget().GetSP());
-    if (!target_sp)
-        return;
+  TargetSP target_sp(process.GetTarget().GetSP());
+  if (!target_sp)
+    return;
 
-    const uint32_t event_type = event.GetType();
-    char stdio_buffer[1024];
-    size_t len;
+  const uint32_t event_type = event.GetType();
+  char stdio_buffer[1024];
+  size_t len;
 
-    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
+  std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
 
-    if (event_type & (Process::eBroadcastBitSTDOUT | Process::eBroadcastBitStateChanged))
-    {
-        // Drain stdout when we stop just in case we have any bytes
-        while ((len = process.GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0)
-            if (out != nullptr)
-                ::fwrite (stdio_buffer, 1, len, out);
-    }
-    
-    if (event_type & (Process::eBroadcastBitSTDERR | Process::eBroadcastBitStateChanged))
-    {
-        // Drain stderr when we stop just in case we have any bytes
-        while ((len = process.GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0)
-            if (err != nullptr)
-                ::fwrite (stdio_buffer, 1, len, err);
-    }
+  if (event_type &
+      (Process::eBroadcastBitSTDOUT | Process::eBroadcastBitStateChanged)) {
+    // Drain stdout when we stop just in case we have any bytes
+    while ((len = process.GetSTDOUT(stdio_buffer, sizeof(stdio_buffer))) > 0)
+      if (out != nullptr)
+        ::fwrite(stdio_buffer, 1, len, out);
+  }
 
-    if (event_type & Process::eBroadcastBitStateChanged)
-    {
-        StateType event_state = SBProcess::GetStateFromEvent (event);
-        
-        if (event_state == eStateInvalid)
-            return;
-        
-        bool is_stopped = StateIsStoppedState (event_state);
-        if (!is_stopped)
-            process.ReportEventState (event, out);
-    }
+  if (event_type &
+      (Process::eBroadcastBitSTDERR | Process::eBroadcastBitStateChanged)) {
+    // Drain stderr when we stop just in case we have any bytes
+    while ((len = process.GetSTDERR(stdio_buffer, sizeof(stdio_buffer))) > 0)
+      if (err != nullptr)
+        ::fwrite(stdio_buffer, 1, len, err);
+  }
+
+  if (event_type & Process::eBroadcastBitStateChanged) {
+    StateType event_state = SBProcess::GetStateFromEvent(event);
+
+    if (event_state == eStateInvalid)
+      return;
+
+    bool is_stopped = StateIsStoppedState(event_state);
+    if (!is_stopped)
+      process.ReportEventState(event, out);
+  }
 }
 
-SBSourceManager
-SBDebugger::GetSourceManager ()
-{
-    SBSourceManager sb_source_manager (*this);
-    return sb_source_manager;
+SBSourceManager SBDebugger::GetSourceManager() {
+  SBSourceManager sb_source_manager(*this);
+  return sb_source_manager;
 }
 
-bool
-SBDebugger::GetDefaultArchitecture (char *arch_name, size_t arch_name_len)
-{
-    if (arch_name && arch_name_len)
-    {
-        ArchSpec default_arch = Target::GetDefaultArchitecture ();
+bool SBDebugger::GetDefaultArchitecture(char *arch_name, size_t arch_name_len) {
+  if (arch_name && arch_name_len) {
+    ArchSpec default_arch = Target::GetDefaultArchitecture();
 
-        if (default_arch.IsValid())
-        {
-            const std::string &triple_str = default_arch.GetTriple().str();
-            if (!triple_str.empty())
-                ::snprintf (arch_name, arch_name_len, "%s", triple_str.c_str());
-            else
-                ::snprintf (arch_name, arch_name_len, "%s", default_arch.GetArchitectureName());
-            return true;
-        }
+    if (default_arch.IsValid()) {
+      const std::string &triple_str = default_arch.GetTriple().str();
+      if (!triple_str.empty())
+        ::snprintf(arch_name, arch_name_len, "%s", triple_str.c_str());
+      else
+        ::snprintf(arch_name, arch_name_len, "%s",
+                   default_arch.GetArchitectureName());
+      return true;
     }
-    if (arch_name && arch_name_len)
-        arch_name[0] = '\0';
-    return false;
+  }
+  if (arch_name && arch_name_len)
+    arch_name[0] = '\0';
+  return false;
 }
 
-bool
-SBDebugger::SetDefaultArchitecture (const char *arch_name)
-{
-    if (arch_name)
-    {
-        ArchSpec arch (arch_name);
-        if (arch.IsValid())
-        {
-            Target::SetDefaultArchitecture (arch);
-            return true;
-        }
+bool SBDebugger::SetDefaultArchitecture(const char *arch_name) {
+  if (arch_name) {
+    ArchSpec arch(arch_name);
+    if (arch.IsValid()) {
+      Target::SetDefaultArchitecture(arch);
+      return true;
     }
-    return false;
+  }
+  return false;
 }
 
 ScriptLanguage
-SBDebugger::GetScriptingLanguage(const char *script_language_name)
-{
-    return Args::StringToScriptLanguage(script_language_name,
-                                        eScriptLanguageDefault,
-                                        nullptr);
+SBDebugger::GetScriptingLanguage(const char *script_language_name) {
+  return Args::StringToScriptLanguage(script_language_name,
+                                      eScriptLanguageDefault, nullptr);
 }
 
-const char *
-SBDebugger::GetVersionString ()
-{
-    return lldb_private::GetVersion();
+const char *SBDebugger::GetVersionString() {
+  return lldb_private::GetVersion();
 }
 
-const char *
-SBDebugger::StateAsCString (StateType state)
-{
-    return lldb_private::StateAsCString (state);
+const char *SBDebugger::StateAsCString(StateType state) {
+  return lldb_private::StateAsCString(state);
 }
 
-bool
-SBDebugger::StateIsRunningState (StateType state)
-{
-    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+bool SBDebugger::StateIsRunningState(StateType state) {
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
 
-    const bool result = lldb_private::StateIsRunningState (state);
-    if (log)
-        log->Printf ("SBDebugger::StateIsRunningState (state=%s) => %i", 
-                     StateAsCString (state), result);
+  const bool result = lldb_private::StateIsRunningState(state);
+  if (log)
+    log->Printf("SBDebugger::StateIsRunningState (state=%s) => %i",
+                StateAsCString(state), result);
 
-    return result;
+  return result;
 }
 
-bool
-SBDebugger::StateIsStoppedState (StateType state)
-{
-    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+bool SBDebugger::StateIsStoppedState(StateType state) {
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
 
-    const bool result = lldb_private::StateIsStoppedState (state, false);
-    if (log)
-        log->Printf ("SBDebugger::StateIsStoppedState (state=%s) => %i", 
-                     StateAsCString (state), result);
+  const bool result = lldb_private::StateIsStoppedState(state, false);
+  if (log)
+    log->Printf("SBDebugger::StateIsStoppedState (state=%s) => %i",
+                StateAsCString(state), result);
 
-    return result;
+  return result;
 }
 
-lldb::SBTarget
-SBDebugger::CreateTarget (const char *filename,
-                          const char *target_triple,
-                          const char *platform_name,
-                          bool add_dependent_modules,
-                          lldb::SBError& sb_error)
-{
-    SBTarget sb_target;
-    TargetSP target_sp;
-    if (m_opaque_sp)
-    {
-        sb_error.Clear();
-        OptionGroupPlatform platform_options (false);
-        platform_options.SetPlatformName (platform_name);
+lldb::SBTarget SBDebugger::CreateTarget(const char *filename,
+                                        const char *target_triple,
+                                        const char *platform_name,
+                                        bool add_dependent_modules,
+                                        lldb::SBError &sb_error) {
+  SBTarget sb_target;
+  TargetSP target_sp;
+  if (m_opaque_sp) {
+    sb_error.Clear();
+    OptionGroupPlatform platform_options(false);
+    platform_options.SetPlatformName(platform_name);
 
-        sb_error.ref() = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, 
-                                                                    filename, 
-                                                                    target_triple, 
-                                                                    add_dependent_modules, 
-                                                                    &platform_options,
-                                                                    target_sp);
+    sb_error.ref() = m_opaque_sp->GetTargetList().CreateTarget(
+        *m_opaque_sp, filename, target_triple, add_dependent_modules,
+        &platform_options, target_sp);
 
-        if (sb_error.Success())
-            sb_target.SetSP (target_sp);
-    }
-    else
-    {
-        sb_error.SetErrorString("invalid debugger");
-    }
+    if (sb_error.Success())
+      sb_target.SetSP(target_sp);
+  } else {
+    sb_error.SetErrorString("invalid debugger");
+  }
 
-    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
-    if (log)
-        log->Printf ("SBDebugger(%p)::CreateTarget (filename=\"%s\", triple=%s, platform_name=%s, add_dependent_modules=%u, error=%s) => SBTarget(%p)",
-                     static_cast<void*>(m_opaque_sp.get()), filename,
-                     target_triple, platform_name, add_dependent_modules,
-                     sb_error.GetCString(), static_cast<void*>(target_sp.get()));
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  if (log)
+    log->Printf("SBDebugger(%p)::CreateTarget (filename=\"%s\", triple=%s, "
+                "platform_name=%s, add_dependent_modules=%u, error=%s) => "
+                "SBTarget(%p)",
+                static_cast<void *>(m_opaque_sp.get()), filename, target_triple,
+                platform_name, add_dependent_modules, sb_error.GetCString(),
+                static_cast<void *>(target_sp.get()));
 
-    return sb_target;
+  return sb_target;
 }
 
 SBTarget
-SBDebugger::CreateTargetWithFileAndTargetTriple (const char *filename,
-                                                 const char *target_triple)
-{
-    SBTarget sb_target;
-    TargetSP target_sp;
-    if (m_opaque_sp)
-    {
-        const bool add_dependent_modules = true;
-        Error error (m_opaque_sp->GetTargetList().CreateTarget(*m_opaque_sp,
-                                                               filename,
-                                                               target_triple,
-                                                               add_dependent_modules,
-                                                               nullptr,
-                                                               target_sp));
-        sb_target.SetSP (target_sp);
-    }
+SBDebugger::CreateTargetWithFileAndTargetTriple(const char *filename,
+                                                const char *target_triple) {
+  SBTarget sb_target;
+  TargetSP target_sp;
+  if (m_opaque_sp) {
+    const bool add_dependent_modules = true;
+    Error error(m_opaque_sp->GetTargetList().CreateTarget(
+        *m_opaque_sp, filename, target_triple, add_dependent_modules, nullptr,
+        target_sp));
+    sb_target.SetSP(target_sp);
+  }
 
-    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
-    if (log)
-        log->Printf ("SBDebugger(%p)::CreateTargetWithFileAndTargetTriple (filename=\"%s\", triple=%s) => SBTarget(%p)",
-                     static_cast<void*>(m_opaque_sp.get()), filename,
-                     target_triple, static_cast<void*>(target_sp.get()));
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  if (log)
+    log->Printf("SBDebugger(%p)::CreateTargetWithFileAndTargetTriple "
+                "(filename=\"%s\", triple=%s) => SBTarget(%p)",
+                static_cast<void *>(m_opaque_sp.get()), filename, target_triple,
+                static_cast<void *>(target_sp.get()));
 
-    return sb_target;
+  return sb_target;
 }
 
-SBTarget
-SBDebugger::CreateTargetWithFileAndArch (const char *filename, const char *arch_cstr)
-{
-    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+SBTarget SBDebugger::CreateTargetWithFileAndArch(const char *filename,
+                                                 const char *arch_cstr) {
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
 
-    SBTarget sb_target;
-    TargetSP target_sp;
-    if (m_opaque_sp)
-    {
-        Error error;
-        const bool add_dependent_modules = true;
-
-        error = m_opaque_sp->GetTargetList().CreateTarget(*m_opaque_sp,
-                                                          filename,
-                                                          arch_cstr,
-                                                          add_dependent_modules,
-                                                          nullptr,
-                                                          target_sp);
-
-        if (error.Success())
-        {
-            m_opaque_sp->GetTargetList().SetSelectedTarget (target_sp.get());
-            sb_target.SetSP (target_sp);
-        }
-    }
-
-    if (log)
-        log->Printf ("SBDebugger(%p)::CreateTargetWithFileAndArch (filename=\"%s\", arch=%s) => SBTarget(%p)",
-                     static_cast<void*>(m_opaque_sp.get()), filename, arch_cstr,
-                     static_cast<void*>(target_sp.get()));
-
-    return sb_target;
-}
-
-SBTarget
-SBDebugger::CreateTarget (const char *filename)
-{
-    SBTarget sb_target;
-    TargetSP target_sp;
-    if (m_opaque_sp)
-    {
-        Error error;
-        const bool add_dependent_modules = true;
-        error = m_opaque_sp->GetTargetList().CreateTarget(*m_opaque_sp,
-                                                          filename,
-                                                          nullptr,
-                                                          add_dependent_modules,
-                                                          nullptr,
-                                                          target_sp);
-
-        if (error.Success())
-        {
-            m_opaque_sp->GetTargetList().SetSelectedTarget (target_sp.get());
-            sb_target.SetSP (target_sp);
-        }
-    }
-    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
-    if (log)
-        log->Printf ("SBDebugger(%p)::CreateTarget (filename=\"%s\") => SBTarget(%p)",
-                     static_cast<void*>(m_opaque_sp.get()), filename,
-                     static_cast<void*>(target_sp.get()));
-    return sb_target;
-}
-
-bool
-SBDebugger::DeleteTarget (lldb::SBTarget &target)
-{
-    bool result = false;
-    if (m_opaque_sp)
-    {
-        TargetSP target_sp(target.GetSP());
-        if (target_sp)
-        {
-            // No need to lock, the target list is thread safe
-            result = m_opaque_sp->GetTargetList().DeleteTarget (target_sp);
-            target_sp->Destroy();
-            target.Clear();
-            const bool mandatory = true;
-            ModuleList::RemoveOrphanSharedModules(mandatory);
-        }
-    }
-
-    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
-    if (log)
-        log->Printf ("SBDebugger(%p)::DeleteTarget (SBTarget(%p)) => %i",
-                     static_cast<void*>(m_opaque_sp.get()),
-                     static_cast<void*>(target.m_opaque_sp.get()), result);
-
-    return result;
-}
-
-SBTarget
-SBDebugger::GetTargetAtIndex (uint32_t idx)
-{
-    SBTarget sb_target;
-    if (m_opaque_sp)
-    {
-        // No need to lock, the target list is thread safe
-        sb_target.SetSP (m_opaque_sp->GetTargetList().GetTargetAtIndex (idx));
-    }
-    return sb_target;
-}
-
-uint32_t
-SBDebugger::GetIndexOfTarget (lldb::SBTarget target)
-{
-
-    lldb::TargetSP target_sp = target.GetSP();
-    if (!target_sp)
-        return UINT32_MAX;
-
-    if (!m_opaque_sp)
-        return UINT32_MAX;
-
-    return m_opaque_sp->GetTargetList().GetIndexOfTarget (target.GetSP());
-}
-
-SBTarget
-SBDebugger::FindTargetWithProcessID (lldb::pid_t pid)
-{
-    SBTarget sb_target;
-    if (m_opaque_sp)
-    {
-        // No need to lock, the target list is thread safe
-        sb_target.SetSP (m_opaque_sp->GetTargetList().FindTargetWithProcessID (pid));
-    }
-    return sb_target;
-}
-
-SBTarget
-SBDebugger::FindTargetWithFileAndArch (const char *filename, const char *arch_name)
-{
-    SBTarget sb_target;
-    if (m_opaque_sp && filename && filename[0])
-    {
-        // No need to lock, the target list is thread safe
-        ArchSpec arch (arch_name, m_opaque_sp->GetPlatformList().GetSelectedPlatform().get());
-        TargetSP target_sp (m_opaque_sp->GetTargetList().FindTargetWithExecutableAndArchitecture(FileSpec(filename, false), arch_name ? &arch : nullptr));
-        sb_target.SetSP (target_sp);
-    }
-    return sb_target;
-}
-
-SBTarget
-SBDebugger::FindTargetWithLLDBProcess (const ProcessSP &process_sp)
-{
-    SBTarget sb_target;
-    if (m_opaque_sp)
-    {
-        // No need to lock, the target list is thread safe
-        sb_target.SetSP (m_opaque_sp->GetTargetList().FindTargetWithProcess (process_sp.get()));
-    }
-    return sb_target;
-}
-
-uint32_t
-SBDebugger::GetNumTargets ()
-{
-    if (m_opaque_sp)
-    {
-        // No need to lock, the target list is thread safe
-        return m_opaque_sp->GetTargetList().GetNumTargets ();
-    }
-    return 0;
-}
-
-SBTarget
-SBDebugger::GetSelectedTarget ()
-{
-    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
-
-    SBTarget sb_target;
-    TargetSP target_sp;
-    if (m_opaque_sp)
-    {
-        // No need to lock, the target list is thread safe
-        target_sp = m_opaque_sp->GetTargetList().GetSelectedTarget ();
-        sb_target.SetSP (target_sp);
-    }
-
-    if (log)
-    {
-        SBStream sstr;
-        sb_target.GetDescription (sstr, eDescriptionLevelBrief);
-        log->Printf ("SBDebugger(%p)::GetSelectedTarget () => SBTarget(%p): %s",
-                     static_cast<void*>(m_opaque_sp.get()),
-                     static_cast<void*>(target_sp.get()), sstr.GetData());
-    }
-
-    return sb_target;
-}
-
-void
-SBDebugger::SetSelectedTarget (SBTarget &sb_target)
-{
-    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
-
-    TargetSP target_sp (sb_target.GetSP());
-    if (m_opaque_sp)
-    {
-        m_opaque_sp->GetTargetList().SetSelectedTarget (target_sp.get());
-    }
-    if (log)
-    {
-        SBStream sstr;
-        sb_target.GetDescription (sstr, eDescriptionLevelBrief);
-        log->Printf ("SBDebugger(%p)::SetSelectedTarget () => SBTarget(%p): %s",
-                     static_cast<void*>(m_opaque_sp.get()),
-                     static_cast<void*>(target_sp.get()), sstr.GetData());
-    }
-}
-
-SBPlatform
-SBDebugger::GetSelectedPlatform()
-{
-    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
-
-    SBPlatform sb_platform;
-    DebuggerSP debugger_sp(m_opaque_sp);
-    if (debugger_sp)
-    {
-        sb_platform.SetSP(debugger_sp->GetPlatformList().GetSelectedPlatform());
-    }
-    if (log)
-        log->Printf ("SBDebugger(%p)::GetSelectedPlatform () => SBPlatform(%p): %s",
-                     static_cast<void*>(m_opaque_sp.get()),
-                     static_cast<void*>(sb_platform.GetSP().get()),
-                     sb_platform.GetName());
-    return sb_platform;
-}
-
-void
-SBDebugger::SetSelectedPlatform(SBPlatform &sb_platform)
-{
-    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
-
-    DebuggerSP debugger_sp(m_opaque_sp);
-    if (debugger_sp)
-    {
-        debugger_sp->GetPlatformList().SetSelectedPlatform(sb_platform.GetSP());
-    }
-
-    if (log)
-        log->Printf ("SBDebugger(%p)::SetSelectedPlatform (SBPlatform(%p) %s)",
-                     static_cast<void*>(m_opaque_sp.get()),
-                     static_cast<void*>(sb_platform.GetSP().get()),
-                     sb_platform.GetName());
-}
-
-void
-SBDebugger::DispatchInput (void* baton, const void *data, size_t data_len)
-{
-    DispatchInput (data,data_len);
-}
-
-void
-SBDebugger::DispatchInput (const void *data, size_t data_len)
-{
-//    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
-//
-//    if (log)
-//        log->Printf ("SBDebugger(%p)::DispatchInput (data=\"%.*s\", size_t=%" PRIu64 ")",
-//                     m_opaque_sp.get(),
-//                     (int) data_len,
-//                     (const char *) data,
-//                     (uint64_t)data_len);
-//
-//    if (m_opaque_sp)
-//        m_opaque_sp->DispatchInput ((const char *) data, data_len);
-}
-
-void
-SBDebugger::DispatchInputInterrupt ()
-{
-    if (m_opaque_sp)
-        m_opaque_sp->DispatchInputInterrupt ();
-}
-
-void
-SBDebugger::DispatchInputEndOfFile ()
-{
-    if (m_opaque_sp)
-        m_opaque_sp->DispatchInputEndOfFile ();
-}
-
-void
-SBDebugger::PushInputReader (SBInputReader &reader)
-{
-}
-
-void
-SBDebugger::RunCommandInterpreter (bool auto_handle_events,
-                                   bool spawn_thread)
-{
-    if (m_opaque_sp)
-    {
-        CommandInterpreterRunOptions options;
-
-        m_opaque_sp->GetCommandInterpreter().RunCommandInterpreter(auto_handle_events,
-                                                                   spawn_thread,
-                                                                   options);
-    }
-}
-
-void
-SBDebugger::RunCommandInterpreter (bool auto_handle_events,
-                                   bool spawn_thread,
-                                   SBCommandInterpreterRunOptions &options,
-                                   int  &num_errors,
-                                   bool &quit_requested,
-                                   bool &stopped_for_crash)
-
-{
-    if (m_opaque_sp)
-    {
-        CommandInterpreter &interp = m_opaque_sp->GetCommandInterpreter();
-        interp.RunCommandInterpreter(auto_handle_events, spawn_thread, options.ref());
-        num_errors = interp.GetNumErrors();
-        quit_requested = interp.GetQuitRequested();
-        stopped_for_crash = interp.GetStoppedForCrash();
-    }
-}
-
-SBError
-SBDebugger::RunREPL (lldb::LanguageType language, const char *repl_options)
-{
-    SBError error;
-    if (m_opaque_sp)
-        error.ref() = m_opaque_sp->RunREPL(language, repl_options);
-    else
-        error.SetErrorString ("invalid debugger");
-    return error;
-}
-
-void
-SBDebugger::reset (const DebuggerSP &debugger_sp)
-{
-    m_opaque_sp = debugger_sp;
-}
-
-Debugger *
-SBDebugger::get () const
-{
-    return m_opaque_sp.get();
-}
-
-Debugger &
-SBDebugger::ref () const
-{
-    assert (m_opaque_sp.get());
-    return *m_opaque_sp;
-}
-
-const lldb::DebuggerSP &
-SBDebugger::get_sp () const
-{
-    return m_opaque_sp;
-}
-
-SBDebugger
-SBDebugger::FindDebuggerWithID (int id)
-{
-    // No need to lock, the debugger list is thread safe
-    SBDebugger sb_debugger;
-    DebuggerSP debugger_sp = Debugger::FindDebuggerWithID (id);
-    if (debugger_sp)
-        sb_debugger.reset (debugger_sp);
-    return sb_debugger;
-}
-
-const char *
-SBDebugger::GetInstanceName()
-{
-    return (m_opaque_sp ? m_opaque_sp->GetInstanceName().AsCString() : nullptr);
-}
-
-SBError
-SBDebugger::SetInternalVariable (const char *var_name, const char *value, const char *debugger_instance_name)
-{
-    SBError sb_error;
-    DebuggerSP debugger_sp(Debugger::FindDebuggerWithInstanceName (ConstString(debugger_instance_name)));
+  SBTarget sb_target;
+  TargetSP target_sp;
+  if (m_opaque_sp) {
     Error error;
-    if (debugger_sp)
-    {
-        ExecutionContext exe_ctx (debugger_sp->GetCommandInterpreter().GetExecutionContext());
-        error = debugger_sp->SetPropertyValue (&exe_ctx,
-                                               eVarSetOperationAssign,
-                                               var_name,
-                                               value);
+    const bool add_dependent_modules = true;
+
+    error = m_opaque_sp->GetTargetList().CreateTarget(
+        *m_opaque_sp, filename, arch_cstr, add_dependent_modules, nullptr,
+        target_sp);
+
+    if (error.Success()) {
+      m_opaque_sp->GetTargetList().SetSelectedTarget(target_sp.get());
+      sb_target.SetSP(target_sp);
     }
-    else
-    {
-        error.SetErrorStringWithFormat ("invalid debugger instance name '%s'", debugger_instance_name);
+  }
+
+  if (log)
+    log->Printf("SBDebugger(%p)::CreateTargetWithFileAndArch (filename=\"%s\", "
+                "arch=%s) => SBTarget(%p)",
+                static_cast<void *>(m_opaque_sp.get()), filename, arch_cstr,
+                static_cast<void *>(target_sp.get()));
+
+  return sb_target;
+}
+
+SBTarget SBDebugger::CreateTarget(const char *filename) {
+  SBTarget sb_target;
+  TargetSP target_sp;
+  if (m_opaque_sp) {
+    Error error;
+    const bool add_dependent_modules = true;
+    error = m_opaque_sp->GetTargetList().CreateTarget(
+        *m_opaque_sp, filename, nullptr, add_dependent_modules, nullptr,
+        target_sp);
+
+    if (error.Success()) {
+      m_opaque_sp->GetTargetList().SetSelectedTarget(target_sp.get());
+      sb_target.SetSP(target_sp);
     }
-    if (error.Fail())
-        sb_error.SetError(error);
-    return sb_error;
+  }
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  if (log)
+    log->Printf(
+        "SBDebugger(%p)::CreateTarget (filename=\"%s\") => SBTarget(%p)",
+        static_cast<void *>(m_opaque_sp.get()), filename,
+        static_cast<void *>(target_sp.get()));
+  return sb_target;
+}
+
+bool SBDebugger::DeleteTarget(lldb::SBTarget &target) {
+  bool result = false;
+  if (m_opaque_sp) {
+    TargetSP target_sp(target.GetSP());
+    if (target_sp) {
+      // No need to lock, the target list is thread safe
+      result = m_opaque_sp->GetTargetList().DeleteTarget(target_sp);
+      target_sp->Destroy();
+      target.Clear();
+      const bool mandatory = true;
+      ModuleList::RemoveOrphanSharedModules(mandatory);
+    }
+  }
+
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  if (log)
+    log->Printf("SBDebugger(%p)::DeleteTarget (SBTarget(%p)) => %i",
+                static_cast<void *>(m_opaque_sp.get()),
+                static_cast<void *>(target.m_opaque_sp.get()), result);
+
+  return result;
+}
+
+SBTarget SBDebugger::GetTargetAtIndex(uint32_t idx) {
+  SBTarget sb_target;
+  if (m_opaque_sp) {
+    // No need to lock, the target list is thread safe
+    sb_target.SetSP(m_opaque_sp->GetTargetList().GetTargetAtIndex(idx));
+  }
+  return sb_target;
+}
+
+uint32_t SBDebugger::GetIndexOfTarget(lldb::SBTarget target) {
+
+  lldb::TargetSP target_sp = target.GetSP();
+  if (!target_sp)
+    return UINT32_MAX;
+
+  if (!m_opaque_sp)
+    return UINT32_MAX;
+
+  return m_opaque_sp->GetTargetList().GetIndexOfTarget(target.GetSP());
+}
+
+SBTarget SBDebugger::FindTargetWithProcessID(lldb::pid_t pid) {
+  SBTarget sb_target;
+  if (m_opaque_sp) {
+    // No need to lock, the target list is thread safe
+    sb_target.SetSP(m_opaque_sp->GetTargetList().FindTargetWithProcessID(pid));
+  }
+  return sb_target;
+}
+
+SBTarget SBDebugger::FindTargetWithFileAndArch(const char *filename,
+                                               const char *arch_name) {
+  SBTarget sb_target;
+  if (m_opaque_sp && filename && filename[0]) {
+    // No need to lock, the target list is thread safe
+    ArchSpec arch(arch_name,
+                  m_opaque_sp->GetPlatformList().GetSelectedPlatform().get());
+    TargetSP target_sp(
+        m_opaque_sp->GetTargetList().FindTargetWithExecutableAndArchitecture(
+            FileSpec(filename, false), arch_name ? &arch : nullptr));
+    sb_target.SetSP(target_sp);
+  }
+  return sb_target;
+}
+
+SBTarget SBDebugger::FindTargetWithLLDBProcess(const ProcessSP &process_sp) {
+  SBTarget sb_target;
+  if (m_opaque_sp) {
+    // No need to lock, the target list is thread safe
+    sb_target.SetSP(
+        m_opaque_sp->GetTargetList().FindTargetWithProcess(process_sp.get()));
+  }
+  return sb_target;
+}
+
+uint32_t SBDebugger::GetNumTargets() {
+  if (m_opaque_sp) {
+    // No need to lock, the target list is thread safe
+    return m_opaque_sp->GetTargetList().GetNumTargets();
+  }
+  return 0;
+}
+
+SBTarget SBDebugger::GetSelectedTarget() {
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+  SBTarget sb_target;
+  TargetSP target_sp;
+  if (m_opaque_sp) {
+    // No need to lock, the target list is thread safe
+    target_sp = m_opaque_sp->GetTargetList().GetSelectedTarget();
+    sb_target.SetSP(target_sp);
+  }
+
+  if (log) {
+    SBStream sstr;
+    sb_target.GetDescription(sstr, eDescriptionLevelBrief);
+    log->Printf("SBDebugger(%p)::GetSelectedTarget () => SBTarget(%p): %s",
+                static_cast<void *>(m_opaque_sp.get()),
+                static_cast<void *>(target_sp.get()), sstr.GetData());
+  }
+
+  return sb_target;
+}
+
+void SBDebugger::SetSelectedTarget(SBTarget &sb_target) {
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+  TargetSP target_sp(sb_target.GetSP());
+  if (m_opaque_sp) {
+    m_opaque_sp->GetTargetList().SetSelectedTarget(target_sp.get());
+  }
+  if (log) {
+    SBStream sstr;
+    sb_target.GetDescription(sstr, eDescriptionLevelBrief);
+    log->Printf("SBDebugger(%p)::SetSelectedTarget () => SBTarget(%p): %s",
+                static_cast<void *>(m_opaque_sp.get()),
+                static_cast<void *>(target_sp.get()), sstr.GetData());
+  }
+}
+
+SBPlatform SBDebugger::GetSelectedPlatform() {
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+  SBPlatform sb_platform;
+  DebuggerSP debugger_sp(m_opaque_sp);
+  if (debugger_sp) {
+    sb_platform.SetSP(debugger_sp->GetPlatformList().GetSelectedPlatform());
+  }
+  if (log)
+    log->Printf("SBDebugger(%p)::GetSelectedPlatform () => SBPlatform(%p): %s",
+                static_cast<void *>(m_opaque_sp.get()),
+                static_cast<void *>(sb_platform.GetSP().get()),
+                sb_platform.GetName());
+  return sb_platform;
+}
+
+void SBDebugger::SetSelectedPlatform(SBPlatform &sb_platform) {
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+  DebuggerSP debugger_sp(m_opaque_sp);
+  if (debugger_sp) {
+    debugger_sp->GetPlatformList().SetSelectedPlatform(sb_platform.GetSP());
+  }
+
+  if (log)
+    log->Printf("SBDebugger(%p)::SetSelectedPlatform (SBPlatform(%p) %s)",
+                static_cast<void *>(m_opaque_sp.get()),
+                static_cast<void *>(sb_platform.GetSP().get()),
+                sb_platform.GetName());
+}
+
+void SBDebugger::DispatchInput(void *baton, const void *data, size_t data_len) {
+  DispatchInput(data, data_len);
+}
+
+void SBDebugger::DispatchInput(const void *data, size_t data_len) {
+  //    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+  //
+  //    if (log)
+  //        log->Printf ("SBDebugger(%p)::DispatchInput (data=\"%.*s\",
+  //        size_t=%" PRIu64 ")",
+  //                     m_opaque_sp.get(),
+  //                     (int) data_len,
+  //                     (const char *) data,
+  //                     (uint64_t)data_len);
+  //
+  //    if (m_opaque_sp)
+  //        m_opaque_sp->DispatchInput ((const char *) data, data_len);
+}
+
+void SBDebugger::DispatchInputInterrupt() {
+  if (m_opaque_sp)
+    m_opaque_sp->DispatchInputInterrupt();
+}
+
+void SBDebugger::DispatchInputEndOfFile() {
+  if (m_opaque_sp)
+    m_opaque_sp->DispatchInputEndOfFile();
+}
+
+void SBDebugger::PushInputReader(SBInputReader &reader) {}
+
+void SBDebugger::RunCommandInterpreter(bool auto_handle_events,
+                                       bool spawn_thread) {
+  if (m_opaque_sp) {
+    CommandInterpreterRunOptions options;
+
+    m_opaque_sp->GetCommandInterpreter().RunCommandInterpreter(
+        auto_handle_events, spawn_thread, options);
+  }
+}
+
+void SBDebugger::RunCommandInterpreter(bool auto_handle_events,
+                                       bool spawn_thread,
+                                       SBCommandInterpreterRunOptions &options,
+                                       int &num_errors, bool &quit_requested,
+                                       bool &stopped_for_crash)
+
+{
+  if (m_opaque_sp) {
+    CommandInterpreter &interp = m_opaque_sp->GetCommandInterpreter();
+    interp.RunCommandInterpreter(auto_handle_events, spawn_thread,
+                                 options.ref());
+    num_errors = interp.GetNumErrors();
+    quit_requested = interp.GetQuitRequested();
+    stopped_for_crash = interp.GetStoppedForCrash();
+  }
+}
+
+SBError SBDebugger::RunREPL(lldb::LanguageType language,
+                            const char *repl_options) {
+  SBError error;
+  if (m_opaque_sp)
+    error.ref() = m_opaque_sp->RunREPL(language, repl_options);
+  else
+    error.SetErrorString("invalid debugger");
+  return error;
+}
+
+void SBDebugger::reset(const DebuggerSP &debugger_sp) {
+  m_opaque_sp = debugger_sp;
+}
+
+Debugger *SBDebugger::get() const { return m_opaque_sp.get(); }
+
+Debugger &SBDebugger::ref() const {
+  assert(m_opaque_sp.get());
+  return *m_opaque_sp;
+}
+
+const lldb::DebuggerSP &SBDebugger::get_sp() const { return m_opaque_sp; }
+
+SBDebugger SBDebugger::FindDebuggerWithID(int id) {
+  // No need to lock, the debugger list is thread safe
+  SBDebugger sb_debugger;
+  DebuggerSP debugger_sp = Debugger::FindDebuggerWithID(id);
+  if (debugger_sp)
+    sb_debugger.reset(debugger_sp);
+  return sb_debugger;
+}
+
+const char *SBDebugger::GetInstanceName() {
+  return (m_opaque_sp ? m_opaque_sp->GetInstanceName().AsCString() : nullptr);
+}
+
+SBError SBDebugger::SetInternalVariable(const char *var_name, const char *value,
+                                        const char *debugger_instance_name) {
+  SBError sb_error;
+  DebuggerSP debugger_sp(Debugger::FindDebuggerWithInstanceName(
+      ConstString(debugger_instance_name)));
+  Error error;
+  if (debugger_sp) {
+    ExecutionContext exe_ctx(
+        debugger_sp->GetCommandInterpreter().GetExecutionContext());
+    error = debugger_sp->SetPropertyValue(&exe_ctx, eVarSetOperationAssign,
+                                          var_name, value);
+  } else {
+    error.SetErrorStringWithFormat("invalid debugger instance name '%s'",
+                                   debugger_instance_name);
+  }
+  if (error.Fail())
+    sb_error.SetError(error);
+  return sb_error;
 }
 
 SBStringList
-SBDebugger::GetInternalVariableValue (const char *var_name, const char *debugger_instance_name)
-{
-    SBStringList ret_value;
-    DebuggerSP debugger_sp(Debugger::FindDebuggerWithInstanceName (ConstString(debugger_instance_name)));
-    Error error;
-    if (debugger_sp)
-    {
-        ExecutionContext exe_ctx (debugger_sp->GetCommandInterpreter().GetExecutionContext());
-        lldb::OptionValueSP value_sp (debugger_sp->GetPropertyValue (&exe_ctx,
-                                                                     var_name,
-                                                                     false,
-                                                                     error));
-        if (value_sp)
-        {
-            StreamString value_strm;
-            value_sp->DumpValue (&exe_ctx, value_strm, OptionValue::eDumpOptionValue);
-            const std::string &value_str = value_strm.GetString();
-            if (!value_str.empty())
-            {
-                StringList string_list;
-                string_list.SplitIntoLines(value_str);
-                return SBStringList(&string_list);
-            }
+SBDebugger::GetInternalVariableValue(const char *var_name,
+                                     const char *debugger_instance_name) {
+  SBStringList ret_value;
+  DebuggerSP debugger_sp(Debugger::FindDebuggerWithInstanceName(
+      ConstString(debugger_instance_name)));
+  Error error;
+  if (debugger_sp) {
+    ExecutionContext exe_ctx(
+        debugger_sp->GetCommandInterpreter().GetExecutionContext());
+    lldb::OptionValueSP value_sp(
+        debugger_sp->GetPropertyValue(&exe_ctx, var_name, false, error));
+    if (value_sp) {
+      StreamString value_strm;
+      value_sp->DumpValue(&exe_ctx, value_strm, OptionValue::eDumpOptionValue);
+      const std::string &value_str = value_strm.GetString();
+      if (!value_str.empty()) {
+        StringList string_list;
+        string_list.SplitIntoLines(value_str);
+        return SBStringList(&string_list);
+      }
+    }
+  }
+  return SBStringList();
+}
+
+uint32_t SBDebugger::GetTerminalWidth() const {
+  return (m_opaque_sp ? m_opaque_sp->GetTerminalWidth() : 0);
+}
+
+void SBDebugger::SetTerminalWidth(uint32_t term_width) {
+  if (m_opaque_sp)
+    m_opaque_sp->SetTerminalWidth(term_width);
+}
+
+const char *SBDebugger::GetPrompt() const {
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+  if (log)
+    log->Printf("SBDebugger(%p)::GetPrompt () => \"%s\"",
+                static_cast<void *>(m_opaque_sp.get()),
+                (m_opaque_sp ? m_opaque_sp->GetPrompt() : ""));
+
+  return (m_opaque_sp ? m_opaque_sp->GetPrompt() : nullptr);
+}
+
+void SBDebugger::SetPrompt(const char *prompt) {
+  if (m_opaque_sp)
+    m_opaque_sp->SetPrompt(prompt);
+}
+
+ScriptLanguage SBDebugger::GetScriptLanguage() const {
+  return (m_opaque_sp ? m_opaque_sp->GetScriptLanguage() : eScriptLanguageNone);
+}
+
+void SBDebugger::SetScriptLanguage(ScriptLanguage script_lang) {
+  if (m_opaque_sp) {
+    m_opaque_sp->SetScriptLanguage(script_lang);
+  }
+}
+
+bool SBDebugger::SetUseExternalEditor(bool value) {
+  return (m_opaque_sp ? m_opaque_sp->SetUseExternalEditor(value) : false);
+}
+
+bool SBDebugger::GetUseExternalEditor() {
+  return (m_opaque_sp ? m_opaque_sp->GetUseExternalEditor() : false);
+}
+
+bool SBDebugger::SetUseColor(bool value) {
+  return (m_opaque_sp ? m_opaque_sp->SetUseColor(value) : false);
+}
+
+bool SBDebugger::GetUseColor() const {
+  return (m_opaque_sp ? m_opaque_sp->GetUseColor() : false);
+}
+
+bool SBDebugger::GetDescription(SBStream &description) {
+  Stream &strm = description.ref();
+
+  if (m_opaque_sp) {
+    const char *name = m_opaque_sp->GetInstanceName().AsCString();
+    user_id_t id = m_opaque_sp->GetID();
+    strm.Printf("Debugger (instance: \"%s\", id: %" PRIu64 ")", name, id);
+  } else
+    strm.PutCString("No value");
+
+  return true;
+}
+
+user_id_t SBDebugger::GetID() {
+  return (m_opaque_sp ? m_opaque_sp->GetID() : LLDB_INVALID_UID);
+}
+
+SBError SBDebugger::SetCurrentPlatform(const char *platform_name_cstr) {
+  SBError sb_error;
+  if (m_opaque_sp) {
+    if (platform_name_cstr && platform_name_cstr[0]) {
+      ConstString platform_name(platform_name_cstr);
+      PlatformSP platform_sp(Platform::Find(platform_name));
+
+      if (platform_sp) {
+        // Already have a platform with this name, just select it
+        m_opaque_sp->GetPlatformList().SetSelectedPlatform(platform_sp);
+      } else {
+        // We don't have a platform by this name yet, create one
+        platform_sp = Platform::Create(platform_name, sb_error.ref());
+        if (platform_sp) {
+          // We created the platform, now append and select it
+          bool make_selected = true;
+          m_opaque_sp->GetPlatformList().Append(platform_sp, make_selected);
         }
+      }
+    } else {
+      sb_error.ref().SetErrorString("invalid platform name");
     }
-    return SBStringList();
+  } else {
+    sb_error.ref().SetErrorString("invalid debugger");
+  }
+  return sb_error;
 }
 
-uint32_t
-SBDebugger::GetTerminalWidth() const
-{
-    return (m_opaque_sp ? m_opaque_sp->GetTerminalWidth() : 0);
-}
+bool SBDebugger::SetCurrentPlatformSDKRoot(const char *sysroot) {
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  if (m_opaque_sp) {
+    PlatformSP platform_sp(
+        m_opaque_sp->GetPlatformList().GetSelectedPlatform());
 
-void
-SBDebugger::SetTerminalWidth (uint32_t term_width)
-{
-    if (m_opaque_sp)
-        m_opaque_sp->SetTerminalWidth (term_width);
-}
-
-const char *
-SBDebugger::GetPrompt() const
-{
-    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
-
-    if (log)
-        log->Printf ("SBDebugger(%p)::GetPrompt () => \"%s\"",
-                     static_cast<void*>(m_opaque_sp.get()),
-                     (m_opaque_sp ? m_opaque_sp->GetPrompt() : ""));
-
-    return (m_opaque_sp ? m_opaque_sp->GetPrompt() : nullptr);
-}
-
-void
-SBDebugger::SetPrompt (const char *prompt)
-{
-    if (m_opaque_sp)
-        m_opaque_sp->SetPrompt (prompt);
-}
-    
-ScriptLanguage 
-SBDebugger::GetScriptLanguage() const
-{
-    return (m_opaque_sp ? m_opaque_sp->GetScriptLanguage() : eScriptLanguageNone);
-}
-
-void
-SBDebugger::SetScriptLanguage (ScriptLanguage script_lang)
-{
-    if (m_opaque_sp)
-    {
-        m_opaque_sp->SetScriptLanguage (script_lang);
+    if (platform_sp) {
+      if (log && sysroot)
+        log->Printf("SBDebugger::SetCurrentPlatformSDKRoot (\"%s\")", sysroot);
+      platform_sp->SetSDKRootDirectory(ConstString(sysroot));
+      return true;
     }
+  }
+  return false;
 }
 
-bool
-SBDebugger::SetUseExternalEditor(bool value)
-{
-    return (m_opaque_sp ? m_opaque_sp->SetUseExternalEditor(value) : false);
+bool SBDebugger::GetCloseInputOnEOF() const {
+  return (m_opaque_sp ? m_opaque_sp->GetCloseInputOnEOF() : false);
 }
 
-bool
-SBDebugger::GetUseExternalEditor()
-{
-    return (m_opaque_sp ? m_opaque_sp->GetUseExternalEditor() : false);
+void SBDebugger::SetCloseInputOnEOF(bool b) {
+  if (m_opaque_sp)
+    m_opaque_sp->SetCloseInputOnEOF(b);
 }
 
-bool
-SBDebugger::SetUseColor(bool value)
-{
-    return (m_opaque_sp ? m_opaque_sp->SetUseColor(value) : false);
+SBTypeCategory SBDebugger::GetCategory(const char *category_name) {
+  if (!category_name || *category_name == 0)
+    return SBTypeCategory();
+
+  TypeCategoryImplSP category_sp;
+
+  if (DataVisualization::Categories::GetCategory(ConstString(category_name),
+                                                 category_sp, false))
+    return SBTypeCategory(category_sp);
+  else
+    return SBTypeCategory();
 }
 
-bool
-SBDebugger::GetUseColor() const
-{
-    return (m_opaque_sp ? m_opaque_sp->GetUseColor() : false);
+SBTypeCategory SBDebugger::GetCategory(lldb::LanguageType lang_type) {
+  TypeCategoryImplSP category_sp;
+  if (DataVisualization::Categories::GetCategory(lang_type, category_sp))
+    return SBTypeCategory(category_sp);
+  else
+    return SBTypeCategory();
 }
 
-bool
-SBDebugger::GetDescription (SBStream &description)
-{
-    Stream &strm = description.ref();
+SBTypeCategory SBDebugger::CreateCategory(const char *category_name) {
+  if (!category_name || *category_name == 0)
+    return SBTypeCategory();
 
-    if (m_opaque_sp)
-    {
-        const char *name = m_opaque_sp->GetInstanceName().AsCString();
-        user_id_t id = m_opaque_sp->GetID();
-        strm.Printf ("Debugger (instance: \"%s\", id: %" PRIu64 ")", name, id);
-    }
-    else
-        strm.PutCString ("No value");
-    
-    return true;
+  TypeCategoryImplSP category_sp;
+
+  if (DataVisualization::Categories::GetCategory(ConstString(category_name),
+                                                 category_sp, true))
+    return SBTypeCategory(category_sp);
+  else
+    return SBTypeCategory();
 }
 
-user_id_t
-SBDebugger::GetID()
-{
-    return (m_opaque_sp ? m_opaque_sp->GetID() : LLDB_INVALID_UID);
+bool SBDebugger::DeleteCategory(const char *category_name) {
+  if (!category_name || *category_name == 0)
+    return false;
+
+  return DataVisualization::Categories::Delete(ConstString(category_name));
 }
 
-SBError
-SBDebugger::SetCurrentPlatform (const char *platform_name_cstr)
-{
-    SBError sb_error;
-    if (m_opaque_sp)
-    {
-        if (platform_name_cstr && platform_name_cstr[0])
-        {
-            ConstString platform_name (platform_name_cstr);
-            PlatformSP platform_sp (Platform::Find (platform_name));
-
-            if (platform_sp)
-            {
-                // Already have a platform with this name, just select it
-                m_opaque_sp->GetPlatformList().SetSelectedPlatform(platform_sp);
-            }
-            else
-            {
-                // We don't have a platform by this name yet, create one
-                platform_sp = Platform::Create (platform_name, sb_error.ref());
-                if (platform_sp)
-                {
-                    // We created the platform, now append and select it
-                    bool make_selected = true;
-                    m_opaque_sp->GetPlatformList().Append (platform_sp, make_selected);
-                }
-            }
-        }
-        else
-        {
-            sb_error.ref().SetErrorString("invalid platform name");
-        }
-    }
-    else
-    {
-        sb_error.ref().SetErrorString("invalid debugger");
-    }
-    return sb_error;
+uint32_t SBDebugger::GetNumCategories() {
+  return DataVisualization::Categories::GetCount();
 }
 
-bool
-SBDebugger::SetCurrentPlatformSDKRoot (const char *sysroot)
-{
-    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
-    if (m_opaque_sp)
-    {
-        PlatformSP platform_sp (m_opaque_sp->GetPlatformList().GetSelectedPlatform());
-        
-        if (platform_sp)
-        {
-            if (log && sysroot)
-                log->Printf ("SBDebugger::SetCurrentPlatformSDKRoot (\"%s\")", sysroot);
-            platform_sp->SetSDKRootDirectory (ConstString (sysroot));
-            return true;
-        }
-    }
+SBTypeCategory SBDebugger::GetCategoryAtIndex(uint32_t index) {
+  return SBTypeCategory(
+      DataVisualization::Categories::GetCategoryAtIndex(index));
+}
+
+SBTypeCategory SBDebugger::GetDefaultCategory() {
+  return GetCategory("default");
+}
+
+SBTypeFormat SBDebugger::GetFormatForType(SBTypeNameSpecifier type_name) {
+  SBTypeCategory default_category_sb = GetDefaultCategory();
+  if (default_category_sb.GetEnabled())
+    return default_category_sb.GetFormatForType(type_name);
+  return SBTypeFormat();
+}
+
+#ifndef LLDB_DISABLE_PYTHON
+SBTypeSummary SBDebugger::GetSummaryForType(SBTypeNameSpecifier type_name) {
+  if (!type_name.IsValid())
+    return SBTypeSummary();
+  return SBTypeSummary(DataVisualization::GetSummaryForType(type_name.GetSP()));
+}
+#endif // LLDB_DISABLE_PYTHON
+
+SBTypeFilter SBDebugger::GetFilterForType(SBTypeNameSpecifier type_name) {
+  if (!type_name.IsValid())
+    return SBTypeFilter();
+  return SBTypeFilter(DataVisualization::GetFilterForType(type_name.GetSP()));
+}
+
+#ifndef LLDB_DISABLE_PYTHON
+SBTypeSynthetic SBDebugger::GetSyntheticForType(SBTypeNameSpecifier type_name) {
+  if (!type_name.IsValid())
+    return SBTypeSynthetic();
+  return SBTypeSynthetic(
+      DataVisualization::GetSyntheticForType(type_name.GetSP()));
+}
+#endif // LLDB_DISABLE_PYTHON
+
+bool SBDebugger::EnableLog(const char *channel, const char **categories) {
+  if (m_opaque_sp) {
+    uint32_t log_options =
+        LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
+    StreamString errors;
+    return m_opaque_sp->EnableLog(channel, categories, nullptr, log_options,
+                                  errors);
+  } else
     return false;
 }
 
-bool
-SBDebugger::GetCloseInputOnEOF() const
-{
-    return (m_opaque_sp ? m_opaque_sp->GetCloseInputOnEOF() : false);
-}
-
-void
-SBDebugger::SetCloseInputOnEOF (bool b)
-{
-    if (m_opaque_sp)
-        m_opaque_sp->SetCloseInputOnEOF (b);
-}
-
-SBTypeCategory
-SBDebugger::GetCategory (const char* category_name)
-{
-    if (!category_name || *category_name == 0)
-        return SBTypeCategory();
-    
-    TypeCategoryImplSP category_sp;
-    
-    if (DataVisualization::Categories::GetCategory(ConstString(category_name), category_sp, false))
-        return SBTypeCategory(category_sp);
-    else
-        return SBTypeCategory();
-}
-
-SBTypeCategory
-SBDebugger::GetCategory (lldb::LanguageType lang_type)
-{
-    TypeCategoryImplSP category_sp;
-    if (DataVisualization::Categories::GetCategory(lang_type, category_sp))
-        return SBTypeCategory(category_sp);
-    else
-        return SBTypeCategory();
-}
-
-SBTypeCategory
-SBDebugger::CreateCategory (const char* category_name)
-{
-    if (!category_name || *category_name == 0)
-        return SBTypeCategory();
-    
-    TypeCategoryImplSP category_sp;
-    
-    if (DataVisualization::Categories::GetCategory(ConstString(category_name), category_sp, true))
-        return SBTypeCategory(category_sp);
-    else
-        return SBTypeCategory();
-}
-
-bool
-SBDebugger::DeleteCategory (const char* category_name)
-{
-    if (!category_name || *category_name == 0)
-        return false;
-    
-    return DataVisualization::Categories::Delete(ConstString(category_name));
-}
-
-uint32_t
-SBDebugger::GetNumCategories()
-{
-    return DataVisualization::Categories::GetCount();
-}
-
-SBTypeCategory
-SBDebugger::GetCategoryAtIndex (uint32_t index)
-{
-    return SBTypeCategory(DataVisualization::Categories::GetCategoryAtIndex(index));
-}
-
-SBTypeCategory
-SBDebugger::GetDefaultCategory()
-{
-    return GetCategory("default");
-}
-
-SBTypeFormat
-SBDebugger::GetFormatForType (SBTypeNameSpecifier type_name)
-{
-    SBTypeCategory default_category_sb = GetDefaultCategory();
-    if (default_category_sb.GetEnabled())
-        return default_category_sb.GetFormatForType(type_name);
-    return SBTypeFormat();
-}
-
-#ifndef LLDB_DISABLE_PYTHON
-SBTypeSummary
-SBDebugger::GetSummaryForType (SBTypeNameSpecifier type_name)
-{
-    if (!type_name.IsValid())
-        return SBTypeSummary();
-    return SBTypeSummary(DataVisualization::GetSummaryForType(type_name.GetSP()));
-}
-#endif // LLDB_DISABLE_PYTHON
-
-SBTypeFilter
-SBDebugger::GetFilterForType (SBTypeNameSpecifier type_name)
-{
-    if (!type_name.IsValid())
-        return SBTypeFilter();
-    return SBTypeFilter(DataVisualization::GetFilterForType(type_name.GetSP()));
-}
-
-#ifndef LLDB_DISABLE_PYTHON
-SBTypeSynthetic
-SBDebugger::GetSyntheticForType (SBTypeNameSpecifier type_name)
-{
-    if (!type_name.IsValid())
-        return SBTypeSynthetic();
-    return SBTypeSynthetic(DataVisualization::GetSyntheticForType(type_name.GetSP()));
-}
-#endif // LLDB_DISABLE_PYTHON
-
-bool
-SBDebugger::EnableLog (const char *channel, const char **categories)
-{
-    if (m_opaque_sp)
-    {
-        uint32_t log_options = LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
-        StreamString errors;
-        return m_opaque_sp->EnableLog(channel, categories, nullptr, log_options, errors);
-    }
-    else
-        return false;
-}
-
-void
-SBDebugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton)
-{
-    if (m_opaque_sp)
-    {
-        return m_opaque_sp->SetLoggingCallback (log_callback, baton);
-    }
+void SBDebugger::SetLoggingCallback(lldb::LogOutputCallback log_callback,
+                                    void *baton) {
+  if (m_opaque_sp) {
+    return m_opaque_sp->SetLoggingCallback(log_callback, baton);
+  }
 }
