//===-- ScriptInterpreterPython.cpp -----------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// In order to guarantee correct working with Python, Python.h *MUST* be
// the *FIRST* header file included here.
#ifdef LLDB_DISABLE_PYTHON

// Python is disabled in this build

#else

#include "lldb/lldb-python.h"
#include "lldb/Interpreter/ScriptInterpreterPython.h"

#include <stdlib.h>
#include <stdio.h>

#include <string>

#include "lldb/API/SBValue.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Breakpoint/WatchpointOptions.h"
#include "lldb/Core/Communication.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Timer.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/DataFormatters/TypeSummary.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/Pipe.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/PythonDataObjects.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"

#if defined(_WIN32)
#include "lldb/Host/windows/ConnectionGenericFileWindows.h"
#endif

using namespace lldb;
using namespace lldb_private;


static ScriptInterpreter::SWIGInitCallback g_swig_init_callback = nullptr;
static ScriptInterpreter::SWIGBreakpointCallbackFunction g_swig_breakpoint_callback = nullptr;
static ScriptInterpreter::SWIGWatchpointCallbackFunction g_swig_watchpoint_callback = nullptr;
static ScriptInterpreter::SWIGPythonTypeScriptCallbackFunction g_swig_typescript_callback = nullptr;
static ScriptInterpreter::SWIGPythonCreateSyntheticProvider g_swig_synthetic_script = nullptr;
static ScriptInterpreter::SWIGPythonCreateCommandObject g_swig_create_cmd = nullptr;
static ScriptInterpreter::SWIGPythonCalculateNumChildren g_swig_calc_children = nullptr;
static ScriptInterpreter::SWIGPythonGetChildAtIndex g_swig_get_child_index = nullptr;
static ScriptInterpreter::SWIGPythonGetIndexOfChildWithName g_swig_get_index_child = nullptr;
static ScriptInterpreter::SWIGPythonCastPyObjectToSBValue g_swig_cast_to_sbvalue  = nullptr;
static ScriptInterpreter::SWIGPythonGetValueObjectSPFromSBValue g_swig_get_valobj_sp_from_sbvalue = nullptr;
static ScriptInterpreter::SWIGPythonUpdateSynthProviderInstance g_swig_update_provider = nullptr;
static ScriptInterpreter::SWIGPythonMightHaveChildrenSynthProviderInstance g_swig_mighthavechildren_provider = nullptr;
static ScriptInterpreter::SWIGPythonGetValueSynthProviderInstance g_swig_getvalue_provider = nullptr;
static ScriptInterpreter::SWIGPythonCallCommand g_swig_call_command = nullptr;
static ScriptInterpreter::SWIGPythonCallCommandObject g_swig_call_command_object = nullptr;
static ScriptInterpreter::SWIGPythonCallModuleInit g_swig_call_module_init = nullptr;
static ScriptInterpreter::SWIGPythonCreateOSPlugin g_swig_create_os_plugin = nullptr;
static ScriptInterpreter::SWIGPythonScriptKeyword_Process g_swig_run_script_keyword_process = nullptr;
static ScriptInterpreter::SWIGPythonScriptKeyword_Thread g_swig_run_script_keyword_thread = nullptr;
static ScriptInterpreter::SWIGPythonScriptKeyword_Target g_swig_run_script_keyword_target = nullptr;
static ScriptInterpreter::SWIGPythonScriptKeyword_Frame g_swig_run_script_keyword_frame = nullptr;
static ScriptInterpreter::SWIGPythonScriptKeyword_Value g_swig_run_script_keyword_value = nullptr;
static ScriptInterpreter::SWIGPython_GetDynamicSetting g_swig_plugin_get = nullptr;
static ScriptInterpreter::SWIGPythonCreateScriptedThreadPlan g_swig_thread_plan_script = nullptr;
static ScriptInterpreter::SWIGPythonCallThreadPlan g_swig_call_thread_plan = nullptr;

static std::string
ReadPythonBacktrace (PyObject* py_backtrace);

ScriptInterpreterPython::Locker::Locker (ScriptInterpreterPython *py_interpreter,
                                         uint16_t on_entry,
                                         uint16_t on_leave,
                                         FILE *in,
                                         FILE *out,
                                         FILE *err) :
    ScriptInterpreterLocker (),
    m_teardown_session( (on_leave & TearDownSession) == TearDownSession ),
    m_python_interpreter(py_interpreter)
{
    DoAcquireLock();
    if ((on_entry & InitSession) == InitSession)
    {
        if (DoInitSession(on_entry, in, out, err) == false)
        {
            // Don't teardown the session if we didn't init it.
            m_teardown_session = false;
        }
    }
}

bool
ScriptInterpreterPython::Locker::DoAcquireLock()
{
    Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT | LIBLLDB_LOG_VERBOSE));
    m_GILState = PyGILState_Ensure();
    if (log)
        log->Printf("Ensured PyGILState. Previous state = %slocked\n", m_GILState == PyGILState_UNLOCKED ? "un" : "");

    // we need to save the thread state when we first start the command
    // because we might decide to interrupt it while some action is taking
    // place outside of Python (e.g. printing to screen, waiting for the network, ...)
    // in that case, _PyThreadState_Current will be NULL - and we would be unable
    // to set the asynchronous exception - not a desirable situation
    m_python_interpreter->SetThreadState (_PyThreadState_Current);
    m_python_interpreter->IncrementLockCount();
    return true;
}

bool
ScriptInterpreterPython::Locker::DoInitSession(uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err)
{
    if (!m_python_interpreter)
        return false;
    return m_python_interpreter->EnterSession (on_entry_flags, in, out, err);
}

bool
ScriptInterpreterPython::Locker::DoFreeLock()
{
    Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT | LIBLLDB_LOG_VERBOSE));
    if (log)
        log->Printf("Releasing PyGILState. Returning to state = %slocked\n", m_GILState == PyGILState_UNLOCKED ? "un" : "");
    PyGILState_Release(m_GILState);
    m_python_interpreter->DecrementLockCount();
    return true;
}

bool
ScriptInterpreterPython::Locker::DoTearDownSession()
{
    if (!m_python_interpreter)
        return false;
    m_python_interpreter->LeaveSession ();
    return true;
}

ScriptInterpreterPython::Locker::~Locker()
{
    if (m_teardown_session)
        DoTearDownSession();
    DoFreeLock();
}


ScriptInterpreterPython::ScriptInterpreterPython (CommandInterpreter &interpreter) :
    ScriptInterpreter (interpreter, eScriptLanguagePython),
    IOHandlerDelegateMultiline("DONE"),
    m_saved_stdin (),
    m_saved_stdout (),
    m_saved_stderr (),
    m_main_module (),
    m_lldb_module (),
    m_session_dict (false),     // Don't create an empty dictionary, leave it invalid
    m_sys_module_dict (false),  // Don't create an empty dictionary, leave it invalid
    m_run_one_line_function (),
    m_run_one_line_str_global (),
    m_dictionary_name (interpreter.GetDebugger().GetInstanceName().AsCString()),
    m_terminal_state (),
    m_active_io_handler (eIOHandlerNone),
    m_session_is_active (false),
    m_pty_slave_is_open (false),
    m_valid_session (true),
    m_lock_count (0),
    m_command_thread_state (nullptr)
{

    ScriptInterpreterPython::InitializePrivate ();

    m_dictionary_name.append("_dict");
    StreamString run_string;
    run_string.Printf ("%s = dict()", m_dictionary_name.c_str());

    Locker locker(this,
                  ScriptInterpreterPython::Locker::AcquireLock,
                  ScriptInterpreterPython::Locker::FreeAcquiredLock);
    PyRun_SimpleString (run_string.GetData());

    run_string.Clear();

    // Importing 'lldb' module calls SBDebugger::Initialize, which calls Debugger::Initialize, which increments a
    // global debugger ref-count; therefore we need to check the ref-count before and after importing lldb, and if the
    // ref-count increased we need to call Debugger::Terminate here to decrement the ref-count so that when the final 
    // call to Debugger::Terminate is made, the ref-count has the correct value. 
    //
    // Bonus question:  Why doesn't the ref-count always increase?  Because sometimes lldb has already been imported, in
    // which case the code inside it, including the call to SBDebugger::Initialize(), does not get executed.
    
    int old_count = Debugger::TestDebuggerRefCount();
    
    run_string.Printf ("run_one_line (%s, 'import copy, keyword, os, re, sys, uuid, lldb')", m_dictionary_name.c_str());
    PyRun_SimpleString (run_string.GetData());

    // WARNING: temporary code that loads Cocoa formatters - this should be done on a per-platform basis rather than loading the whole set
    // and letting the individual formatter classes exploit APIs to check whether they can/cannot do their task
    run_string.Clear();
    run_string.Printf ("run_one_line (%s, 'import lldb.formatters, lldb.formatters.cpp, pydoc')", m_dictionary_name.c_str());
    PyRun_SimpleString (run_string.GetData());
    run_string.Clear();

    int new_count = Debugger::TestDebuggerRefCount();
    
    if (new_count > old_count)
        Debugger::Terminate();

    run_string.Printf ("run_one_line (%s, 'import lldb.embedded_interpreter; from lldb.embedded_interpreter import run_python_interpreter; from lldb.embedded_interpreter import run_one_line')", m_dictionary_name.c_str());
    PyRun_SimpleString (run_string.GetData());
    run_string.Clear();
    
    run_string.Printf ("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64 "; pydoc.pager = pydoc.plainpager')", m_dictionary_name.c_str(),
                       interpreter.GetDebugger().GetID());
    PyRun_SimpleString (run_string.GetData());
}

ScriptInterpreterPython::~ScriptInterpreterPython ()
{
}

void
ScriptInterpreterPython::IOHandlerActivated (IOHandler &io_handler)
{
    const char *instructions = nullptr;
    
    switch (m_active_io_handler)
    {
    case eIOHandlerNone:
            break;
    case eIOHandlerBreakpoint:
            instructions = R"(Enter your Python command(s). Type 'DONE' to end.
def function (frame, bp_loc, internal_dict):
    """frame: the lldb.SBFrame for the location at which you stopped
       bp_loc: an lldb.SBBreakpointLocation for the breakpoint location information
       internal_dict: an LLDB support object not to be used"""
)";
            break;
    case eIOHandlerWatchpoint:
            instructions = "Enter your Python command(s). Type 'DONE' to end.\n";
            break;
    }
    
    if (instructions)
    {
        StreamFileSP output_sp(io_handler.GetOutputStreamFile());
        if (output_sp)
        {
            output_sp->PutCString(instructions);
            output_sp->Flush();
        }
    }
}

void
ScriptInterpreterPython::IOHandlerInputComplete (IOHandler &io_handler, std::string &data)
{
    io_handler.SetIsDone(true);
    bool batch_mode = m_interpreter.GetBatchCommandMode();

    switch (m_active_io_handler)
    {
    case eIOHandlerNone:
        break;
    case eIOHandlerBreakpoint:
        {
            std::vector<BreakpointOptions *> *bp_options_vec = (std::vector<BreakpointOptions *> *)io_handler.GetUserData();
            for (auto bp_options : *bp_options_vec)
            {
                if (!bp_options)
                    continue;
                    
                std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
                if (data_ap.get())
                {
                    data_ap->user_source.SplitIntoLines(data);
                    
                    if (GenerateBreakpointCommandCallbackData (data_ap->user_source, data_ap->script_source).Success())
                    {
                        BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
                        bp_options->SetCallback (ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp);
                    }
                    else if (!batch_mode)
                    {
                        StreamFileSP error_sp = io_handler.GetErrorStreamFile();
                        if (error_sp)
                        {
                            error_sp->Printf ("Warning: No command attached to breakpoint.\n");
                            error_sp->Flush();
                        }
                    }
                }
            }
            m_active_io_handler = eIOHandlerNone;
        }
        break;
    case eIOHandlerWatchpoint:
        {
            WatchpointOptions *wp_options = (WatchpointOptions *)io_handler.GetUserData();
            std::unique_ptr<WatchpointOptions::CommandData> data_ap(new WatchpointOptions::CommandData());
            if (data_ap.get())
            {
                data_ap->user_source.SplitIntoLines(data);
                
                if (GenerateWatchpointCommandCallbackData (data_ap->user_source, data_ap->script_source))
                {
                    BatonSP baton_sp (new WatchpointOptions::CommandBaton (data_ap.release()));
                    wp_options->SetCallback (ScriptInterpreterPython::WatchpointCallbackFunction, baton_sp);
                }
                else if (!batch_mode)
                {
                    StreamFileSP error_sp = io_handler.GetErrorStreamFile();
                    if (error_sp)
                    {
                        error_sp->Printf ("Warning: No command attached to breakpoint.\n");
                        error_sp->Flush();
                    }
                }
            }
            m_active_io_handler = eIOHandlerNone;
        }
        break;
    }
}


void
ScriptInterpreterPython::ResetOutputFileHandle (FILE *fh)
{
}

void
ScriptInterpreterPython::SaveTerminalState (int fd)
{
    // Python mucks with the terminal state of STDIN. If we can possibly avoid
    // this by setting the file handles up correctly prior to entering the
    // interpreter we should. For now we save and restore the terminal state
    // on the input file handle.
    m_terminal_state.Save (fd, false);
}

void
ScriptInterpreterPython::RestoreTerminalState ()
{
    // Python mucks with the terminal state of STDIN. If we can possibly avoid
    // this by setting the file handles up correctly prior to entering the
    // interpreter we should. For now we save and restore the terminal state
    // on the input file handle.
    m_terminal_state.Restore();
}

void
ScriptInterpreterPython::LeaveSession ()
{
    Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
    if (log)
        log->PutCString("ScriptInterpreterPython::LeaveSession()");

    // checking that we have a valid thread state - since we use our own threading and locking
    // in some (rare) cases during cleanup Python may end up believing we have no thread state
    // and PyImport_AddModule will crash if that is the case - since that seems to only happen
    // when destroying the SBDebugger, we can make do without clearing up stdout and stderr

    // rdar://problem/11292882
    // When the current thread state is NULL, PyThreadState_Get() issues a fatal error.
    if (PyThreadState_GetDict())
    {
        PythonDictionary &sys_module_dict = GetSysModuleDictionary ();
        if (sys_module_dict)
        {
            if (m_saved_stdin)
            {
                sys_module_dict.SetItemForKey("stdin", m_saved_stdin);
                m_saved_stdin.Reset ();
            }
            if (m_saved_stdout)
            {
                sys_module_dict.SetItemForKey("stdout", m_saved_stdout);
                m_saved_stdout.Reset ();
            }
            if (m_saved_stderr)
            {
                sys_module_dict.SetItemForKey("stderr", m_saved_stderr);
                m_saved_stderr.Reset ();
            }
        }
    }

    m_session_is_active = false;
}

bool
ScriptInterpreterPython::EnterSession (uint16_t on_entry_flags,
                                       FILE *in,
                                       FILE *out,
                                       FILE *err)
{
    // If we have already entered the session, without having officially 'left' it, then there is no need to 
    // 'enter' it again.
    Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
    if (m_session_is_active)
    {
        if (log)
            log->Printf("ScriptInterpreterPython::EnterSession(on_entry_flags=0x%" PRIx16 ") session is already active, returning without doing anything", on_entry_flags);
        return false;
    }

    if (log)
        log->Printf("ScriptInterpreterPython::EnterSession(on_entry_flags=0x%" PRIx16 ")", on_entry_flags);
    

    m_session_is_active = true;

    StreamString run_string;

    if (on_entry_flags & Locker::InitGlobals)
    {
        run_string.Printf (    "run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64, m_dictionary_name.c_str(), GetCommandInterpreter().GetDebugger().GetID());
        run_string.Printf (    "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64 ")", GetCommandInterpreter().GetDebugger().GetID());
        run_string.PutCString ("; lldb.target = lldb.debugger.GetSelectedTarget()");
        run_string.PutCString ("; lldb.process = lldb.target.GetProcess()");
        run_string.PutCString ("; lldb.thread = lldb.process.GetSelectedThread ()");
        run_string.PutCString ("; lldb.frame = lldb.thread.GetSelectedFrame ()");
        run_string.PutCString ("')");
    }
    else
    {
        // If we aren't initing the globals, we should still always set the debugger (since that is always unique.)
        run_string.Printf (    "run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64, m_dictionary_name.c_str(), GetCommandInterpreter().GetDebugger().GetID());
        run_string.Printf (    "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64 ")", GetCommandInterpreter().GetDebugger().GetID());
        run_string.PutCString ("')");
    }

    PyRun_SimpleString (run_string.GetData());
    run_string.Clear();

    PythonDictionary &sys_module_dict = GetSysModuleDictionary ();
    if (sys_module_dict)
    {
        lldb::StreamFileSP in_sp;
        lldb::StreamFileSP out_sp;
        lldb::StreamFileSP err_sp;
        if (in == nullptr || out == nullptr || err == nullptr)
            m_interpreter.GetDebugger().AdoptTopIOHandlerFilesIfInvalid (in_sp, out_sp, err_sp);

        m_saved_stdin.Reset();

        if ((on_entry_flags & Locker::NoSTDIN) == 0)
        {
            // STDIN is enabled
            if (in == nullptr && in_sp)
                in = in_sp->GetFile().GetStream();
            if (in)
            {
                m_saved_stdin.Reset(sys_module_dict.GetItemForKey("stdin"));
                // This call can deadlock your process if the file is locked
                PyObject *new_file = PyFile_FromFile (in, (char *) "", (char *) "r", nullptr);
                sys_module_dict.SetItemForKey ("stdin", new_file);
                Py_DECREF (new_file);
            }
        }

        if (out == nullptr && out_sp)
            out = out_sp->GetFile().GetStream();
        if (out)
        {
            m_saved_stdout.Reset(sys_module_dict.GetItemForKey("stdout"));

            PyObject *new_file = PyFile_FromFile (out, (char *) "", (char *) "w", nullptr);
            sys_module_dict.SetItemForKey ("stdout", new_file);
            Py_DECREF (new_file);
        }
        else
            m_saved_stdout.Reset();

        if (err == nullptr && err_sp)
            err = err_sp->GetFile().GetStream();
        if (err)
        {
            m_saved_stderr.Reset(sys_module_dict.GetItemForKey("stderr"));

            PyObject *new_file = PyFile_FromFile (err, (char *) "", (char *) "w", nullptr);
            sys_module_dict.SetItemForKey ("stderr", new_file);
            Py_DECREF (new_file);
        }
        else
            m_saved_stderr.Reset();
    }

    if (PyErr_Occurred())
        PyErr_Clear ();
    
    return true;
}

PythonObject &
ScriptInterpreterPython::GetMainModule ()
{
    if (!m_main_module)
        m_main_module.Reset(PyImport_AddModule ("__main__"));
    return m_main_module;
}

PythonDictionary &
ScriptInterpreterPython::GetSessionDictionary ()
{
    if (!m_session_dict)
    {
        PythonObject &main_module = GetMainModule ();
        if (main_module)
        {
            PythonDictionary main_dict(PyModule_GetDict (main_module.get()));
            if (main_dict)
            {
                m_session_dict = main_dict.GetItemForKey(m_dictionary_name.c_str());
            }
        }
    }
    return m_session_dict;
}

PythonDictionary &
ScriptInterpreterPython::GetSysModuleDictionary ()
{
    if (!m_sys_module_dict)
    {
        PyObject *sys_module = PyImport_AddModule ("sys");
        if (sys_module)
            m_sys_module_dict.Reset(PyModule_GetDict (sys_module));
    }
    return m_sys_module_dict;
}

static std::string
GenerateUniqueName (const char* base_name_wanted,
                    uint32_t& functions_counter,
                    const void* name_token = nullptr)
{
    StreamString sstr;
    
    if (!base_name_wanted)
        return std::string();
    
    if (!name_token)
        sstr.Printf ("%s_%d", base_name_wanted, functions_counter++);
    else
        sstr.Printf ("%s_%p", base_name_wanted, name_token);
    
    return sstr.GetString();
}

bool
ScriptInterpreterPython::GetEmbeddedInterpreterModuleObjects ()
{
    if (!m_run_one_line_function)
    {
        PyObject *module = PyImport_AddModule ("lldb.embedded_interpreter");
        if (module != nullptr)
        {
            PythonDictionary module_dict (PyModule_GetDict (module));
            if (module_dict)
            {
                m_run_one_line_function = module_dict.GetItemForKey("run_one_line");
                m_run_one_line_str_global = module_dict.GetItemForKey("g_run_one_line_str");
            }
        }
    }
    return (bool)m_run_one_line_function;
}

static void
ReadThreadBytesReceived(void *baton, const void *src, size_t src_len)
{
    if (src && src_len)
    {
        Stream *strm = (Stream *)baton;
        strm->Write(src, src_len);
        strm->Flush();
    }
}

bool
ScriptInterpreterPython::ExecuteOneLine (const char *command, CommandReturnObject *result, const ExecuteScriptOptions &options)
{
    if (!m_valid_session)
        return false;
    
    if (command && command[0])
    {
        // We want to call run_one_line, passing in the dictionary and the command string.  We cannot do this through
        // PyRun_SimpleString here because the command string may contain escaped characters, and putting it inside
        // another string to pass to PyRun_SimpleString messes up the escaping.  So we use the following more complicated
        // method to pass the command string directly down to Python.
        Debugger &debugger = m_interpreter.GetDebugger();
        
        StreamFileSP input_file_sp;
        StreamFileSP output_file_sp;
        StreamFileSP error_file_sp;
        Communication output_comm ("lldb.ScriptInterpreterPython.ExecuteOneLine.comm");
        bool join_read_thread = false;
        if (options.GetEnableIO())
        {
            if (result)
            {
                input_file_sp = debugger.GetInputFile();
                // Set output to a temporary file so we can forward the results on to the result object
                
                Pipe pipe;
                Error pipe_result = pipe.CreateNew(false);
                if (pipe_result.Success())
                {
#if defined(_WIN32)
                    lldb::file_t read_file = pipe.GetReadNativeHandle();
                    pipe.ReleaseReadFileDescriptor();
                    std::unique_ptr<ConnectionGenericFile> conn_ap(new ConnectionGenericFile(read_file, true));
#else
                    std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor(pipe.ReleaseReadFileDescriptor(), true));
#endif
                    if (conn_ap->IsConnected())
                    {
                        output_comm.SetConnection(conn_ap.release());
                        output_comm.SetReadThreadBytesReceivedCallback(ReadThreadBytesReceived, &result->GetOutputStream());
                        output_comm.StartReadThread();
                        join_read_thread = true;
                        FILE *outfile_handle = fdopen (pipe.ReleaseWriteFileDescriptor(), "w");
                        output_file_sp.reset(new StreamFile(outfile_handle, true));
                        error_file_sp = output_file_sp;
                        if (outfile_handle)
                            ::setbuf (outfile_handle, nullptr);
                        
                        result->SetImmediateOutputFile(debugger.GetOutputFile()->GetFile().GetStream());
                        result->SetImmediateErrorFile(debugger.GetErrorFile()->GetFile().GetStream());
                    }
                }
            }
            if (!input_file_sp || !output_file_sp || !error_file_sp)
                debugger.AdoptTopIOHandlerFilesIfInvalid(input_file_sp, output_file_sp, error_file_sp);
        }
        else
        {
            input_file_sp.reset (new StreamFile ());
            input_file_sp->GetFile().Open("/dev/null", File::eOpenOptionRead);
            output_file_sp.reset (new StreamFile ());
            output_file_sp->GetFile().Open("/dev/null", File::eOpenOptionWrite);
            error_file_sp = output_file_sp;
        }

        FILE *in_file = input_file_sp->GetFile().GetStream();
        FILE *out_file = output_file_sp->GetFile().GetStream();
        FILE *err_file = error_file_sp->GetFile().GetStream();
        Locker locker(this,
                      ScriptInterpreterPython::Locker::AcquireLock |
                      ScriptInterpreterPython::Locker::InitSession |
                      (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0) |
                      ((result && result->GetInteractive()) ? 0: Locker::NoSTDIN),
                      ScriptInterpreterPython::Locker::FreeAcquiredLock |
                      ScriptInterpreterPython::Locker::TearDownSession,
                      in_file,
                      out_file,
                      err_file);
        
        bool success = false;
        
        // Find the correct script interpreter dictionary in the main module.
        PythonDictionary &session_dict = GetSessionDictionary ();
        if (session_dict)
        {
            if (GetEmbeddedInterpreterModuleObjects ())
            {
                PyObject *pfunc = m_run_one_line_function.get();
                
                if (pfunc && PyCallable_Check (pfunc))
                {
                    PythonObject pargs (Py_BuildValue("(Os)", session_dict.get(), command));
                    if (pargs)
                    {
                        PythonObject return_value(PyObject_CallObject (pfunc, pargs.get()));
                        if (return_value)
                            success = true;
                        else if (options.GetMaskoutErrors() && PyErr_Occurred ())
                        {
                            PyErr_Print();
                            PyErr_Clear();
                        }
                    }
                }
            }
        }

        // Flush our output and error file handles
        ::fflush (out_file);
        if (out_file != err_file)
            ::fflush (err_file);
        
        if (join_read_thread)
        {
            // Close the write end of the pipe since we are done with our
            // one line script. This should cause the read thread that
            // output_comm is using to exit
            output_file_sp->GetFile().Close();
            // The close above should cause this thread to exit when it gets
            // to the end of file, so let it get all its data
            output_comm.JoinReadThread();
            // Now we can close the read end of the pipe
            output_comm.Disconnect();
        }
        
        
        if (success)
            return true;

        // The one-liner failed.  Append the error message.
        if (result)
            result->AppendErrorWithFormat ("python failed attempting to evaluate '%s'\n", command);
        return false;
    }

    if (result)
        result->AppendError ("empty command passed to python\n");
    return false;
}


class IOHandlerPythonInterpreter :
    public IOHandler
{
public:
    
    IOHandlerPythonInterpreter (Debugger &debugger,
                                ScriptInterpreterPython *python) :
        IOHandler (debugger, IOHandler::Type::PythonInterpreter),
        m_python(python)
    {
        
    }
    
    virtual
    ~IOHandlerPythonInterpreter()
    {
        
    }
    
    virtual ConstString
    GetControlSequence (char ch)
    {
        if (ch == 'd')
            return ConstString("quit()\n");
        return ConstString();
    }

    virtual void
    Run ()
    {
        if (m_python)
        {
            int stdin_fd = GetInputFD();
            if (stdin_fd >= 0)
            {
                Terminal terminal(stdin_fd);
                TerminalState terminal_state;
                const bool is_a_tty = terminal.IsATerminal();
                
                if (is_a_tty)
                {
                    terminal_state.Save (stdin_fd, false);
                    terminal.SetCanonical(false);
                    terminal.SetEcho(true);
                }
                
                ScriptInterpreterPython::Locker locker (m_python,
                                                        ScriptInterpreterPython::Locker::AcquireLock |
                                                        ScriptInterpreterPython::Locker::InitSession |
                                                        ScriptInterpreterPython::Locker::InitGlobals,
                                                        ScriptInterpreterPython::Locker::FreeAcquiredLock |
                                                        ScriptInterpreterPython::Locker::TearDownSession);

                // The following call drops into the embedded interpreter loop and stays there until the
                // user chooses to exit from the Python interpreter.
                // This embedded interpreter will, as any Python code that performs I/O, unlock the GIL before
                // a system call that can hang, and lock it when the syscall has returned.
                
                // We need to surround the call to the embedded interpreter with calls to PyGILState_Ensure and
                // PyGILState_Release (using the Locker above). This is because Python has a global lock which must be held whenever we want
                // to touch any Python objects. Otherwise, if the user calls Python code, the interpreter state will be off,
                // and things could hang (it's happened before).
                
                StreamString run_string;
                run_string.Printf ("run_python_interpreter (%s)", m_python->GetDictionaryName ());
                PyRun_SimpleString (run_string.GetData());
                
                if (is_a_tty)
                    terminal_state.Restore();
            }
        }
        SetIsDone(true);
    }

    virtual void
    Hide ()
    {
        
    }
    
    virtual void
    Refresh ()
    {
        
    }

    virtual void
    Cancel ()
    {
        
    }

    virtual bool
    Interrupt ()
    {
        return m_python->Interrupt();
    }
    
    virtual void
    GotEOF()
    {
        
    }
protected:
    ScriptInterpreterPython *m_python;
};


void
ScriptInterpreterPython::ExecuteInterpreterLoop ()
{
    Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);

    Debugger &debugger = GetCommandInterpreter().GetDebugger();

    // At the moment, the only time the debugger does not have an input file handle is when this is called
    // directly from Python, in which case it is both dangerous and unnecessary (not to mention confusing) to
    // try to embed a running interpreter loop inside the already running Python interpreter loop, so we won't
    // do it.

    if (!debugger.GetInputFile()->GetFile().IsValid())
        return;

    IOHandlerSP io_handler_sp (new IOHandlerPythonInterpreter (debugger, this));
    if (io_handler_sp)
    {
        debugger.PushIOHandler(io_handler_sp);
    }
}

bool
ScriptInterpreterPython::Interrupt()
{
    Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));

    if (IsExecutingPython())
    {
        PyThreadState* state = _PyThreadState_Current;
        if (!state)
            state = GetThreadState();
        if (state)
        {
            long tid = state->thread_id;
            _PyThreadState_Current = state;
            int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt);
            if (log)
                log->Printf("ScriptInterpreterPython::Interrupt() sending PyExc_KeyboardInterrupt (tid = %li, num_threads = %i)...", tid, num_threads);
            return true;
        }
    }
    if (log)
        log->Printf("ScriptInterpreterPython::Interrupt() python code not running, can't interrupt");
    return false;

}
bool
ScriptInterpreterPython::ExecuteOneLineWithReturn (const char *in_string,
                                                   ScriptInterpreter::ScriptReturnType return_type,
                                                   void *ret_value,
                                                   const ExecuteScriptOptions &options)
{

    Locker locker(this,
                  ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0) | Locker::NoSTDIN,
                  ScriptInterpreterPython::Locker::FreeAcquiredLock | ScriptInterpreterPython::Locker::TearDownSession);

    PyObject *py_return = nullptr;
    PythonObject &main_module = GetMainModule ();
    PythonDictionary globals (PyModule_GetDict(main_module.get()));
    PyObject *py_error = nullptr;
    bool ret_success = false;
    int success;
    
    PythonDictionary locals = GetSessionDictionary ();
    
    if (!locals)
    {
        locals = PyObject_GetAttrString (globals.get(), m_dictionary_name.c_str());
    }
        
    if (!locals)
        locals = globals;

    py_error = PyErr_Occurred();
    if (py_error != nullptr)
        PyErr_Clear();
    
    if (in_string != nullptr)
    {
        { // scope for PythonInputReaderManager
            //PythonInputReaderManager py_input(options.GetEnableIO() ? this : NULL);
            py_return = PyRun_String (in_string, Py_eval_input, globals.get(), locals.get());
            if (py_return == nullptr)
            { 
                py_error = PyErr_Occurred ();
                if (py_error != nullptr)
                    PyErr_Clear ();

                py_return = PyRun_String (in_string, Py_single_input, globals.get(), locals.get());
            }
        }

        if (py_return != nullptr)
        {
            switch (return_type)
            {
                case eScriptReturnTypeCharPtr: // "char *"
                {
                    const char format[3] = "s#";
                    success = PyArg_Parse (py_return, format, (char **) ret_value);
                    break;
                }
                case eScriptReturnTypeCharStrOrNone: // char* or NULL if py_return == Py_None
                {
                    const char format[3] = "z";
                    success = PyArg_Parse (py_return, format, (char **) ret_value);
                    break;
                }
                case eScriptReturnTypeBool:
                {
                    const char format[2] = "b";
                    success = PyArg_Parse (py_return, format, (bool *) ret_value);
                    break;
                }
                case eScriptReturnTypeShortInt:
                {
                    const char format[2] = "h";
                    success = PyArg_Parse (py_return, format, (short *) ret_value);
                    break;
                }
                case eScriptReturnTypeShortIntUnsigned:
                {
                    const char format[2] = "H";
                    success = PyArg_Parse (py_return, format, (unsigned short *) ret_value);
                    break;
                }
                case eScriptReturnTypeInt:
                {
                    const char format[2] = "i";
                    success = PyArg_Parse (py_return, format, (int *) ret_value);
                    break;
                }
                case eScriptReturnTypeIntUnsigned:
                {
                    const char format[2] = "I";
                    success = PyArg_Parse (py_return, format, (unsigned int *) ret_value);
                    break;
                }
                case eScriptReturnTypeLongInt:
                {
                    const char format[2] = "l";
                    success = PyArg_Parse (py_return, format, (long *) ret_value);
                    break;
                }
                case eScriptReturnTypeLongIntUnsigned:
                {
                    const char format[2] = "k";
                    success = PyArg_Parse (py_return, format, (unsigned long *) ret_value);
                    break;
                }
                case eScriptReturnTypeLongLong:
                {
                    const char format[2] = "L";
                    success = PyArg_Parse (py_return, format, (long long *) ret_value);
                    break;
                }
                case eScriptReturnTypeLongLongUnsigned:
                {
                    const char format[2] = "K";
                    success = PyArg_Parse (py_return, format, (unsigned long long *) ret_value);
                    break;
                }
                case eScriptReturnTypeFloat:
                {
                    const char format[2] = "f";
                    success = PyArg_Parse (py_return, format, (float *) ret_value);
                    break;
                }
                case eScriptReturnTypeDouble:
                {
                    const char format[2] = "d";
                    success = PyArg_Parse (py_return, format, (double *) ret_value);
                    break;
                }
                case eScriptReturnTypeChar:
                {
                    const char format[2] = "c";
                    success = PyArg_Parse (py_return, format, (char *) ret_value);
                    break;
                }
                case eScriptReturnTypeOpaqueObject:
                {
                    success = true;
                    Py_XINCREF(py_return);
                    *((PyObject**)ret_value) = py_return;
                    break;
                }
            }
            Py_XDECREF (py_return);
            if (success)
                ret_success = true;
            else
                ret_success = false;
        }
    }

    py_error = PyErr_Occurred();
    if (py_error != nullptr)
    {
        ret_success = false;
        if (options.GetMaskoutErrors())
        {
            if (PyErr_GivenExceptionMatches (py_error, PyExc_SyntaxError))
                PyErr_Print ();
            PyErr_Clear();
        }
    }

    return ret_success;
}

Error
ScriptInterpreterPython::ExecuteMultipleLines (const char *in_string, const ExecuteScriptOptions &options)
{
    Error error;
    
    Locker locker(this,
                  ScriptInterpreterPython::Locker::AcquireLock      | ScriptInterpreterPython::Locker::InitSession | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0) | Locker::NoSTDIN,
                  ScriptInterpreterPython::Locker::FreeAcquiredLock | ScriptInterpreterPython::Locker::TearDownSession);

    PythonObject return_value;
    PythonObject &main_module = GetMainModule ();
    PythonDictionary globals (PyModule_GetDict(main_module.get()));
    PyObject *py_error = nullptr;

    PythonDictionary locals = GetSessionDictionary ();
    
    if (!locals)
    {
        locals = PyObject_GetAttrString (globals.get(), m_dictionary_name.c_str());
    }

    if (!locals)
    {
        locals = globals;
    }

    py_error = PyErr_Occurred();
    if (py_error != nullptr)
        PyErr_Clear();
    
    if (in_string != nullptr)
    {
        struct _node *compiled_node = PyParser_SimpleParseString (in_string, Py_file_input);
        if (compiled_node)
        {
            PyCodeObject *compiled_code = PyNode_Compile (compiled_node, "temp.py");
            if (compiled_code)
            {
              return_value.Reset(PyEval_EvalCode (compiled_code, globals.get(), locals.get()));
            }
        }
    }

    py_error = PyErr_Occurred ();
    if (py_error != nullptr)
    {
//        puts(in_string);
//        _PyObject_Dump (py_error);
//        PyErr_Print();
//        success = false;
        
        PyObject *type = nullptr;
        PyObject *value = nullptr;
        PyObject *traceback = nullptr;
        PyErr_Fetch (&type,&value,&traceback);
        
        // get the backtrace
        std::string bt = ReadPythonBacktrace(traceback);
        
        if (value && value != Py_None)
            error.SetErrorStringWithFormat("%s\n%s", PyString_AsString(PyObject_Str(value)),bt.c_str());
        else
            error.SetErrorStringWithFormat("%s",bt.c_str());
        Py_XDECREF(type);
        Py_XDECREF(value);
        Py_XDECREF(traceback);
        if (options.GetMaskoutErrors())
        {
            PyErr_Clear();
        }
    }

    return error;
}


void
ScriptInterpreterPython::CollectDataForBreakpointCommandCallback (std::vector<BreakpointOptions *> &bp_options_vec,
                                                                  CommandReturnObject &result)
{
    m_active_io_handler = eIOHandlerBreakpoint;
    m_interpreter.GetPythonCommandsFromIOHandler ("    ", *this, true, &bp_options_vec);
}

void
ScriptInterpreterPython::CollectDataForWatchpointCommandCallback (WatchpointOptions *wp_options,
                                                                  CommandReturnObject &result)
{
    m_active_io_handler = eIOHandlerWatchpoint;
    m_interpreter.GetPythonCommandsFromIOHandler ("    ", *this, true, wp_options);
}

void
ScriptInterpreterPython::SetBreakpointCommandCallbackFunction (BreakpointOptions *bp_options,
                                                               const char *function_name)
{
    // For now just cons up a oneliner that calls the provided function.
    std::string oneliner("return ");
    oneliner += function_name;
    oneliner += "(frame, bp_loc, internal_dict)";
    m_interpreter.GetScriptInterpreter()->SetBreakpointCommandCallback (bp_options,
                                                                        oneliner.c_str());
}

// Set a Python one-liner as the callback for the breakpoint.
Error
ScriptInterpreterPython::SetBreakpointCommandCallback (BreakpointOptions *bp_options,
                                                       const char *command_body_text)
{
    std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());

    // Split the command_body_text into lines, and pass that to GenerateBreakpointCommandCallbackData.  That will
    // wrap the body in an auto-generated function, and return the function name in script_source.  That is what
    // the callback will actually invoke.
    
    data_ap->user_source.SplitIntoLines(command_body_text);
    Error error = GenerateBreakpointCommandCallbackData (data_ap->user_source, data_ap->script_source);
    if (error.Success())
    {
        BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
        bp_options->SetCallback (ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp);
        return error;
    }
    else
        return error;
}

// Set a Python one-liner as the callback for the watchpoint.
void
ScriptInterpreterPython::SetWatchpointCommandCallback (WatchpointOptions *wp_options,
                                                       const char *oneliner)
{
    std::unique_ptr<WatchpointOptions::CommandData> data_ap(new WatchpointOptions::CommandData());

    // It's necessary to set both user_source and script_source to the oneliner.
    // The former is used to generate callback description (as in watchpoint command list)
    // while the latter is used for Python to interpret during the actual callback.

    data_ap->user_source.AppendString (oneliner);
    data_ap->script_source.assign (oneliner);

    if (GenerateWatchpointCommandCallbackData (data_ap->user_source, data_ap->script_source))
    {
        BatonSP baton_sp (new WatchpointOptions::CommandBaton (data_ap.release()));
        wp_options->SetCallback (ScriptInterpreterPython::WatchpointCallbackFunction, baton_sp);
    }
    
    return;
}

Error
ScriptInterpreterPython::ExportFunctionDefinitionToInterpreter (StringList &function_def)
{
    // Convert StringList to one long, newline delimited, const char *.
    std::string function_def_string(function_def.CopyList());

    Error error = ExecuteMultipleLines (function_def_string.c_str(), ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false));
    return error;
}

Error
ScriptInterpreterPython::GenerateFunction(const char *signature, const StringList &input)
{
    Error error;
    int num_lines = input.GetSize ();
    if (num_lines == 0)
    {
        error.SetErrorString ("No input data.");
        return error;
    }
    
    if (!signature || *signature == 0)
    {
        error.SetErrorString("No output function name.");
        return error;
    }

    StreamString sstr;
    StringList auto_generated_function;
    auto_generated_function.AppendString (signature);
    auto_generated_function.AppendString ("     global_dict = globals()");   // Grab the global dictionary
    auto_generated_function.AppendString ("     new_keys = internal_dict.keys()");    // Make a list of keys in the session dict
    auto_generated_function.AppendString ("     old_keys = global_dict.keys()"); // Save list of keys in global dict
    auto_generated_function.AppendString ("     global_dict.update (internal_dict)"); // Add the session dictionary to the 
    // global dictionary.
    
    // Wrap everything up inside the function, increasing the indentation.
    
    auto_generated_function.AppendString("     if True:");
    for (int i = 0; i < num_lines; ++i)
    {
        sstr.Clear ();
        sstr.Printf ("       %s", input.GetStringAtIndex (i));
        auto_generated_function.AppendString (sstr.GetData());
    }
    auto_generated_function.AppendString ("     for key in new_keys:");  // Iterate over all the keys from session dict
    auto_generated_function.AppendString ("         internal_dict[key] = global_dict[key]");  // Update session dict values
    auto_generated_function.AppendString ("         if key not in old_keys:");       // If key was not originally in global dict
    auto_generated_function.AppendString ("             del global_dict[key]");      //  ...then remove key/value from global dict
    
    // Verify that the results are valid Python.
    
    error = ExportFunctionDefinitionToInterpreter (auto_generated_function);
    
    return error;
}

bool
ScriptInterpreterPython::GenerateTypeScriptFunction (StringList &user_input, std::string& output, const void* name_token)
{
    static uint32_t num_created_functions = 0;
    user_input.RemoveBlankLines ();
    StreamString sstr;
    
    // Check to see if we have any data; if not, just return.
    if (user_input.GetSize() == 0)
        return false;
    
    // Take what the user wrote, wrap it all up inside one big auto-generated Python function, passing in the
    // ValueObject as parameter to the function.
    
    std::string auto_generated_function_name(GenerateUniqueName("lldb_autogen_python_type_print_func", num_created_functions, name_token));
    sstr.Printf ("def %s (valobj, internal_dict):", auto_generated_function_name.c_str());
    
    if (!GenerateFunction(sstr.GetData(), user_input).Success())
        return false;

    // Store the name of the auto-generated function to be called.
    output.assign(auto_generated_function_name);
    return true;
}

bool
ScriptInterpreterPython::GenerateScriptAliasFunction (StringList &user_input, std::string &output)
{
    static uint32_t num_created_functions = 0;
    user_input.RemoveBlankLines ();
    StreamString sstr;
    
    // Check to see if we have any data; if not, just return.
    if (user_input.GetSize() == 0)
        return false;
    
    std::string auto_generated_function_name(GenerateUniqueName("lldb_autogen_python_cmd_alias_func", num_created_functions));

    sstr.Printf ("def %s (debugger, args, result, internal_dict):", auto_generated_function_name.c_str());
    
    if (!GenerateFunction(sstr.GetData(),user_input).Success())
        return false;
    
    // Store the name of the auto-generated function to be called.
    output.assign(auto_generated_function_name);
    return true;
}


bool
ScriptInterpreterPython::GenerateTypeSynthClass (StringList &user_input, std::string &output, const void* name_token)
{
    static uint32_t num_created_classes = 0;
    user_input.RemoveBlankLines ();
    int num_lines = user_input.GetSize ();
    StreamString sstr;
    
    // Check to see if we have any data; if not, just return.
    if (user_input.GetSize() == 0)
        return false;
    
    // Wrap all user input into a Python class
    
    std::string auto_generated_class_name(GenerateUniqueName("lldb_autogen_python_type_synth_class",num_created_classes,name_token));
    
    StringList auto_generated_class;
    
    // Create the function name & definition string.
    
    sstr.Printf ("class %s:", auto_generated_class_name.c_str());
    auto_generated_class.AppendString (sstr.GetData());
        
    // Wrap everything up inside the class, increasing the indentation.
    // we don't need to play any fancy indentation tricks here because there is no
    // surrounding code whose indentation we need to honor
    for (int i = 0; i < num_lines; ++i)
    {
        sstr.Clear ();
        sstr.Printf ("     %s", user_input.GetStringAtIndex (i));
        auto_generated_class.AppendString (sstr.GetData());
    }
    
    
    // Verify that the results are valid Python.
    // (even though the method is ExportFunctionDefinitionToInterpreter, a class will actually be exported)
    // (TODO: rename that method to ExportDefinitionToInterpreter)
    if (!ExportFunctionDefinitionToInterpreter (auto_generated_class).Success())
        return false;
    
    // Store the name of the auto-generated class
    
    output.assign(auto_generated_class_name);
    return true;
}

StructuredData::GenericSP
ScriptInterpreterPython::OSPlugin_CreatePluginObject(const char *class_name, lldb::ProcessSP process_sp)
{
    if (class_name == nullptr || class_name[0] == '\0')
        return StructuredData::GenericSP();

    if (!process_sp)
        return StructuredData::GenericSP();

    void* ret_val;
    
    {
        Locker py_lock  (this,
                         Locker::AcquireLock | Locker::NoSTDIN,
                         Locker::FreeLock);
        ret_val = g_swig_create_os_plugin    (class_name,
                                              m_dictionary_name.c_str(),
                                              process_sp);
    }

    return StructuredData::GenericSP(new StructuredPythonObject(ret_val));
}

StructuredData::DictionarySP
ScriptInterpreterPython::OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp)
{
    Locker py_lock(this,
                   Locker::AcquireLock | Locker::NoSTDIN,
                   Locker::FreeLock);
    
    static char callee_name[] = "get_register_info";
    
    if (!os_plugin_object_sp)
        return StructuredData::DictionarySP();

    StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
    if (!generic)
        return nullptr;

    PyObject *implementor = (PyObject *)generic->GetValue();

    if (implementor == nullptr || implementor == Py_None)
        return StructuredData::DictionarySP();

    PyObject* pmeth  = PyObject_GetAttrString(implementor, callee_name);
    
    if (PyErr_Occurred())
    {
        PyErr_Clear();
    }
    
    if (pmeth == nullptr || pmeth == Py_None)
    {
        Py_XDECREF(pmeth);
        return StructuredData::DictionarySP();
    }
    
    if (PyCallable_Check(pmeth) == 0)
    {
        if (PyErr_Occurred())
        {
            PyErr_Clear();
        }
        
        Py_XDECREF(pmeth);
        return StructuredData::DictionarySP();
    }
    
    if (PyErr_Occurred())
    {
        PyErr_Clear();
    }
    
    Py_XDECREF(pmeth);
    
    // right now we know this function exists and is callable..
    PyObject* py_return = PyObject_CallMethod(implementor, callee_name, nullptr);
    
    // if it fails, print the error but otherwise go on
    if (PyErr_Occurred())
    {
        PyErr_Print();
        PyErr_Clear();
    }

    PythonDictionary result_dict(py_return);
    return result_dict.CreateStructuredDictionary();
}

StructuredData::ArraySP
ScriptInterpreterPython::OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp)
{
    Locker py_lock (this,
                    Locker::AcquireLock | Locker::NoSTDIN,
                    Locker::FreeLock);

    static char callee_name[] = "get_thread_info";

    if (!os_plugin_object_sp)
        return StructuredData::ArraySP();

    StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
    if (!generic)
        return nullptr;
    PyObject *implementor = (PyObject *)generic->GetValue();

    if (implementor == nullptr || implementor == Py_None)
        return StructuredData::ArraySP();

    PyObject* pmeth  = PyObject_GetAttrString(implementor, callee_name);
    
    if (PyErr_Occurred())
    {
        PyErr_Clear();
    }
    
    if (pmeth == nullptr || pmeth == Py_None)
    {
        Py_XDECREF(pmeth);
        return StructuredData::ArraySP();
    }
    
    if (PyCallable_Check(pmeth) == 0)
    {
        if (PyErr_Occurred())
        {
            PyErr_Clear();
        }
        
        Py_XDECREF(pmeth);
        return StructuredData::ArraySP();
    }
    
    if (PyErr_Occurred())
    {
        PyErr_Clear();
    }
    
    Py_XDECREF(pmeth);
    
    // right now we know this function exists and is callable..
    PyObject* py_return = PyObject_CallMethod(implementor, callee_name, nullptr);
    
    // if it fails, print the error but otherwise go on
    if (PyErr_Occurred())
    {
        PyErr_Print();
        PyErr_Clear();
    }

    PythonList ResultList(py_return);
    return ResultList.CreateStructuredArray();
}

// GetPythonValueFormatString provides a system independent type safe way to
// convert a variable's type into a python value format. Python value formats
// are defined in terms of builtin C types and could change from system to
// as the underlying typedef for uint* types, size_t, off_t and other values
// change.

template <typename T>
const char *GetPythonValueFormatString(T t)
{
    assert(!"Unhandled type passed to GetPythonValueFormatString(T), make a specialization of GetPythonValueFormatString() to support this type.");
    return nullptr;
}
template <> const char *GetPythonValueFormatString (char *)             { return "s"; }
template <> const char *GetPythonValueFormatString (char)               { return "b"; }
template <> const char *GetPythonValueFormatString (unsigned char)      { return "B"; }
template <> const char *GetPythonValueFormatString (short)              { return "h"; }
template <> const char *GetPythonValueFormatString (unsigned short)     { return "H"; }
template <> const char *GetPythonValueFormatString (int)                { return "i"; }
template <> const char *GetPythonValueFormatString (unsigned int)       { return "I"; }
template <> const char *GetPythonValueFormatString (long)               { return "l"; }
template <> const char *GetPythonValueFormatString (unsigned long)      { return "k"; }
template <> const char *GetPythonValueFormatString (long long)          { return "L"; }
template <> const char *GetPythonValueFormatString (unsigned long long) { return "K"; }
template <> const char *GetPythonValueFormatString (float t)            { return "f"; }
template <> const char *GetPythonValueFormatString (double t)           { return "d"; }

StructuredData::StringSP
ScriptInterpreterPython::OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid)
{
    Locker py_lock (this,
                    Locker::AcquireLock | Locker::NoSTDIN,
                    Locker::FreeLock);

    static char callee_name[] = "get_register_data";
    static char *param_format = const_cast<char *>(GetPythonValueFormatString(tid));
    
    if (!os_plugin_object_sp)
        return StructuredData::StringSP();

    StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
    if (!generic)
        return nullptr;
    PyObject *implementor = (PyObject *)generic->GetValue();

    if (implementor == nullptr || implementor == Py_None)
        return StructuredData::StringSP();

    PyObject* pmeth  = PyObject_GetAttrString(implementor, callee_name);
    
    if (PyErr_Occurred())
    {
        PyErr_Clear();
    }
    
    if (pmeth == nullptr || pmeth == Py_None)
    {
        Py_XDECREF(pmeth);
        return StructuredData::StringSP();
    }
    
    if (PyCallable_Check(pmeth) == 0)
    {
        if (PyErr_Occurred())
        {
            PyErr_Clear();
        }
        
        Py_XDECREF(pmeth);
        return StructuredData::StringSP();
    }
    
    if (PyErr_Occurred())
    {
        PyErr_Clear();
    }
    
    Py_XDECREF(pmeth);
    
    // right now we know this function exists and is callable..
    PyObject* py_return = PyObject_CallMethod(implementor, callee_name, param_format, tid);

    // if it fails, print the error but otherwise go on
    if (PyErr_Occurred())
    {
        PyErr_Print();
        PyErr_Clear();
    }
    PythonString result_string(py_return);
    return result_string.CreateStructuredString();
}

StructuredData::DictionarySP
ScriptInterpreterPython::OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid, lldb::addr_t context)
{
    Locker py_lock(this,
                   Locker::AcquireLock | Locker::NoSTDIN,
                   Locker::FreeLock);
    
    static char callee_name[] = "create_thread";
    std::string param_format;
    param_format += GetPythonValueFormatString(tid);
    param_format += GetPythonValueFormatString(context);
    
    if (!os_plugin_object_sp)
        return StructuredData::DictionarySP();

    StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
    if (!generic)
        return nullptr;
    PyObject *implementor = (PyObject *)generic->GetValue();

    if (implementor == nullptr || implementor == Py_None)
        return StructuredData::DictionarySP();

    PyObject* pmeth  = PyObject_GetAttrString(implementor, callee_name);
    
    if (PyErr_Occurred())
    {
        PyErr_Clear();
    }
    
    if (pmeth == nullptr || pmeth == Py_None)
    {
        Py_XDECREF(pmeth);
        return StructuredData::DictionarySP();
    }
    
    if (PyCallable_Check(pmeth) == 0)
    {
        if (PyErr_Occurred())
        {
            PyErr_Clear();
        }
        
        Py_XDECREF(pmeth);
        return StructuredData::DictionarySP();
    }
    
    if (PyErr_Occurred())
    {
        PyErr_Clear();
    }
    
    Py_XDECREF(pmeth);
    
    // right now we know this function exists and is callable..
    PyObject* py_return = PyObject_CallMethod(implementor, callee_name, &param_format[0], tid, context);
    
    // if it fails, print the error but otherwise go on
    if (PyErr_Occurred())
    {
        PyErr_Print();
        PyErr_Clear();
    }

    PythonDictionary result_dict(py_return);
    return result_dict.CreateStructuredDictionary();
}

StructuredData::ObjectSP
ScriptInterpreterPython::CreateScriptedThreadPlan(const char *class_name, lldb::ThreadPlanSP thread_plan_sp)
{
    if (class_name == nullptr || class_name[0] == '\0')
        return StructuredData::ObjectSP();

    if (!thread_plan_sp.get())
        return StructuredData::ObjectSP();

    Debugger &debugger = thread_plan_sp->GetTarget().GetDebugger();
    ScriptInterpreter *script_interpreter = debugger.GetCommandInterpreter().GetScriptInterpreter();
    ScriptInterpreterPython *python_interpreter = static_cast<ScriptInterpreterPython *>(script_interpreter);
    
    if (!script_interpreter)
        return StructuredData::ObjectSP();

    void* ret_val;

    {
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        
        ret_val = g_swig_thread_plan_script (class_name,
                                             python_interpreter->m_dictionary_name.c_str(),
                                             thread_plan_sp);
    }

    return StructuredData::ObjectSP(new StructuredPythonObject(ret_val));
}

bool
ScriptInterpreterPython::ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error)
{
    bool explains_stop = true;
    StructuredData::Generic *generic = nullptr;
    if (implementor_sp)
        generic = implementor_sp->GetAsGeneric();
    if (generic)
    {
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        explains_stop = g_swig_call_thread_plan(generic->GetValue(), "explains_stop", event, script_error);
        if (script_error)
            return true;
    }
    return explains_stop;
}

bool
ScriptInterpreterPython::ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error)
{
    bool should_stop = true;
    StructuredData::Generic *generic = nullptr;
    if (implementor_sp)
        generic = implementor_sp->GetAsGeneric();
    if (generic)
    {
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        should_stop = g_swig_call_thread_plan(generic->GetValue(), "should_stop", event, script_error);
        if (script_error)
            return true;
    }
    return should_stop;
}

lldb::StateType
ScriptInterpreterPython::ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp, bool &script_error)
{
    bool should_step = false;
    StructuredData::Generic *generic = nullptr;
    if (implementor_sp)
        generic = implementor_sp->GetAsGeneric();
    if (generic)
    {
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        should_step = g_swig_call_thread_plan(generic->GetValue(), "should_step", NULL, script_error);
        if (script_error)
            should_step = true;
    }
    if (should_step)
        return lldb::eStateStepping;
    else
        return lldb::eStateRunning;
}

StructuredData::ObjectSP
ScriptInterpreterPython::LoadPluginModule(const FileSpec &file_spec, lldb_private::Error &error)
{
    if (!file_spec.Exists())
    {
        error.SetErrorString("no such file");
        return StructuredData::ObjectSP();
    }

    StructuredData::ObjectSP module_sp;

    if (LoadScriptingModule(file_spec.GetPath().c_str(),true,true,error,&module_sp))
        return module_sp;

    return StructuredData::ObjectSP();
}

StructuredData::DictionarySP
ScriptInterpreterPython::GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target, const char *setting_name,
                                            lldb_private::Error &error)
{
    if (!plugin_module_sp || !target || !setting_name || !setting_name[0] || !g_swig_plugin_get)
        return StructuredData::DictionarySP();
    StructuredData::Generic *generic = plugin_module_sp->GetAsGeneric();
    if (!generic)
        return StructuredData::DictionarySP();

    PyObject *reply_pyobj = nullptr;
    
    {
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        TargetSP target_sp(target->shared_from_this());
        reply_pyobj = (PyObject *)g_swig_plugin_get(generic->GetValue(), setting_name, target_sp);
    }

    PythonDictionary py_dict(reply_pyobj);

    return py_dict.CreateStructuredDictionary();
}

StructuredData::ObjectSP
ScriptInterpreterPython::CreateSyntheticScriptedProvider(const char *class_name, lldb::ValueObjectSP valobj)
{
    if (class_name == nullptr || class_name[0] == '\0')
        return StructuredData::ObjectSP();

    if (!valobj.get())
        return StructuredData::ObjectSP();

    ExecutionContext exe_ctx (valobj->GetExecutionContextRef());
    Target *target = exe_ctx.GetTargetPtr();
    
    if (!target)
        return StructuredData::ObjectSP();

    Debugger &debugger = target->GetDebugger();
    ScriptInterpreter *script_interpreter = debugger.GetCommandInterpreter().GetScriptInterpreter();
    ScriptInterpreterPython *python_interpreter = (ScriptInterpreterPython *) script_interpreter;
    
    if (!script_interpreter)
        return StructuredData::ObjectSP();

    void *ret_val = nullptr;

    {
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        ret_val = g_swig_synthetic_script (class_name,
                                           python_interpreter->m_dictionary_name.c_str(),
                                           valobj);
    }

    return StructuredData::ObjectSP(new StructuredPythonObject(ret_val));
}

StructuredData::GenericSP
ScriptInterpreterPython::CreateScriptCommandObject (const char *class_name)
{
    DebuggerSP debugger_sp(GetCommandInterpreter().GetDebugger().shared_from_this());
    
    if (class_name == nullptr || class_name[0] == '\0')
        return StructuredData::GenericSP();
    
    if (!debugger_sp.get())
        return StructuredData::GenericSP();
    
    void* ret_val;
    
    {
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        ret_val = g_swig_create_cmd (class_name,
                                     m_dictionary_name.c_str(),
                                     debugger_sp);
    }
    
    return StructuredData::GenericSP(new StructuredPythonObject(ret_val));
}

bool
ScriptInterpreterPython::GenerateTypeScriptFunction (const char* oneliner, std::string& output, const void* name_token)
{
    StringList input;
    input.SplitIntoLines(oneliner, strlen(oneliner));
    return GenerateTypeScriptFunction(input, output, name_token);
}

bool
ScriptInterpreterPython::GenerateTypeSynthClass (const char* oneliner, std::string& output, const void* name_token)
{
    StringList input;
    input.SplitIntoLines(oneliner, strlen(oneliner));
    return GenerateTypeSynthClass(input, output, name_token);
}


Error
ScriptInterpreterPython::GenerateBreakpointCommandCallbackData (StringList &user_input, std::string& output)
{
    static uint32_t num_created_functions = 0;
    user_input.RemoveBlankLines ();
    StreamString sstr;
    Error error;
    if (user_input.GetSize() == 0)
    {
        error.SetErrorString("No input data.");
        return error;
    }

    std::string auto_generated_function_name(GenerateUniqueName("lldb_autogen_python_bp_callback_func_",num_created_functions));
    sstr.Printf ("def %s (frame, bp_loc, internal_dict):", auto_generated_function_name.c_str());
    
    error = GenerateFunction(sstr.GetData(), user_input);
    if (!error.Success())
        return error;
    
    // Store the name of the auto-generated function to be called.
    output.assign(auto_generated_function_name);
    return error;
}

bool
ScriptInterpreterPython::GenerateWatchpointCommandCallbackData (StringList &user_input, std::string& output)
{
    static uint32_t num_created_functions = 0;
    user_input.RemoveBlankLines ();
    StreamString sstr;

    if (user_input.GetSize() == 0)
        return false;

    std::string auto_generated_function_name(GenerateUniqueName("lldb_autogen_python_wp_callback_func_",num_created_functions));
    sstr.Printf ("def %s (frame, wp, internal_dict):", auto_generated_function_name.c_str());
    
    if (!GenerateFunction(sstr.GetData(), user_input).Success())
        return false;
    
    // Store the name of the auto-generated function to be called.
    output.assign(auto_generated_function_name);
    return true;
}

bool
ScriptInterpreterPython::GetScriptedSummary(const char *python_function_name, lldb::ValueObjectSP valobj,
                                            StructuredData::ObjectSP &callee_wrapper_sp, const TypeSummaryOptions &options,
                                            std::string &retval)
{
    
    Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
    
    if (!valobj.get())
    {
        retval.assign("<no object>");
        return false;
    }

    void *old_callee = nullptr;
    StructuredData::Generic *generic = nullptr;
    if (callee_wrapper_sp)
    {
        generic = callee_wrapper_sp->GetAsGeneric();
        if (generic)
            old_callee = generic->GetValue();
    }
    void* new_callee = old_callee;
    
    bool ret_val;
    if (python_function_name && *python_function_name)
    {
        {
            Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
            {
                TypeSummaryOptionsSP options_sp(new TypeSummaryOptions(options));
                
                Timer scoped_timer ("g_swig_typescript_callback","g_swig_typescript_callback");
                ret_val = g_swig_typescript_callback (python_function_name,
                                                      GetSessionDictionary().get(),
                                                      valobj,
                                                      &new_callee,
                                                      options_sp,
                                                      retval);
            }
        }
    }
    else
    {
        retval.assign("<no function name>");
        return false;
    }
    
    if (new_callee && old_callee != new_callee)
        callee_wrapper_sp.reset(new StructuredPythonObject(new_callee));

    return ret_val;
}

void
ScriptInterpreterPython::Clear ()
{
    // Release any global variables that might have strong references to
    // LLDB objects when clearing the python script interpreter.
    Locker locker(this,
                  ScriptInterpreterPython::Locker::AcquireLock,
                  ScriptInterpreterPython::Locker::FreeAcquiredLock);

    // This may be called as part of Py_Finalize.  In that case the modules are destroyed in random
    // order and we can't guarantee that we can access these.
    if (Py_IsInitialized())
        PyRun_SimpleString("lldb.debugger = None; lldb.target = None; lldb.process = None; lldb.thread = None; lldb.frame = None");
}

bool
ScriptInterpreterPython::BreakpointCallbackFunction 
(
    void *baton,
    StoppointCallbackContext *context,
    user_id_t break_id,
    user_id_t break_loc_id
)
{
    BreakpointOptions::CommandData *bp_option_data = (BreakpointOptions::CommandData *) baton;
    const char *python_function_name = bp_option_data->script_source.c_str();

    if (!context)
        return true;
        
    ExecutionContext exe_ctx (context->exe_ctx_ref);
    Target *target = exe_ctx.GetTargetPtr();
    
    if (!target)
        return true;
        
    Debugger &debugger = target->GetDebugger();
    ScriptInterpreter *script_interpreter = debugger.GetCommandInterpreter().GetScriptInterpreter();
    ScriptInterpreterPython *python_interpreter = (ScriptInterpreterPython *) script_interpreter;
    
    if (!script_interpreter)
        return true;
    
    if (python_function_name && python_function_name[0])
    {
        const StackFrameSP stop_frame_sp (exe_ctx.GetFrameSP());
        BreakpointSP breakpoint_sp = target->GetBreakpointByID (break_id);
        if (breakpoint_sp)
        {
            const BreakpointLocationSP bp_loc_sp (breakpoint_sp->FindLocationByID (break_loc_id));

            if (stop_frame_sp && bp_loc_sp)
            {
                bool ret_val = true;
                {
                    Locker py_lock(python_interpreter, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
                    ret_val = g_swig_breakpoint_callback (python_function_name,
                                                          python_interpreter->m_dictionary_name.c_str(),
                                                          stop_frame_sp, 
                                                          bp_loc_sp);
                }
                return ret_val;
            }
        }
    }
    // We currently always true so we stop in case anything goes wrong when
    // trying to call the script function
    return true;
}

bool
ScriptInterpreterPython::WatchpointCallbackFunction 
(
    void *baton,
    StoppointCallbackContext *context,
    user_id_t watch_id
)
{
    WatchpointOptions::CommandData *wp_option_data = (WatchpointOptions::CommandData *) baton;
    const char *python_function_name = wp_option_data->script_source.c_str();

    if (!context)
        return true;
        
    ExecutionContext exe_ctx (context->exe_ctx_ref);
    Target *target = exe_ctx.GetTargetPtr();
    
    if (!target)
        return true;
        
    Debugger &debugger = target->GetDebugger();
    ScriptInterpreter *script_interpreter = debugger.GetCommandInterpreter().GetScriptInterpreter();
    ScriptInterpreterPython *python_interpreter = (ScriptInterpreterPython *) script_interpreter;
    
    if (!script_interpreter)
        return true;
    
    if (python_function_name && python_function_name[0])
    {
        const StackFrameSP stop_frame_sp (exe_ctx.GetFrameSP());
        WatchpointSP wp_sp = target->GetWatchpointList().FindByID (watch_id);
        if (wp_sp)
        {
            if (stop_frame_sp && wp_sp)
            {
                bool ret_val = true;
                {
                    Locker py_lock(python_interpreter, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
                    ret_val = g_swig_watchpoint_callback (python_function_name,
                                                          python_interpreter->m_dictionary_name.c_str(),
                                                          stop_frame_sp, 
                                                          wp_sp);
                }
                return ret_val;
            }
        }
    }
    // We currently always true so we stop in case anything goes wrong when
    // trying to call the script function
    return true;
}

size_t
ScriptInterpreterPython::CalculateNumChildren(const StructuredData::ObjectSP &implementor_sp)
{
    if (!implementor_sp)
        return 0;
    StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
    if (!generic)
        return 0;
    void *implementor = generic->GetValue();
    if (!implementor)
        return 0;
    
    if (!g_swig_calc_children)
        return 0;

    size_t ret_val = 0;
    
    {
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        ret_val = g_swig_calc_children (implementor);
    }
    
    return ret_val;
}

lldb::ValueObjectSP
ScriptInterpreterPython::GetChildAtIndex(const StructuredData::ObjectSP &implementor_sp, uint32_t idx)
{
    if (!implementor_sp)
        return lldb::ValueObjectSP();

    StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
    if (!generic)
        return lldb::ValueObjectSP();
    void *implementor = generic->GetValue();
    if (!implementor)
        return lldb::ValueObjectSP();
    
    if (!g_swig_get_child_index || !g_swig_cast_to_sbvalue)
        return lldb::ValueObjectSP();
    
    lldb::ValueObjectSP ret_val;
    
    {
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        void* child_ptr = g_swig_get_child_index (implementor,idx);
        if (child_ptr != nullptr && child_ptr != Py_None)
        {
            lldb::SBValue* sb_value_ptr = (lldb::SBValue*)g_swig_cast_to_sbvalue(child_ptr);
            if (sb_value_ptr == nullptr)
                Py_XDECREF(child_ptr);
            else
                ret_val = g_swig_get_valobj_sp_from_sbvalue (sb_value_ptr);
        }
        else
        {
            Py_XDECREF(child_ptr);
        }
    }
    
    return ret_val;
}

int
ScriptInterpreterPython::GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor_sp, const char *child_name)
{
    if (!implementor_sp)
        return UINT32_MAX;

    StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
    if (!generic)
        return UINT32_MAX;
    void *implementor = generic->GetValue();
    if (!implementor)
        return UINT32_MAX;
    
    if (!g_swig_get_index_child)
        return UINT32_MAX;
    
    int ret_val = UINT32_MAX;
    
    {
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        ret_val = g_swig_get_index_child (implementor, child_name);
    }
    
    return ret_val;
}

bool
ScriptInterpreterPython::UpdateSynthProviderInstance(const StructuredData::ObjectSP &implementor_sp)
{
    bool ret_val = false;
    
    if (!implementor_sp)
        return ret_val;

    StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
    if (!generic)
        return ret_val;
    void *implementor = generic->GetValue();
    if (!implementor)
        return ret_val;
    
    if (!g_swig_update_provider)
        return ret_val;
    
    {
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        ret_val = g_swig_update_provider (implementor);
    }
    
    return ret_val;
}

bool
ScriptInterpreterPython::MightHaveChildrenSynthProviderInstance(const StructuredData::ObjectSP &implementor_sp)
{
    bool ret_val = false;
    
    if (!implementor_sp)
        return ret_val;

    StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
    if (!generic)
        return ret_val;
    void *implementor = generic->GetValue();
    if (!implementor)
        return ret_val;
    
    if (!g_swig_mighthavechildren_provider)
        return ret_val;
    
    {
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        ret_val = g_swig_mighthavechildren_provider (implementor);
    }
    
    return ret_val;
}

lldb::ValueObjectSP
ScriptInterpreterPython::GetSyntheticValue(const StructuredData::ObjectSP &implementor_sp)
{
    lldb::ValueObjectSP ret_val(nullptr);
    
    if (!implementor_sp)
        return ret_val;

    StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
    if (!generic)
        return ret_val;
    void *implementor = generic->GetValue();
    if (!implementor)
        return ret_val;
    
    if (!g_swig_getvalue_provider || !g_swig_cast_to_sbvalue || !g_swig_get_valobj_sp_from_sbvalue)
        return ret_val;
    
    {
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        void* child_ptr = g_swig_getvalue_provider (implementor);
        if (child_ptr != nullptr && child_ptr != Py_None)
        {
            lldb::SBValue* sb_value_ptr = (lldb::SBValue*)g_swig_cast_to_sbvalue(child_ptr);
            if (sb_value_ptr == nullptr)
                Py_XDECREF(child_ptr);
            else
                ret_val = g_swig_get_valobj_sp_from_sbvalue (sb_value_ptr);
        }
        else
        {
            Py_XDECREF(child_ptr);
        }
    }
    
    return ret_val;
}

static std::string
ReadPythonBacktrace (PyObject* py_backtrace)
{
    PyObject* traceback_module = nullptr,
    *stringIO_module = nullptr,
    *stringIO_builder = nullptr,
    *stringIO_buffer = nullptr,
    *printTB = nullptr,
    *printTB_args = nullptr,
    *printTB_result = nullptr,
    *stringIO_getvalue = nullptr,
    *printTB_string = nullptr;

    std::string retval("backtrace unavailable");
    
    if (py_backtrace && py_backtrace != Py_None)
    {
        traceback_module = PyImport_ImportModule("traceback");
        stringIO_module = PyImport_ImportModule("StringIO");
        
        if (traceback_module && traceback_module != Py_None && stringIO_module && stringIO_module != Py_None)
        {
            stringIO_builder = PyObject_GetAttrString(stringIO_module, "StringIO");
            if (stringIO_builder && stringIO_builder != Py_None)
            {
                stringIO_buffer = PyObject_CallObject(stringIO_builder, nullptr);
                if (stringIO_buffer && stringIO_buffer != Py_None)
                {
                    printTB = PyObject_GetAttrString(traceback_module, "print_tb");
                    if (printTB && printTB != Py_None)
                    {
                        printTB_args = Py_BuildValue("OOO",py_backtrace,Py_None,stringIO_buffer);
                        printTB_result = PyObject_CallObject(printTB, printTB_args);
                        stringIO_getvalue = PyObject_GetAttrString(stringIO_buffer, "getvalue");
                        if (stringIO_getvalue && stringIO_getvalue != Py_None)
                        {
                            printTB_string = PyObject_CallObject (stringIO_getvalue,nullptr);
                            if (printTB_string && printTB_string != Py_None && PyString_Check(printTB_string))
                                retval.assign(PyString_AsString(printTB_string));
                        }
                    }
                }
            }
        }
    }
    Py_XDECREF(traceback_module);
    Py_XDECREF(stringIO_module);
    Py_XDECREF(stringIO_builder);
    Py_XDECREF(stringIO_buffer);
    Py_XDECREF(printTB);
    Py_XDECREF(printTB_args);
    Py_XDECREF(printTB_result);
    Py_XDECREF(stringIO_getvalue);
    Py_XDECREF(printTB_string);
    return retval;
}

bool
ScriptInterpreterPython::RunScriptFormatKeyword (const char* impl_function,
                                                 Process* process,
                                                 std::string& output,
                                                 Error& error)
{
    bool ret_val;
    if (!process)
    {
        error.SetErrorString("no process");
        return false;
    }
    if (!impl_function || !impl_function[0])
    {
        error.SetErrorString("no function to execute");
        return false;
    }
    if (!g_swig_run_script_keyword_process)
    {
        error.SetErrorString("internal helper function missing");
        return false;
    }
    {
        ProcessSP process_sp(process->shared_from_this());
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        ret_val = g_swig_run_script_keyword_process (impl_function, m_dictionary_name.c_str(), process_sp, output);
        if (!ret_val)
            error.SetErrorString("python script evaluation failed");
    }
    return ret_val;
}

bool
ScriptInterpreterPython::RunScriptFormatKeyword (const char* impl_function,
                                                 Thread* thread,
                                                 std::string& output,
                                                 Error& error)
{
    bool ret_val;
    if (!thread)
    {
        error.SetErrorString("no thread");
        return false;
    }
    if (!impl_function || !impl_function[0])
    {
        error.SetErrorString("no function to execute");
        return false;
    }
    if (!g_swig_run_script_keyword_thread)
    {
        error.SetErrorString("internal helper function missing");
        return false;
    }
    {
        ThreadSP thread_sp(thread->shared_from_this());
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        ret_val = g_swig_run_script_keyword_thread (impl_function, m_dictionary_name.c_str(), thread_sp, output);
        if (!ret_val)
            error.SetErrorString("python script evaluation failed");
    }
    return ret_val;
}

bool
ScriptInterpreterPython::RunScriptFormatKeyword (const char* impl_function,
                                                 Target* target,
                                                 std::string& output,
                                                 Error& error)
{
    bool ret_val;
    if (!target)
    {
        error.SetErrorString("no thread");
        return false;
    }
    if (!impl_function || !impl_function[0])
    {
        error.SetErrorString("no function to execute");
        return false;
    }
    if (!g_swig_run_script_keyword_target)
    {
        error.SetErrorString("internal helper function missing");
        return false;
    }
    {
        TargetSP target_sp(target->shared_from_this());
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        ret_val = g_swig_run_script_keyword_target (impl_function, m_dictionary_name.c_str(), target_sp, output);
        if (!ret_val)
            error.SetErrorString("python script evaluation failed");
    }
    return ret_val;
}

bool
ScriptInterpreterPython::RunScriptFormatKeyword (const char* impl_function,
                                                 StackFrame* frame,
                                                 std::string& output,
                                                 Error& error)
{
    bool ret_val;
    if (!frame)
    {
        error.SetErrorString("no frame");
        return false;
    }
    if (!impl_function || !impl_function[0])
    {
        error.SetErrorString("no function to execute");
        return false;
    }
    if (!g_swig_run_script_keyword_frame)
    {
        error.SetErrorString("internal helper function missing");
        return false;
    }
    {
        StackFrameSP frame_sp(frame->shared_from_this());
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        ret_val = g_swig_run_script_keyword_frame (impl_function, m_dictionary_name.c_str(), frame_sp, output);
        if (!ret_val)
            error.SetErrorString("python script evaluation failed");
    }
    return ret_val;
}
    
bool
ScriptInterpreterPython::RunScriptFormatKeyword (const char* impl_function,
                                                 ValueObject *value,
                                                 std::string& output,
                                                 Error& error)
{
    bool ret_val;
    if (!value)
    {
        error.SetErrorString("no value");
        return false;
    }
    if (!impl_function || !impl_function[0])
    {
        error.SetErrorString("no function to execute");
        return false;
    }
    if (!g_swig_run_script_keyword_value)
    {
        error.SetErrorString("internal helper function missing");
        return false;
    }
    {
        ValueObjectSP value_sp(value->GetSP());
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        ret_val = g_swig_run_script_keyword_value (impl_function, m_dictionary_name.c_str(), value_sp, output);
        if (!ret_val)
            error.SetErrorString("python script evaluation failed");
    }
    return ret_val;
}

uint64_t replace_all(std::string& str, const std::string& oldStr, const std::string& newStr)
{
    size_t pos = 0;
    uint64_t matches = 0;
    while((pos = str.find(oldStr, pos)) != std::string::npos)
    {
        matches++;
        str.replace(pos, oldStr.length(), newStr);
        pos += newStr.length();
    }
    return matches;
}

bool
ScriptInterpreterPython::LoadScriptingModule(const char *pathname, bool can_reload, bool init_session, lldb_private::Error &error,
                                             StructuredData::ObjectSP *module_sp)
{
    if (!pathname || !pathname[0])
    {
        error.SetErrorString("invalid pathname");
        return false;
    }
    
    if (!g_swig_call_module_init)
    {
        error.SetErrorString("internal helper function missing");
        return false;
    }
    
    lldb::DebuggerSP debugger_sp = m_interpreter.GetDebugger().shared_from_this();

    {
        FileSpec target_file(pathname, true);
        std::string basename(target_file.GetFilename().GetCString());
        
        StreamString command_stream;

        // Before executing Pyton code, lock the GIL.
        Locker py_lock (this,
                        Locker::AcquireLock      | (init_session ? Locker::InitSession     : 0) | Locker::NoSTDIN,
                        Locker::FreeAcquiredLock | (init_session ? Locker::TearDownSession : 0));
        
        if (target_file.GetFileType() == FileSpec::eFileTypeInvalid ||
            target_file.GetFileType() == FileSpec::eFileTypeUnknown)
        {
            // if not a valid file of any sort, check if it might be a filename still
            // dot can't be used but / and \ can, and if either is found, reject
            if (strchr(pathname,'\\') || strchr(pathname,'/'))
            {
                error.SetErrorString("invalid pathname");
                return false;
            }
            basename = pathname; // not a filename, probably a package of some sort, let it go through
        }
        else if (target_file.GetFileType() == FileSpec::eFileTypeDirectory ||
                 target_file.GetFileType() == FileSpec::eFileTypeRegular ||
                 target_file.GetFileType() == FileSpec::eFileTypeSymbolicLink)
        {
            std::string directory(target_file.GetDirectory().GetCString());
            replace_all(directory,"'","\\'");
            
            // now make sure that Python has "directory" in the search path
            StreamString command_stream;
            command_stream.Printf("if not (sys.path.__contains__('%s')):\n    sys.path.insert(1,'%s');\n\n",
                                  directory.c_str(),
                                  directory.c_str());
            bool syspath_retval = ExecuteMultipleLines(command_stream.GetData(), ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false).SetSetLLDBGlobals(false)).Success();
            if (!syspath_retval)
            {
                error.SetErrorString("Python sys.path handling failed");
                return false;
            }
            
            // strip .py or .pyc extension
            ConstString extension = target_file.GetFileNameExtension();
            if (extension)
            {
                if (::strcmp(extension.GetCString(), "py") == 0)
                    basename.resize(basename.length()-3);
                else if(::strcmp(extension.GetCString(), "pyc") == 0)
                    basename.resize(basename.length()-4);
            }
        }
        else
        {
            error.SetErrorString("no known way to import this module specification");
            return false;
        }
        
        // check if the module is already import-ed
        command_stream.Clear();
        command_stream.Printf("sys.modules.__contains__('%s')",basename.c_str());
        bool does_contain = false;
        // this call will succeed if the module was ever imported in any Debugger in the lifetime of the process
        // in which this LLDB framework is living
        bool was_imported_globally = (ExecuteOneLineWithReturn(command_stream.GetData(),
                                                               ScriptInterpreterPython::eScriptReturnTypeBool,
                                                               &does_contain,
                                                               ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false).SetSetLLDBGlobals(false)) && does_contain);
        // this call will fail if the module was not imported in this Debugger before
        command_stream.Clear();
        command_stream.Printf("sys.getrefcount(%s)",basename.c_str());
        bool was_imported_locally = !(GetSessionDictionary().GetItemForKey(basename.c_str()).IsNULLOrNone());
        
        bool was_imported = (was_imported_globally || was_imported_locally);
        
        if (was_imported == true && can_reload == false)
        {
            error.SetErrorString("module already imported");
            return false;
        }

        // now actually do the import
        command_stream.Clear();
        
        if (was_imported)
        {
            if (!was_imported_locally)
                command_stream.Printf("import %s ; reload(%s)",basename.c_str(),basename.c_str());
            else
                command_stream.Printf("reload(%s)",basename.c_str());
        }
        else
            command_stream.Printf("import %s",basename.c_str());
        
        error = ExecuteMultipleLines(command_stream.GetData(), ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false).SetSetLLDBGlobals(false));
        if (error.Fail())
            return false;
        
        // if we are here, everything worked
        // call __lldb_init_module(debugger,dict)
        if (!g_swig_call_module_init (basename.c_str(),
                                      m_dictionary_name.c_str(),
                                      debugger_sp))
        {
            error.SetErrorString("calling __lldb_init_module failed");
            return false;
        }
        
        if (module_sp)
        {
            // everything went just great, now set the module object
            command_stream.Clear();
            command_stream.Printf("%s",basename.c_str());
            void* module_pyobj = nullptr;
            if (ExecuteOneLineWithReturn(command_stream.GetData(),ScriptInterpreter::eScriptReturnTypeOpaqueObject,&module_pyobj) && module_pyobj)
                module_sp->reset(new StructuredPythonObject(module_pyobj));
        }
        
        return true;
    }
}

bool
ScriptInterpreterPython::IsReservedWord (const char* word)
{
    StreamString command_stream;
    command_stream.Printf("keyword.iskeyword('%s')", word);
    bool result;
    ExecuteScriptOptions options;
    options.SetEnableIO(false);
    options.SetMaskoutErrors(true);
    options.SetSetLLDBGlobals(false);
    if (ExecuteOneLineWithReturn(command_stream.GetData(), ScriptInterpreter::eScriptReturnTypeBool, &result, options))
        return result;
    return false;
}

ScriptInterpreterPython::SynchronicityHandler::SynchronicityHandler (lldb::DebuggerSP debugger_sp,
                                                                     ScriptedCommandSynchronicity synchro) :
    m_debugger_sp(debugger_sp),
    m_synch_wanted(synchro),
    m_old_asynch(debugger_sp->GetAsyncExecution())
{
    if (m_synch_wanted == eScriptedCommandSynchronicitySynchronous)
        m_debugger_sp->SetAsyncExecution(false);
    else if (m_synch_wanted == eScriptedCommandSynchronicityAsynchronous)
        m_debugger_sp->SetAsyncExecution(true);
}

ScriptInterpreterPython::SynchronicityHandler::~SynchronicityHandler()
{
    if (m_synch_wanted != eScriptedCommandSynchronicityCurrentValue)
        m_debugger_sp->SetAsyncExecution(m_old_asynch);
}

bool
ScriptInterpreterPython::RunScriptBasedCommand(const char* impl_function,
                                               const char* args,
                                               ScriptedCommandSynchronicity synchronicity,
                                               lldb_private::CommandReturnObject& cmd_retobj,
                                               Error& error,
                                               const lldb_private::ExecutionContext& exe_ctx)
{
    if (!impl_function)
    {
        error.SetErrorString("no function to execute");
        return false;
    }
    
    if (!g_swig_call_command)
    {
        error.SetErrorString("no helper function to run scripted commands");
        return false;
    }
    
    lldb::DebuggerSP debugger_sp = m_interpreter.GetDebugger().shared_from_this();
    lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx));
    
    if (!debugger_sp.get())
    {
        error.SetErrorString("invalid Debugger pointer");
        return false;
   }
    
    bool ret_val = false;
    
    std::string err_msg;

    {
        Locker py_lock(this,
                       Locker::AcquireLock | Locker::InitSession | (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN),
                       Locker::FreeLock    | Locker::TearDownSession);
        
        SynchronicityHandler synch_handler(debugger_sp,
                                           synchronicity);
        
        ret_val = g_swig_call_command       (impl_function,
                                             m_dictionary_name.c_str(),
                                             debugger_sp,
                                             args,
                                             cmd_retobj,
                                             exe_ctx_ref_sp);
    }
    
    if (!ret_val)
        error.SetErrorString("unable to execute script function");
    else
        error.Clear();
    
    return ret_val;
}

bool
ScriptInterpreterPython::RunScriptBasedCommand (StructuredData::GenericSP impl_obj_sp,
                                                const char* args,
                                                ScriptedCommandSynchronicity synchronicity,
                                                lldb_private::CommandReturnObject& cmd_retobj,
                                                Error& error,
                                                const lldb_private::ExecutionContext& exe_ctx)
{
    if (!impl_obj_sp || !impl_obj_sp->IsValid())
    {
        error.SetErrorString("no function to execute");
        return false;
    }
    
    if (!g_swig_call_command_object)
    {
        error.SetErrorString("no helper function to run scripted commands");
        return false;
    }
    
    lldb::DebuggerSP debugger_sp = m_interpreter.GetDebugger().shared_from_this();
    lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx));
    
    if (!debugger_sp.get())
    {
        error.SetErrorString("invalid Debugger pointer");
        return false;
    }
    
    bool ret_val = false;
    
    std::string err_msg;
    
    {
        Locker py_lock(this,
                       Locker::AcquireLock | Locker::InitSession | (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN),
                       Locker::FreeLock    | Locker::TearDownSession);
        
        SynchronicityHandler synch_handler(debugger_sp,
                                           synchronicity);
        
        ret_val = g_swig_call_command_object      (impl_obj_sp->GetValue(),
                                                   debugger_sp,
                                                   args,
                                                   cmd_retobj,
                                                   exe_ctx_ref_sp);
    }
    
    if (!ret_val)
        error.SetErrorString("unable to execute script function");
    else
        error.Clear();

    return ret_val;
}

// in Python, a special attribute __doc__ contains the docstring
// for an object (function, method, class, ...) if any is defined
// Otherwise, the attribute's value is None
bool
ScriptInterpreterPython::GetDocumentationForItem(const char* item, std::string& dest)
{
	dest.clear();
	if (!item || !*item)
		return false;
    std::string command(item);
    command += ".__doc__";
    
    char* result_ptr = nullptr; // Python is going to point this to valid data if ExecuteOneLineWithReturn returns successfully
    
    if (ExecuteOneLineWithReturn (command.c_str(),
                                  ScriptInterpreter::eScriptReturnTypeCharStrOrNone,
                                  &result_ptr,
                                  ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false)))
    {
        if (result_ptr)
            dest.assign(result_ptr);
        return true;
    }
    else
    {
        StreamString str_stream;
        str_stream.Printf("Function %s was not found. Containing module might be missing.",item);
        dest.assign(str_stream.GetData());
        return false;
    }
}

bool
ScriptInterpreterPython::GetShortHelpForCommandObject (StructuredData::GenericSP cmd_obj_sp,
                                                       std::string& dest)
{
    bool got_string = false;
    dest.clear();
    
    Locker py_lock (this,
                    Locker::AcquireLock | Locker::NoSTDIN,
                    Locker::FreeLock);
    
    static char callee_name[] = "get_short_help";
    
    if (!cmd_obj_sp)
        return false;
    
    PyObject* implementor = (PyObject*)cmd_obj_sp->GetValue();
    
    if (implementor == nullptr || implementor == Py_None)
        return false;
    
    PyObject* pmeth  = PyObject_GetAttrString(implementor, callee_name);
    
    if (PyErr_Occurred())
    {
        PyErr_Clear();
    }
    
    if (pmeth == nullptr || pmeth == Py_None)
    {
        Py_XDECREF(pmeth);
        return false;
    }
    
    if (PyCallable_Check(pmeth) == 0)
    {
        if (PyErr_Occurred())
        {
            PyErr_Clear();
        }
        
        Py_XDECREF(pmeth);
        return false;
    }
    
    if (PyErr_Occurred())
    {
        PyErr_Clear();
    }
    
    Py_XDECREF(pmeth);
    
    // right now we know this function exists and is callable..
    PyObject* py_return = PyObject_CallMethod(implementor, callee_name, nullptr);
    
    // if it fails, print the error but otherwise go on
    if (PyErr_Occurred())
    {
        PyErr_Print();
        PyErr_Clear();
    }
    
    if (py_return != nullptr && py_return != Py_None)
    {
        if (PyString_Check(py_return))
        {
            dest.assign(PyString_AsString(py_return));
            got_string = true;
        }
    }
    Py_XDECREF(py_return);
    
    return got_string;
}

bool
ScriptInterpreterPython::GetLongHelpForCommandObject (StructuredData::GenericSP cmd_obj_sp,
                                                      std::string& dest)
{
    bool got_string = false;
    dest.clear();
    
    Locker py_lock (this,
                    Locker::AcquireLock | Locker::NoSTDIN,
                    Locker::FreeLock);
    
    static char callee_name[] = "get_long_help";
    
    if (!cmd_obj_sp)
        return false;
    
    PyObject* implementor = (PyObject*)cmd_obj_sp->GetValue();
    
    if (implementor == nullptr || implementor == Py_None)
        return false;
    
    PyObject* pmeth  = PyObject_GetAttrString(implementor, callee_name);
    
    if (PyErr_Occurred())
    {
        PyErr_Clear();
    }
    
    if (pmeth == nullptr || pmeth == Py_None)
    {
        Py_XDECREF(pmeth);
        return false;
    }
    
    if (PyCallable_Check(pmeth) == 0)
    {
        if (PyErr_Occurred())
        {
            PyErr_Clear();
        }
        
        Py_XDECREF(pmeth);
        return false;
    }
    
    if (PyErr_Occurred())
    {
        PyErr_Clear();
    }
    
    Py_XDECREF(pmeth);
    
    // right now we know this function exists and is callable..
    PyObject* py_return = PyObject_CallMethod(implementor, callee_name, nullptr);
    
    // if it fails, print the error but otherwise go on
    if (PyErr_Occurred())
    {
        PyErr_Print();
        PyErr_Clear();
    }
    
    if (py_return != nullptr && py_return != Py_None)
    {
        if (PyString_Check(py_return))
        {
            dest.assign(PyString_AsString(py_return));
            got_string = true;
        }
    }
    Py_XDECREF(py_return);
    
    return got_string;
}

std::unique_ptr<ScriptInterpreterLocker>
ScriptInterpreterPython::AcquireInterpreterLock ()
{
    std::unique_ptr<ScriptInterpreterLocker> py_lock(new Locker(this,
                                                                Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN,
                                                                Locker::FreeLock | Locker::TearDownSession));
    return py_lock;
}

void
ScriptInterpreterPython::InitializeInterpreter (SWIGInitCallback swig_init_callback,
                                                SWIGBreakpointCallbackFunction swig_breakpoint_callback,
                                                SWIGWatchpointCallbackFunction swig_watchpoint_callback,
                                                SWIGPythonTypeScriptCallbackFunction swig_typescript_callback,
                                                SWIGPythonCreateSyntheticProvider swig_synthetic_script,
                                                SWIGPythonCreateCommandObject swig_create_cmd,
                                                SWIGPythonCalculateNumChildren swig_calc_children,
                                                SWIGPythonGetChildAtIndex swig_get_child_index,
                                                SWIGPythonGetIndexOfChildWithName swig_get_index_child,
                                                SWIGPythonCastPyObjectToSBValue swig_cast_to_sbvalue ,
                                                SWIGPythonGetValueObjectSPFromSBValue swig_get_valobj_sp_from_sbvalue,
                                                SWIGPythonUpdateSynthProviderInstance swig_update_provider,
                                                SWIGPythonMightHaveChildrenSynthProviderInstance swig_mighthavechildren_provider,
                                                SWIGPythonGetValueSynthProviderInstance swig_getvalue_provider,
                                                SWIGPythonCallCommand swig_call_command,
                                                SWIGPythonCallCommandObject swig_call_command_object,
                                                SWIGPythonCallModuleInit swig_call_module_init,
                                                SWIGPythonCreateOSPlugin swig_create_os_plugin,
                                                SWIGPythonScriptKeyword_Process swig_run_script_keyword_process,
                                                SWIGPythonScriptKeyword_Thread swig_run_script_keyword_thread,
                                                SWIGPythonScriptKeyword_Target swig_run_script_keyword_target,
                                                SWIGPythonScriptKeyword_Frame swig_run_script_keyword_frame,
                                                SWIGPythonScriptKeyword_Value swig_run_script_keyword_value,
                                                SWIGPython_GetDynamicSetting swig_plugin_get,
                                                SWIGPythonCreateScriptedThreadPlan swig_thread_plan_script,
                                                SWIGPythonCallThreadPlan swig_call_thread_plan)
{
    g_swig_init_callback = swig_init_callback;
    g_swig_breakpoint_callback = swig_breakpoint_callback;
    g_swig_watchpoint_callback = swig_watchpoint_callback;
    g_swig_typescript_callback = swig_typescript_callback;
    g_swig_synthetic_script = swig_synthetic_script;
    g_swig_create_cmd = swig_create_cmd;
    g_swig_calc_children = swig_calc_children;
    g_swig_get_child_index = swig_get_child_index;
    g_swig_get_index_child = swig_get_index_child;
    g_swig_cast_to_sbvalue = swig_cast_to_sbvalue;
    g_swig_get_valobj_sp_from_sbvalue = swig_get_valobj_sp_from_sbvalue;
    g_swig_update_provider = swig_update_provider;
    g_swig_mighthavechildren_provider = swig_mighthavechildren_provider;
    g_swig_getvalue_provider = swig_getvalue_provider;
    g_swig_call_command = swig_call_command;
    g_swig_call_command_object = swig_call_command_object;
    g_swig_call_module_init = swig_call_module_init;
    g_swig_create_os_plugin = swig_create_os_plugin;
    g_swig_run_script_keyword_process = swig_run_script_keyword_process;
    g_swig_run_script_keyword_thread = swig_run_script_keyword_thread;
    g_swig_run_script_keyword_target = swig_run_script_keyword_target;
    g_swig_run_script_keyword_frame = swig_run_script_keyword_frame;
    g_swig_run_script_keyword_value = swig_run_script_keyword_value;
    g_swig_plugin_get = swig_plugin_get;
    g_swig_thread_plan_script = swig_thread_plan_script;
    g_swig_call_thread_plan = swig_call_thread_plan;
}

void
ScriptInterpreterPython::InitializePrivate ()
{
    static int g_initialized = false;
    
    if (g_initialized)
        return;
    
    g_initialized = true;

    Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);

    // Python will muck with STDIN terminal state, so save off any current TTY
    // settings so we can restore them.
    TerminalState stdin_tty_state;
    stdin_tty_state.Save(STDIN_FILENO, false);

    PyGILState_STATE gstate;
    Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT | LIBLLDB_LOG_VERBOSE));
    bool threads_already_initialized = false;
    if (PyEval_ThreadsInitialized ()) {
        gstate = PyGILState_Ensure ();
        if (log)
            log->Printf("Ensured PyGILState. Previous state = %slocked\n", gstate == PyGILState_UNLOCKED ? "un" : "");
        threads_already_initialized = true;
    } else {
        // InitThreads acquires the GIL if it hasn't been called before.
        PyEval_InitThreads ();
    }
    Py_InitializeEx (0);

    // Initialize SWIG after setting up python
    if (g_swig_init_callback)
        g_swig_init_callback ();

    // Update the path python uses to search for modules to include the current directory.

    PyRun_SimpleString ("import sys");
    PyRun_SimpleString ("sys.path.append ('.')");

    // Find the module that owns this code and use that path we get to
    // set the sys.path appropriately.

    FileSpec file_spec;
    char python_dir_path[PATH_MAX];
    if (HostInfo::GetLLDBPath(ePathTypePythonDir, file_spec))
    {
        std::string python_path("sys.path.insert(0,\"");
        size_t orig_len = python_path.length();
        if (file_spec.GetPath(python_dir_path, sizeof (python_dir_path)))
        {
            python_path.append (python_dir_path);
            python_path.append ("\")");
            PyRun_SimpleString (python_path.c_str());
            python_path.resize (orig_len);
        }

        if (HostInfo::GetLLDBPath(ePathTypeLLDBShlibDir, file_spec))
        {
            if (file_spec.GetPath(python_dir_path, sizeof (python_dir_path)))
            {
                python_path.append (python_dir_path);
                python_path.append ("\")");
                PyRun_SimpleString (python_path.c_str());
                python_path.resize (orig_len);
            }
        }
    }

    // Importing 'lldb' module calls SBDebugger::Initialize, which calls Debugger::Initialize, which increments a
    // global debugger ref-count; therefore we need to check the ref-count before and after importing lldb, and if the
    // ref-count increased we need to call Debugger::Terminate here to decrement the ref-count so that when the final 
    // call to Debugger::Terminate is made, the ref-count has the correct value. 
    
    int old_count = Debugger::TestDebuggerRefCount ();

    PyRun_SimpleString ("sys.dont_write_bytecode = 1; import lldb.embedded_interpreter; from lldb.embedded_interpreter import run_python_interpreter; from lldb.embedded_interpreter import run_one_line");

    int new_count = Debugger::TestDebuggerRefCount ();
    
    if (new_count > old_count)
        Debugger::Terminate ();

    if (threads_already_initialized) {
        if (log)
            log->Printf("Releasing PyGILState. Returning to state = %slocked\n", gstate == PyGILState_UNLOCKED ? "un" : "");
        PyGILState_Release (gstate);
    } else {
        // We initialized the threads in this function, just unlock the GIL.
        PyEval_SaveThread();
    }

    stdin_tty_state.Restore();
}

//void
//ScriptInterpreterPython::Terminate ()
//{
//    // We are intentionally NOT calling Py_Finalize here (this would be the logical place to call it).  Calling
//    // Py_Finalize here causes test suite runs to seg fault:  The test suite runs in Python.  It registers 
//    // SBDebugger::Terminate to be called 'at_exit'.  When the test suite Python harness finishes up, it calls 
//    // Py_Finalize, which calls all the 'at_exit' registered functions.  SBDebugger::Terminate calls Debugger::Terminate,
//    // which calls lldb::Terminate, which calls ScriptInterpreter::Terminate, which calls 
//    // ScriptInterpreterPython::Terminate.  So if we call Py_Finalize here, we end up with Py_Finalize being called from
//    // within Py_Finalize, which results in a seg fault.
//    //
//    // Since this function only gets called when lldb is shutting down and going away anyway, the fact that we don't
//    // actually call Py_Finalize should not cause any problems (everything should shut down/go away anyway when the
//    // process exits).
//    //
////    Py_Finalize ();
//}

#endif // #ifdef LLDB_DISABLE_PYTHON
