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

#include "lldb/Core/PluginManager.h"

#include <limits.h>

#include <string>
#include <vector>

#include "lldb/Core/Debugger.h"
#include "lldb/Core/Error.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/Mutex.h"
#include "lldb/Interpreter/OptionValueProperties.h"

#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DynamicLibrary.h"

using namespace lldb;
using namespace lldb_private;

enum PluginAction
{
    ePluginRegisterInstance,
    ePluginUnregisterInstance,
    ePluginGetInstanceAtIndex
};


typedef bool (*PluginInitCallback) (void);
typedef void (*PluginTermCallback) (void);

struct PluginInfo
{
    PluginInfo()
        : plugin_init_callback(nullptr), plugin_term_callback(nullptr)
    {
    }

    llvm::sys::DynamicLibrary library;
    PluginInitCallback plugin_init_callback;
    PluginTermCallback plugin_term_callback;
};

typedef std::map<FileSpec, PluginInfo> PluginTerminateMap;

static Mutex &
GetPluginMapMutex ()
{
    static Mutex g_plugin_map_mutex (Mutex::eMutexTypeRecursive);
    return g_plugin_map_mutex;
}

static PluginTerminateMap &
GetPluginMap ()
{
    static PluginTerminateMap g_plugin_map;
    return g_plugin_map;
}

static bool
PluginIsLoaded (const FileSpec &plugin_file_spec)
{
    Mutex::Locker locker (GetPluginMapMutex ());
    PluginTerminateMap &plugin_map = GetPluginMap ();
    return plugin_map.find (plugin_file_spec) != plugin_map.end();
}
    
static void
SetPluginInfo (const FileSpec &plugin_file_spec, const PluginInfo &plugin_info)
{
    Mutex::Locker locker (GetPluginMapMutex ());
    PluginTerminateMap &plugin_map = GetPluginMap ();
    assert (plugin_map.find (plugin_file_spec) == plugin_map.end());
    plugin_map[plugin_file_spec] = plugin_info;
}

template <typename FPtrTy>
static FPtrTy
CastToFPtr (void *VPtr)
{
    return reinterpret_cast<FPtrTy>(reinterpret_cast<intptr_t>(VPtr));
}

static FileSpec::EnumerateDirectoryResult 
LoadPluginCallback 
(
    void *baton,
    FileSpec::FileType file_type,
    const FileSpec &file_spec
)
{
//    PluginManager *plugin_manager = (PluginManager *)baton;
    Error error;
    
    // If we have a regular file, a symbolic link or unknown file type, try
    // and process the file. We must handle unknown as sometimes the directory 
    // enumeration might be enumerating a file system that doesn't have correct
    // file type information.
    if (file_type == FileSpec::eFileTypeRegular         ||
        file_type == FileSpec::eFileTypeSymbolicLink    ||
        file_type == FileSpec::eFileTypeUnknown          )
    {
        FileSpec plugin_file_spec (file_spec);
        plugin_file_spec.ResolvePath();
        
        if (PluginIsLoaded (plugin_file_spec))
            return FileSpec::eEnumerateDirectoryResultNext;
        else
        {
            PluginInfo plugin_info;

            std::string pluginLoadError;
            plugin_info.library = llvm::sys::DynamicLibrary::getPermanentLibrary (plugin_file_spec.GetPath().c_str(), &pluginLoadError);
            if (plugin_info.library.isValid())
            {
                bool success = false;
                plugin_info.plugin_init_callback =
                    CastToFPtr<PluginInitCallback>(plugin_info.library.getAddressOfSymbol("LLDBPluginInitialize"));
                if (plugin_info.plugin_init_callback)
                {
                    // Call the plug-in "bool LLDBPluginInitialize(void)" function
                    success = plugin_info.plugin_init_callback();
                }

                if (success)
                {
                    // It is ok for the "LLDBPluginTerminate" symbol to be NULL
                    plugin_info.plugin_term_callback =
                        CastToFPtr<PluginTermCallback>(plugin_info.library.getAddressOfSymbol("LLDBPluginTerminate"));
                }
                else 
                {
                    // The initialize function returned FALSE which means the plug-in might not be
                    // compatible, or might be too new or too old, or might not want to run on this
                    // machine.  Set it to a default-constructed instance to invalidate it.
                    plugin_info = PluginInfo();
                }

                // Regardless of success or failure, cache the plug-in load
                // in our plug-in info so we don't try to load it again and 
                // again.
                SetPluginInfo (plugin_file_spec, plugin_info);

                return FileSpec::eEnumerateDirectoryResultNext;
            }
        }
    }
    
    if (file_type == FileSpec::eFileTypeUnknown     ||
        file_type == FileSpec::eFileTypeDirectory   ||
        file_type == FileSpec::eFileTypeSymbolicLink )
    {
        // Try and recurse into anything that a directory or symbolic link. 
        // We must also do this for unknown as sometimes the directory enumeration
        // might be enumerating a file system that doesn't have correct file type
        // information.
        return FileSpec::eEnumerateDirectoryResultEnter;
    }

    return FileSpec::eEnumerateDirectoryResultNext;
}


void
PluginManager::Initialize ()
{
#if 1
    FileSpec dir_spec;
    const bool find_directories = true;
    const bool find_files = true;
    const bool find_other = true;
    char dir_path[PATH_MAX];
    if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec))
    {
        if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
        {
            FileSpec::EnumerateDirectory (dir_path, 
                                          find_directories,
                                          find_files,
                                          find_other,
                                          LoadPluginCallback,
                                          NULL);
        }
    }

    if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec))
    {
        if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
        {
            FileSpec::EnumerateDirectory (dir_path, 
                                          find_directories,
                                          find_files,
                                          find_other,
                                          LoadPluginCallback,
                                          NULL);
        }
    }
#endif
}

void
PluginManager::Terminate ()
{
    Mutex::Locker locker (GetPluginMapMutex ());
    PluginTerminateMap &plugin_map = GetPluginMap ();
    
    PluginTerminateMap::const_iterator pos, end = plugin_map.end();
    for (pos = plugin_map.begin(); pos != end; ++pos)
    {
        // Call the plug-in "void LLDBPluginTerminate (void)" function if there
        // is one (if the symbol was not NULL).
        if (pos->second.library.isValid())
        {
            if (pos->second.plugin_term_callback)
                pos->second.plugin_term_callback();
        }
    }
    plugin_map.clear();
}


#pragma mark ABI


struct ABIInstance
{
    ABIInstance() :
        name(),
        description(),
        create_callback(NULL)
    {
    }

    ConstString name;
    std::string description;
    ABICreateInstance create_callback;
};

typedef std::vector<ABIInstance> ABIInstances;

static Mutex &
GetABIInstancesMutex ()
{
    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
    return g_instances_mutex;
}

static ABIInstances &
GetABIInstances ()
{
    static ABIInstances g_instances;
    return g_instances;
}

bool
PluginManager::RegisterPlugin
(
    const ConstString &name,
    const char *description,
    ABICreateInstance create_callback
)
{
    if (create_callback)
    {
        ABIInstance instance;
        assert ((bool)name);
        instance.name = name;
        if (description && description[0])
            instance.description = description;
        instance.create_callback = create_callback;
        Mutex::Locker locker (GetABIInstancesMutex ());
        GetABIInstances ().push_back (instance);
        return true;
    }
    return false;
}

bool
PluginManager::UnregisterPlugin (ABICreateInstance create_callback)
{
    if (create_callback)
    {
        Mutex::Locker locker (GetABIInstancesMutex ());
        ABIInstances &instances = GetABIInstances ();

        ABIInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (pos->create_callback == create_callback)
            {
                instances.erase(pos);
                return true;
            }
        }
    }
    return false;
}

ABICreateInstance
PluginManager::GetABICreateCallbackAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetABIInstancesMutex ());
    ABIInstances &instances = GetABIInstances ();
    if (idx < instances.size())
        return instances[idx].create_callback;
    return NULL;
}

ABICreateInstance
PluginManager::GetABICreateCallbackForPluginName (const ConstString &name)
{
    if (name)
    {
        Mutex::Locker locker (GetABIInstancesMutex ());
        ABIInstances &instances = GetABIInstances ();

        ABIInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (name == pos->name)
                return pos->create_callback;
        }
    }
    return NULL;
}


#pragma mark Disassembler


struct DisassemblerInstance
{
    DisassemblerInstance() :
        name(),
        description(),
        create_callback(NULL)
    {
    }

    ConstString name;
    std::string description;
    DisassemblerCreateInstance create_callback;
};

typedef std::vector<DisassemblerInstance> DisassemblerInstances;

static Mutex &
GetDisassemblerMutex ()
{
    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
    return g_instances_mutex;
}

static DisassemblerInstances &
GetDisassemblerInstances ()
{
    static DisassemblerInstances g_instances;
    return g_instances;
}

bool
PluginManager::RegisterPlugin
(
    const ConstString &name,
    const char *description,
    DisassemblerCreateInstance create_callback
)
{
    if (create_callback)
    {
        DisassemblerInstance instance;
        assert ((bool)name);
        instance.name = name;
        if (description && description[0])
            instance.description = description;
        instance.create_callback = create_callback;
        Mutex::Locker locker (GetDisassemblerMutex ());
        GetDisassemblerInstances ().push_back (instance);
        return true;
    }
    return false;
}

bool
PluginManager::UnregisterPlugin (DisassemblerCreateInstance create_callback)
{
    if (create_callback)
    {
        Mutex::Locker locker (GetDisassemblerMutex ());
        DisassemblerInstances &instances = GetDisassemblerInstances ();
        
        DisassemblerInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (pos->create_callback == create_callback)
            {
                instances.erase(pos);
                return true;
            }
        }
    }
    return false;
}

DisassemblerCreateInstance
PluginManager::GetDisassemblerCreateCallbackAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetDisassemblerMutex ());
    DisassemblerInstances &instances = GetDisassemblerInstances ();
    if (idx < instances.size())
        return instances[idx].create_callback;
    return NULL;
}

DisassemblerCreateInstance
PluginManager::GetDisassemblerCreateCallbackForPluginName (const ConstString &name)
{
    if (name)
    {
        Mutex::Locker locker (GetDisassemblerMutex ());
        DisassemblerInstances &instances = GetDisassemblerInstances ();
        
        DisassemblerInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (name == pos->name)
                return pos->create_callback;
        }
    }
    return NULL;
}



#pragma mark DynamicLoader


struct DynamicLoaderInstance
{
    DynamicLoaderInstance() :
        name(),
        description(),
        create_callback(NULL),
        debugger_init_callback (NULL)
    {
    }

    ConstString name;
    std::string description;
    DynamicLoaderCreateInstance create_callback;
    DebuggerInitializeCallback debugger_init_callback;
};

typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances;


static Mutex &
GetDynamicLoaderMutex ()
{
    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
    return g_instances_mutex;
}

static DynamicLoaderInstances &
GetDynamicLoaderInstances ()
{
    static DynamicLoaderInstances g_instances;
    return g_instances;
}


bool
PluginManager::RegisterPlugin
(
    const ConstString &name,
    const char *description,
    DynamicLoaderCreateInstance create_callback,
    DebuggerInitializeCallback debugger_init_callback
)
{
    if (create_callback)
    {
        DynamicLoaderInstance instance;
        assert ((bool)name);
        instance.name = name;
        if (description && description[0])
            instance.description = description;
        instance.create_callback = create_callback;
        instance.debugger_init_callback = debugger_init_callback;
        Mutex::Locker locker (GetDynamicLoaderMutex ());
        GetDynamicLoaderInstances ().push_back (instance);
    }
    return false;
}

bool
PluginManager::UnregisterPlugin (DynamicLoaderCreateInstance create_callback)
{
    if (create_callback)
    {
        Mutex::Locker locker (GetDynamicLoaderMutex ());
        DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
        
        DynamicLoaderInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (pos->create_callback == create_callback)
            {
                instances.erase(pos);
                return true;
            }
        }
    }
    return false;
}

DynamicLoaderCreateInstance
PluginManager::GetDynamicLoaderCreateCallbackAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetDynamicLoaderMutex ());
    DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
    if (idx < instances.size())
        return instances[idx].create_callback;
    return NULL;
}

DynamicLoaderCreateInstance
PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const ConstString &name)
{
    if (name)
    {
        Mutex::Locker locker (GetDynamicLoaderMutex ());
        DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
        
        DynamicLoaderInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (name == pos->name)
                return pos->create_callback;
        }
    }
    return NULL;
}

#pragma mark JITLoader


struct JITLoaderInstance
{
    JITLoaderInstance() :
        name(),
        description(),
        create_callback(NULL),
        debugger_init_callback (NULL)
    {
    }

    ConstString name;
    std::string description;
    JITLoaderCreateInstance create_callback;
    DebuggerInitializeCallback debugger_init_callback;
};

typedef std::vector<JITLoaderInstance> JITLoaderInstances;


static Mutex &
GetJITLoaderMutex ()
{
    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
    return g_instances_mutex;
}

static JITLoaderInstances &
GetJITLoaderInstances ()
{
    static JITLoaderInstances g_instances;
    return g_instances;
}


bool
PluginManager::RegisterPlugin
(
    const ConstString &name,
    const char *description,
    JITLoaderCreateInstance create_callback,
    DebuggerInitializeCallback debugger_init_callback
)
{
    if (create_callback)
    {
        JITLoaderInstance instance;
        assert ((bool)name);
        instance.name = name;
        if (description && description[0])
            instance.description = description;
        instance.create_callback = create_callback;
        instance.debugger_init_callback = debugger_init_callback;
        Mutex::Locker locker (GetJITLoaderMutex ());
        GetJITLoaderInstances ().push_back (instance);
    }
    return false;
}

bool
PluginManager::UnregisterPlugin (JITLoaderCreateInstance create_callback)
{
    if (create_callback)
    {
        Mutex::Locker locker (GetJITLoaderMutex ());
        JITLoaderInstances &instances = GetJITLoaderInstances ();
        
        JITLoaderInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (pos->create_callback == create_callback)
            {
                instances.erase(pos);
                return true;
            }
        }
    }
    return false;
}

JITLoaderCreateInstance
PluginManager::GetJITLoaderCreateCallbackAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetJITLoaderMutex ());
    JITLoaderInstances &instances = GetJITLoaderInstances ();
    if (idx < instances.size())
        return instances[idx].create_callback;
    return NULL;
}

JITLoaderCreateInstance
PluginManager::GetJITLoaderCreateCallbackForPluginName (const ConstString &name)
{
    if (name)
    {
        Mutex::Locker locker (GetJITLoaderMutex ());
        JITLoaderInstances &instances = GetJITLoaderInstances ();
        
        JITLoaderInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (name == pos->name)
                return pos->create_callback;
        }
    }
    return NULL;
}

#pragma mark EmulateInstruction


struct EmulateInstructionInstance
{
    EmulateInstructionInstance() :
    name(),
    description(),
    create_callback(NULL)
    {
    }
    
    ConstString name;
    std::string description;
    EmulateInstructionCreateInstance create_callback;
};

typedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances;

static Mutex &
GetEmulateInstructionMutex ()
{
    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
    return g_instances_mutex;
}

static EmulateInstructionInstances &
GetEmulateInstructionInstances ()
{
    static EmulateInstructionInstances g_instances;
    return g_instances;
}


bool
PluginManager::RegisterPlugin
(
    const ConstString &name,
    const char *description,
    EmulateInstructionCreateInstance create_callback
)
{
    if (create_callback)
    {
        EmulateInstructionInstance instance;
        assert ((bool)name);
        instance.name = name;
        if (description && description[0])
            instance.description = description;
        instance.create_callback = create_callback;
        Mutex::Locker locker (GetEmulateInstructionMutex ());
        GetEmulateInstructionInstances ().push_back (instance);
    }
    return false;
}

bool
PluginManager::UnregisterPlugin (EmulateInstructionCreateInstance create_callback)
{
    if (create_callback)
    {
        Mutex::Locker locker (GetEmulateInstructionMutex ());
        EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
        
        EmulateInstructionInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (pos->create_callback == create_callback)
            {
                instances.erase(pos);
                return true;
            }
        }
    }
    return false;
}

EmulateInstructionCreateInstance
PluginManager::GetEmulateInstructionCreateCallbackAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetEmulateInstructionMutex ());
    EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
    if (idx < instances.size())
        return instances[idx].create_callback;
    return NULL;
}

EmulateInstructionCreateInstance
PluginManager::GetEmulateInstructionCreateCallbackForPluginName (const ConstString &name)
{
    if (name)
    {
        Mutex::Locker locker (GetEmulateInstructionMutex ());
        EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
        
        EmulateInstructionInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (name == pos->name)
                return pos->create_callback;
        }
    }
    return NULL;
}
#pragma mark OperatingSystem


struct OperatingSystemInstance
{
    OperatingSystemInstance () :
        name (),
        description (),
        create_callback (nullptr),
        debugger_init_callback (nullptr)
    {
    }
    
    ConstString name;
    std::string description;
    OperatingSystemCreateInstance create_callback;
    DebuggerInitializeCallback debugger_init_callback;
};

typedef std::vector<OperatingSystemInstance> OperatingSystemInstances;

static Mutex &
GetOperatingSystemMutex ()
{
    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
    return g_instances_mutex;
}

static OperatingSystemInstances &
GetOperatingSystemInstances ()
{
    static OperatingSystemInstances g_instances;
    return g_instances;
}

bool
PluginManager::RegisterPlugin(const ConstString &name, const char *description,
                              OperatingSystemCreateInstance create_callback,
                              DebuggerInitializeCallback debugger_init_callback)
{
    if (create_callback)
    {
        OperatingSystemInstance instance;
        assert ((bool)name);
        instance.name = name;
        if (description && description[0])
            instance.description = description;
        instance.create_callback = create_callback;
        instance.debugger_init_callback = debugger_init_callback;
        Mutex::Locker locker (GetOperatingSystemMutex ());
        GetOperatingSystemInstances ().push_back (instance);
    }
    return false;
}

bool
PluginManager::UnregisterPlugin (OperatingSystemCreateInstance create_callback)
{
    if (create_callback)
    {
        Mutex::Locker locker (GetOperatingSystemMutex ());
        OperatingSystemInstances &instances = GetOperatingSystemInstances ();
        
        OperatingSystemInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (pos->create_callback == create_callback)
            {
                instances.erase(pos);
                return true;
            }
        }
    }
    return false;
}

OperatingSystemCreateInstance
PluginManager::GetOperatingSystemCreateCallbackAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetOperatingSystemMutex ());
    OperatingSystemInstances &instances = GetOperatingSystemInstances ();
    if (idx < instances.size())
        return instances[idx].create_callback;
    return NULL;
}

OperatingSystemCreateInstance
PluginManager::GetOperatingSystemCreateCallbackForPluginName (const ConstString &name)
{
    if (name)
    {
        Mutex::Locker locker (GetOperatingSystemMutex ());
        OperatingSystemInstances &instances = GetOperatingSystemInstances ();
        
        OperatingSystemInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (name == pos->name)
                return pos->create_callback;
        }
    }
    return NULL;
}


#pragma mark Language


struct LanguageInstance
{
    LanguageInstance() :
        name(),
        description(),
        create_callback(NULL)
    {
    }
    
    ConstString name;
    std::string description;
    LanguageCreateInstance create_callback;
};

typedef std::vector<LanguageInstance> LanguageInstances;

static Mutex &
GetLanguageMutex ()
{
    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
    return g_instances_mutex;
}

static LanguageInstances &
GetLanguageInstances ()
{
    static LanguageInstances g_instances;
    return g_instances;
}

bool
PluginManager::RegisterPlugin
(
 const ConstString &name,
 const char *description,
 LanguageCreateInstance create_callback
 )
{
    if (create_callback)
    {
        LanguageInstance instance;
        assert ((bool)name);
        instance.name = name;
        if (description && description[0])
            instance.description = description;
        instance.create_callback = create_callback;
        Mutex::Locker locker (GetLanguageMutex ());
        GetLanguageInstances ().push_back (instance);
    }
    return false;
}

bool
PluginManager::UnregisterPlugin (LanguageCreateInstance create_callback)
{
    if (create_callback)
    {
        Mutex::Locker locker (GetLanguageMutex ());
        LanguageInstances &instances = GetLanguageInstances ();
        
        LanguageInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (pos->create_callback == create_callback)
            {
                instances.erase(pos);
                return true;
            }
        }
    }
    return false;
}

LanguageCreateInstance
PluginManager::GetLanguageCreateCallbackAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetLanguageMutex ());
    LanguageInstances &instances = GetLanguageInstances ();
    if (idx < instances.size())
        return instances[idx].create_callback;
    return NULL;
}

LanguageCreateInstance
PluginManager::GetLanguageCreateCallbackForPluginName (const ConstString &name)
{
    if (name)
    {
        Mutex::Locker locker (GetLanguageMutex ());
        LanguageInstances &instances = GetLanguageInstances ();
        
        LanguageInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (name == pos->name)
                return pos->create_callback;
        }
    }
    return NULL;
}


#pragma mark LanguageRuntime


struct LanguageRuntimeInstance
{
    LanguageRuntimeInstance() :
        name(),
        description(),
        create_callback(NULL)
    {
    }

    ConstString name;
    std::string description;
    LanguageRuntimeCreateInstance create_callback;
    LanguageRuntimeGetCommandObject command_callback;
};

typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;

static Mutex &
GetLanguageRuntimeMutex ()
{
    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
    return g_instances_mutex;
}

static LanguageRuntimeInstances &
GetLanguageRuntimeInstances ()
{
    static LanguageRuntimeInstances g_instances;
    return g_instances;
}

bool
PluginManager::RegisterPlugin
(
    const ConstString &name,
    const char *description,
    LanguageRuntimeCreateInstance create_callback,
    LanguageRuntimeGetCommandObject command_callback
)
{
    if (create_callback)
    {
        LanguageRuntimeInstance instance;
        assert ((bool)name);
        instance.name = name;
        if (description && description[0])
            instance.description = description;
        instance.create_callback = create_callback;
        instance.command_callback = command_callback;
        Mutex::Locker locker (GetLanguageRuntimeMutex ());
        GetLanguageRuntimeInstances ().push_back (instance);
    }
    return false;
}

bool
PluginManager::UnregisterPlugin (LanguageRuntimeCreateInstance create_callback)
{
    if (create_callback)
    {
        Mutex::Locker locker (GetLanguageRuntimeMutex ());
        LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
        
        LanguageRuntimeInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (pos->create_callback == create_callback)
            {
                instances.erase(pos);
                return true;
            }
        }
    }
    return false;
}

LanguageRuntimeCreateInstance
PluginManager::GetLanguageRuntimeCreateCallbackAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetLanguageRuntimeMutex ());
    LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
    if (idx < instances.size())
        return instances[idx].create_callback;
    return NULL;
}

LanguageRuntimeGetCommandObject
PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetLanguageRuntimeMutex ());
    LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
    if (idx < instances.size())
        return instances[idx].command_callback;
    return NULL;
}

LanguageRuntimeCreateInstance
PluginManager::GetLanguageRuntimeCreateCallbackForPluginName (const ConstString &name)
{
    if (name)
    {
        Mutex::Locker locker (GetLanguageRuntimeMutex ());
        LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
        
        LanguageRuntimeInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (name == pos->name)
                return pos->create_callback;
        }
    }
    return NULL;
}

#pragma mark SystemRuntime


struct SystemRuntimeInstance
{
    SystemRuntimeInstance() :
        name(),
        description(),
        create_callback(NULL)
    {
    }

    ConstString name;
    std::string description;
    SystemRuntimeCreateInstance create_callback;
};

typedef std::vector<SystemRuntimeInstance> SystemRuntimeInstances;

static Mutex &
GetSystemRuntimeMutex ()
{
    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
    return g_instances_mutex;
}

static SystemRuntimeInstances &
GetSystemRuntimeInstances ()
{
    static SystemRuntimeInstances g_instances;
    return g_instances;
}

bool
PluginManager::RegisterPlugin
(
    const ConstString &name,
    const char *description,
    SystemRuntimeCreateInstance create_callback
)
{
    if (create_callback)
    {
        SystemRuntimeInstance instance;
        assert ((bool)name);
        instance.name = name;
        if (description && description[0])
            instance.description = description;
        instance.create_callback = create_callback;
        Mutex::Locker locker (GetSystemRuntimeMutex ());
        GetSystemRuntimeInstances ().push_back (instance);
    }
    return false;
}

bool
PluginManager::UnregisterPlugin (SystemRuntimeCreateInstance create_callback)
{
    if (create_callback)
    {
        Mutex::Locker locker (GetSystemRuntimeMutex ());
        SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
        
        SystemRuntimeInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (pos->create_callback == create_callback)
            {
                instances.erase(pos);
                return true;
            }
        }
    }
    return false;
}

SystemRuntimeCreateInstance
PluginManager::GetSystemRuntimeCreateCallbackAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetSystemRuntimeMutex ());
    SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
    if (idx < instances.size())
        return instances[idx].create_callback;
    return NULL;
}

SystemRuntimeCreateInstance
PluginManager::GetSystemRuntimeCreateCallbackForPluginName (const ConstString &name)
{
    if (name)
    {
        Mutex::Locker locker (GetSystemRuntimeMutex ());
        SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
        
        SystemRuntimeInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (name == pos->name)
                return pos->create_callback;
        }
    }
    return NULL;
}


#pragma mark ObjectFile

struct ObjectFileInstance
{
    ObjectFileInstance() :
        name(),
        description(),
        create_callback(NULL),
        create_memory_callback (NULL),
        get_module_specifications (NULL),
        save_core (NULL)
    {
    }

    ConstString name;
    std::string description;
    ObjectFileCreateInstance create_callback;
    ObjectFileCreateMemoryInstance create_memory_callback;
    ObjectFileGetModuleSpecifications get_module_specifications;
    ObjectFileSaveCore save_core;
};

typedef std::vector<ObjectFileInstance> ObjectFileInstances;

static Mutex &
GetObjectFileMutex ()
{
    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
    return g_instances_mutex;
}

static ObjectFileInstances &
GetObjectFileInstances ()
{
    static ObjectFileInstances g_instances;
    return g_instances;
}


bool
PluginManager::RegisterPlugin (const ConstString &name,
                               const char *description,
                               ObjectFileCreateInstance create_callback,
                               ObjectFileCreateMemoryInstance create_memory_callback,
                               ObjectFileGetModuleSpecifications get_module_specifications,
                               ObjectFileSaveCore save_core)
{
    if (create_callback)
    {
        ObjectFileInstance instance;
        assert ((bool)name);
        instance.name = name;
        if (description && description[0])
            instance.description = description;
        instance.create_callback = create_callback;
        instance.create_memory_callback = create_memory_callback;
        instance.save_core = save_core;
        instance.get_module_specifications = get_module_specifications;
        Mutex::Locker locker (GetObjectFileMutex ());
        GetObjectFileInstances ().push_back (instance);
    }
    return false;
}

bool
PluginManager::UnregisterPlugin (ObjectFileCreateInstance create_callback)
{
    if (create_callback)
    {
        Mutex::Locker locker (GetObjectFileMutex ());
        ObjectFileInstances &instances = GetObjectFileInstances ();
        
        ObjectFileInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (pos->create_callback == create_callback)
            {
                instances.erase(pos);
                return true;
            }
        }
    }
    return false;
}

ObjectFileCreateInstance
PluginManager::GetObjectFileCreateCallbackAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetObjectFileMutex ());
    ObjectFileInstances &instances = GetObjectFileInstances ();
    if (idx < instances.size())
        return instances[idx].create_callback;
    return NULL;
}


ObjectFileCreateMemoryInstance
PluginManager::GetObjectFileCreateMemoryCallbackAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetObjectFileMutex ());
    ObjectFileInstances &instances = GetObjectFileInstances ();
    if (idx < instances.size())
        return instances[idx].create_memory_callback;
    return NULL;
}

ObjectFileGetModuleSpecifications
PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetObjectFileMutex ());
    ObjectFileInstances &instances = GetObjectFileInstances ();
    if (idx < instances.size())
        return instances[idx].get_module_specifications;
    return NULL;
}

ObjectFileCreateInstance
PluginManager::GetObjectFileCreateCallbackForPluginName (const ConstString &name)
{
    if (name)
    {
        Mutex::Locker locker (GetObjectFileMutex ());
        ObjectFileInstances &instances = GetObjectFileInstances ();
        
        ObjectFileInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (name == pos->name)
                return pos->create_callback;
        }
    }
    return NULL;
}


ObjectFileCreateMemoryInstance
PluginManager::GetObjectFileCreateMemoryCallbackForPluginName (const ConstString &name)
{
    if (name)
    {
        Mutex::Locker locker (GetObjectFileMutex ());
        ObjectFileInstances &instances = GetObjectFileInstances ();
        
        ObjectFileInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (name == pos->name)
                return pos->create_memory_callback;
        }
    }
    return NULL;
}

Error
PluginManager::SaveCore (const lldb::ProcessSP &process_sp, const FileSpec &outfile)
{
    Error error;
    Mutex::Locker locker (GetObjectFileMutex ());
    ObjectFileInstances &instances = GetObjectFileInstances ();
    
    ObjectFileInstances::iterator pos, end = instances.end();
    for (pos = instances.begin(); pos != end; ++ pos)
    {
        if (pos->save_core && pos->save_core (process_sp, outfile, error))
            return error;
    }
    error.SetErrorString("no ObjectFile plugins were able to save a core for this process");
    return error;
}

#pragma mark ObjectContainer

struct ObjectContainerInstance
{
    ObjectContainerInstance() :
        name(),
        description(),
        create_callback (NULL),
        get_module_specifications (NULL)
    {
    }

    ConstString name;
    std::string description;
    ObjectContainerCreateInstance create_callback;
    ObjectFileGetModuleSpecifications get_module_specifications;

};

typedef std::vector<ObjectContainerInstance> ObjectContainerInstances;

static Mutex &
GetObjectContainerMutex ()
{
    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
    return g_instances_mutex;
}

static ObjectContainerInstances &
GetObjectContainerInstances ()
{
    static ObjectContainerInstances g_instances;
    return g_instances;
}

bool
PluginManager::RegisterPlugin (const ConstString &name,
                               const char *description,
                               ObjectContainerCreateInstance create_callback,
                               ObjectFileGetModuleSpecifications get_module_specifications)
{
    if (create_callback)
    {
        ObjectContainerInstance instance;
        assert ((bool)name);
        instance.name = name;
        if (description && description[0])
            instance.description = description;
        instance.create_callback = create_callback;
        instance.get_module_specifications = get_module_specifications;
        Mutex::Locker locker (GetObjectContainerMutex ());
        GetObjectContainerInstances ().push_back (instance);
    }
    return false;
}

bool
PluginManager::UnregisterPlugin (ObjectContainerCreateInstance create_callback)
{
    if (create_callback)
    {
        Mutex::Locker locker (GetObjectContainerMutex ());
        ObjectContainerInstances &instances = GetObjectContainerInstances ();
        
        ObjectContainerInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (pos->create_callback == create_callback)
            {
                instances.erase(pos);
                return true;
            }
        }
    }
    return false;
}

ObjectContainerCreateInstance
PluginManager::GetObjectContainerCreateCallbackAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetObjectContainerMutex ());
    ObjectContainerInstances &instances = GetObjectContainerInstances ();
    if (idx < instances.size())
        return instances[idx].create_callback;
    return NULL;
}

ObjectContainerCreateInstance
PluginManager::GetObjectContainerCreateCallbackForPluginName (const ConstString &name)
{
    if (name)
    {
        Mutex::Locker locker (GetObjectContainerMutex ());
        ObjectContainerInstances &instances = GetObjectContainerInstances ();
        
        ObjectContainerInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (name == pos->name)
                return pos->create_callback;
        }
    }
    return NULL;
}

ObjectFileGetModuleSpecifications
PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetObjectContainerMutex ());
    ObjectContainerInstances &instances = GetObjectContainerInstances ();
    if (idx < instances.size())
        return instances[idx].get_module_specifications;
    return NULL;
}

#pragma mark LogChannel

struct LogInstance
{
    LogInstance() :
        name(),
        description(),
        create_callback(NULL)
    {
    }

    ConstString name;
    std::string description;
    LogChannelCreateInstance create_callback;
};

typedef std::vector<LogInstance> LogInstances;

static Mutex &
GetLogMutex ()
{
    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
    return g_instances_mutex;
}

static LogInstances &
GetLogInstances ()
{
    static LogInstances g_instances;
    return g_instances;
}



bool
PluginManager::RegisterPlugin
(
    const ConstString &name,
    const char *description,
    LogChannelCreateInstance create_callback
)
{
    if (create_callback)
    {
        LogInstance instance;
        assert ((bool)name);
        instance.name = name;
        if (description && description[0])
            instance.description = description;
        instance.create_callback = create_callback;
        Mutex::Locker locker (GetLogMutex ());
        GetLogInstances ().push_back (instance);
    }
    return false;
}

bool
PluginManager::UnregisterPlugin (LogChannelCreateInstance create_callback)
{
    if (create_callback)
    {
        Mutex::Locker locker (GetLogMutex ());
        LogInstances &instances = GetLogInstances ();
        
        LogInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (pos->create_callback == create_callback)
            {
                instances.erase(pos);
                return true;
            }
        }
    }
    return false;
}

const char *
PluginManager::GetLogChannelCreateNameAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetLogMutex ());
    LogInstances &instances = GetLogInstances ();
    if (idx < instances.size())
        return instances[idx].name.GetCString();
    return NULL;
}


LogChannelCreateInstance
PluginManager::GetLogChannelCreateCallbackAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetLogMutex ());
    LogInstances &instances = GetLogInstances ();
    if (idx < instances.size())
        return instances[idx].create_callback;
    return NULL;
}

LogChannelCreateInstance
PluginManager::GetLogChannelCreateCallbackForPluginName (const ConstString &name)
{
    if (name)
    {
        Mutex::Locker locker (GetLogMutex ());
        LogInstances &instances = GetLogInstances ();
        
        LogInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (name == pos->name)
                return pos->create_callback;
        }
    }
    return NULL;
}

#pragma mark Platform

struct PlatformInstance
{
    PlatformInstance() :
        name(),
        description(),
        create_callback(NULL),
        debugger_init_callback (NULL)
    {
    }
    
    ConstString name;
    std::string description;
    PlatformCreateInstance create_callback;
    DebuggerInitializeCallback debugger_init_callback;
};

typedef std::vector<PlatformInstance> PlatformInstances;

static Mutex &
GetPlatformInstancesMutex ()
{
    static Mutex g_platform_instances_mutex (Mutex::eMutexTypeRecursive);
    return g_platform_instances_mutex;
}

static PlatformInstances &
GetPlatformInstances ()
{
    static PlatformInstances g_platform_instances;
    return g_platform_instances;
}


bool
PluginManager::RegisterPlugin (const ConstString &name,
                               const char *description,
                               PlatformCreateInstance create_callback,
                               DebuggerInitializeCallback debugger_init_callback)
{
    if (create_callback)
    {
        Mutex::Locker locker (GetPlatformInstancesMutex ());
        
        PlatformInstance instance;
        assert ((bool)name);
        instance.name = name;
        if (description && description[0])
            instance.description = description;
        instance.create_callback = create_callback;
        instance.debugger_init_callback = debugger_init_callback;
        GetPlatformInstances ().push_back (instance);
        return true;
    }
    return false;
}


const char *
PluginManager::GetPlatformPluginNameAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetPlatformInstancesMutex ());
    PlatformInstances &instances = GetPlatformInstances ();
    if (idx < instances.size())
        return instances[idx].name.GetCString();
    return NULL;
}

const char *
PluginManager::GetPlatformPluginDescriptionAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetPlatformInstancesMutex ());
    PlatformInstances &instances = GetPlatformInstances ();
    if (idx < instances.size())
        return instances[idx].description.c_str();
    return NULL;
}

bool
PluginManager::UnregisterPlugin (PlatformCreateInstance create_callback)
{
    if (create_callback)
    {
        Mutex::Locker locker (GetPlatformInstancesMutex ());
        PlatformInstances &instances = GetPlatformInstances ();

        PlatformInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (pos->create_callback == create_callback)
            {
                instances.erase(pos);
                return true;
            }
        }
    }
    return false;
}

PlatformCreateInstance
PluginManager::GetPlatformCreateCallbackAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetPlatformInstancesMutex ());
    PlatformInstances &instances = GetPlatformInstances ();
    if (idx < instances.size())
        return instances[idx].create_callback;
    return NULL;
}

PlatformCreateInstance
PluginManager::GetPlatformCreateCallbackForPluginName (const ConstString &name)
{
    if (name)
    {
        Mutex::Locker locker (GetPlatformInstancesMutex ());
        PlatformInstances &instances = GetPlatformInstances ();

        PlatformInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (name == pos->name)
                return pos->create_callback;
        }
    }
    return NULL;
}

size_t
PluginManager::AutoCompletePlatformName (const char *name, StringList &matches)
{
    if (name)
    {
        Mutex::Locker locker (GetPlatformInstancesMutex ());
        PlatformInstances &instances = GetPlatformInstances ();
        llvm::StringRef name_sref(name);

        PlatformInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            llvm::StringRef plugin_name (pos->name.GetCString());
            if (plugin_name.startswith(name_sref))
                matches.AppendString (plugin_name.data());
        }
    }
    return matches.GetSize();
}
#pragma mark Process

struct ProcessInstance
{
    ProcessInstance() :
        name(),
        description(),
        create_callback(NULL),
        debugger_init_callback(NULL)
    {
    }
    
    ConstString name;
    std::string description;
    ProcessCreateInstance create_callback;
    DebuggerInitializeCallback debugger_init_callback;
};

typedef std::vector<ProcessInstance> ProcessInstances;

static Mutex &
GetProcessMutex ()
{
    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
    return g_instances_mutex;
}

static ProcessInstances &
GetProcessInstances ()
{
    static ProcessInstances g_instances;
    return g_instances;
}


bool
PluginManager::RegisterPlugin (const ConstString &name,
                               const char *description,
                               ProcessCreateInstance create_callback,
                               DebuggerInitializeCallback debugger_init_callback)
{
    if (create_callback)
    {
        ProcessInstance instance;
        assert ((bool)name);
        instance.name = name;
        if (description && description[0])
            instance.description = description;
        instance.create_callback = create_callback;
        instance.debugger_init_callback = debugger_init_callback;
        Mutex::Locker locker (GetProcessMutex ());
        GetProcessInstances ().push_back (instance);
    }
    return false;
}

const char *
PluginManager::GetProcessPluginNameAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetProcessMutex ());
    ProcessInstances &instances = GetProcessInstances ();
    if (idx < instances.size())
        return instances[idx].name.GetCString();
    return NULL;
}

const char *
PluginManager::GetProcessPluginDescriptionAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetProcessMutex ());
    ProcessInstances &instances = GetProcessInstances ();
    if (idx < instances.size())
        return instances[idx].description.c_str();
    return NULL;
}

bool
PluginManager::UnregisterPlugin (ProcessCreateInstance create_callback)
{
    if (create_callback)
    {
        Mutex::Locker locker (GetProcessMutex ());
        ProcessInstances &instances = GetProcessInstances ();
        
        ProcessInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (pos->create_callback == create_callback)
            {
                instances.erase(pos);
                return true;
            }
        }
    }
    return false;
}

ProcessCreateInstance
PluginManager::GetProcessCreateCallbackAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetProcessMutex ());
    ProcessInstances &instances = GetProcessInstances ();
    if (idx < instances.size())
        return instances[idx].create_callback;
    return NULL;
}


ProcessCreateInstance
PluginManager::GetProcessCreateCallbackForPluginName (const ConstString &name)
{
    if (name)
    {
        Mutex::Locker locker (GetProcessMutex ());
        ProcessInstances &instances = GetProcessInstances ();
        
        ProcessInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (name == pos->name)
                return pos->create_callback;
        }
    }
    return NULL;
}

#pragma mark ScriptInterpreter

struct ScriptInterpreterInstance
{
    ScriptInterpreterInstance()
        : name()
        , language(lldb::eScriptLanguageNone)
        , description()
        , create_callback(NULL)
    {
    }

    ConstString name;
    lldb::ScriptLanguage language;
    std::string description;
    ScriptInterpreterCreateInstance create_callback;
};

typedef std::vector<ScriptInterpreterInstance> ScriptInterpreterInstances;

static Mutex &
GetScriptInterpreterMutex()
{
    static Mutex g_instances_mutex(Mutex::eMutexTypeRecursive);
    return g_instances_mutex;
}

static ScriptInterpreterInstances &
GetScriptInterpreterInstances()
{
    static ScriptInterpreterInstances g_instances;
    return g_instances;
}

bool
PluginManager::RegisterPlugin(const ConstString &name, const char *description, lldb::ScriptLanguage script_language,
                              ScriptInterpreterCreateInstance create_callback)
{
    if (!create_callback)
        return false;
    ScriptInterpreterInstance instance;
    assert((bool)name);
    instance.name = name;
    if (description && description[0])
        instance.description = description;
    instance.create_callback = create_callback;
    instance.language = script_language;
    Mutex::Locker locker(GetScriptInterpreterMutex());
    GetScriptInterpreterInstances().push_back(instance);
    return false;
}

bool
PluginManager::UnregisterPlugin(ScriptInterpreterCreateInstance create_callback)
{
    if (!create_callback)
        return false;
    Mutex::Locker locker(GetScriptInterpreterMutex());
    ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();

    ScriptInterpreterInstances::iterator pos, end = instances.end();
    for (pos = instances.begin(); pos != end; ++pos)
    {
        if (pos->create_callback != create_callback)
            continue;

        instances.erase(pos);
        return true;
    }
    return false;
}

ScriptInterpreterCreateInstance
PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx)
{
    Mutex::Locker locker(GetScriptInterpreterMutex());
    ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
    if (idx < instances.size())
        return instances[idx].create_callback;
    return nullptr;
}

lldb::ScriptInterpreterSP
PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang, CommandInterpreter &interpreter)
{
    Mutex::Locker locker(GetScriptInterpreterMutex());
    ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();

    ScriptInterpreterInstances::iterator pos, end = instances.end();
    ScriptInterpreterCreateInstance none_instance = nullptr;
    for (pos = instances.begin(); pos != end; ++pos)
    {
        if (pos->language == lldb::eScriptLanguageNone)
            none_instance = pos->create_callback;

        if (script_lang == pos->language)
            return pos->create_callback(interpreter);
    }

    // If we didn't find one, return the ScriptInterpreter for the null language.
    assert(none_instance != nullptr);
    return none_instance(interpreter);
}

#pragma mark SymbolFile

struct SymbolFileInstance
{
    SymbolFileInstance() :
        name(),
        description(),
        create_callback(nullptr),
        debugger_init_callback(nullptr)
    {
    }

    ConstString name;
    std::string description;
    SymbolFileCreateInstance create_callback;
    DebuggerInitializeCallback debugger_init_callback;
};

typedef std::vector<SymbolFileInstance> SymbolFileInstances;

static Mutex &
GetSymbolFileMutex ()
{
    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
    return g_instances_mutex;
}

static SymbolFileInstances &
GetSymbolFileInstances ()
{
    static SymbolFileInstances g_instances;
    return g_instances;
}


bool
PluginManager::RegisterPlugin
(
    const ConstString &name,
    const char *description,
    SymbolFileCreateInstance create_callback,
    DebuggerInitializeCallback debugger_init_callback
)
{
    if (create_callback)
    {
        SymbolFileInstance instance;
        assert ((bool)name);
        instance.name = name;
        if (description && description[0])
            instance.description = description;
        instance.create_callback = create_callback;
        instance.debugger_init_callback = debugger_init_callback;
        Mutex::Locker locker (GetSymbolFileMutex ());
        GetSymbolFileInstances ().push_back (instance);
    }
    return false;
}

bool
PluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback)
{
    if (create_callback)
    {
        Mutex::Locker locker (GetSymbolFileMutex ());
        SymbolFileInstances &instances = GetSymbolFileInstances ();
        
        SymbolFileInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (pos->create_callback == create_callback)
            {
                instances.erase(pos);
                return true;
            }
        }
    }
    return false;
}

SymbolFileCreateInstance
PluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetSymbolFileMutex ());
    SymbolFileInstances &instances = GetSymbolFileInstances ();
    if (idx < instances.size())
        return instances[idx].create_callback;
    return NULL;
}

SymbolFileCreateInstance
PluginManager::GetSymbolFileCreateCallbackForPluginName (const ConstString &name)
{
    if (name)
    {
        Mutex::Locker locker (GetSymbolFileMutex ());
        SymbolFileInstances &instances = GetSymbolFileInstances ();
        
        SymbolFileInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (name == pos->name)
                return pos->create_callback;
        }
    }
    return NULL;
}



#pragma mark SymbolVendor

struct SymbolVendorInstance
{
    SymbolVendorInstance() :
        name(),
        description(),
        create_callback(NULL)
    {
    }

    ConstString name;
    std::string description;
    SymbolVendorCreateInstance create_callback;
};

typedef std::vector<SymbolVendorInstance> SymbolVendorInstances;

static Mutex &
GetSymbolVendorMutex ()
{
    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
    return g_instances_mutex;
}

static SymbolVendorInstances &
GetSymbolVendorInstances ()
{
    static SymbolVendorInstances g_instances;
    return g_instances;
}

bool
PluginManager::RegisterPlugin
(
    const ConstString &name,
    const char *description,
    SymbolVendorCreateInstance create_callback
)
{
    if (create_callback)
    {
        SymbolVendorInstance instance;
        assert ((bool)name);
        instance.name = name;
        if (description && description[0])
            instance.description = description;
        instance.create_callback = create_callback;
        Mutex::Locker locker (GetSymbolVendorMutex ());
        GetSymbolVendorInstances ().push_back (instance);
    }
    return false;
}

bool
PluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback)
{
    if (create_callback)
    {
        Mutex::Locker locker (GetSymbolVendorMutex ());
        SymbolVendorInstances &instances = GetSymbolVendorInstances ();
        
        SymbolVendorInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (pos->create_callback == create_callback)
            {
                instances.erase(pos);
                return true;
            }
        }
    }
    return false;
}

SymbolVendorCreateInstance
PluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetSymbolVendorMutex ());
    SymbolVendorInstances &instances = GetSymbolVendorInstances ();
    if (idx < instances.size())
        return instances[idx].create_callback;
    return NULL;
}


SymbolVendorCreateInstance
PluginManager::GetSymbolVendorCreateCallbackForPluginName (const ConstString &name)
{
    if (name)
    {
        Mutex::Locker locker (GetSymbolVendorMutex ());
        SymbolVendorInstances &instances = GetSymbolVendorInstances ();
        
        SymbolVendorInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (name == pos->name)
                return pos->create_callback;
        }
    }
    return NULL;
}


#pragma mark UnwindAssembly

struct UnwindAssemblyInstance
{
    UnwindAssemblyInstance() :
        name(),
        description(),
        create_callback(NULL)
    {
    }

    ConstString name;
    std::string description;
    UnwindAssemblyCreateInstance create_callback;
};

typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances;

static Mutex &
GetUnwindAssemblyMutex ()
{
    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
    return g_instances_mutex;
}

static UnwindAssemblyInstances &
GetUnwindAssemblyInstances ()
{
    static UnwindAssemblyInstances g_instances;
    return g_instances;
}

bool
PluginManager::RegisterPlugin
(
    const ConstString &name,
    const char *description,
    UnwindAssemblyCreateInstance create_callback
)
{
    if (create_callback)
    {
        UnwindAssemblyInstance instance;
        assert ((bool)name);
        instance.name = name;
        if (description && description[0])
            instance.description = description;
        instance.create_callback = create_callback;
        Mutex::Locker locker (GetUnwindAssemblyMutex ());
        GetUnwindAssemblyInstances ().push_back (instance);
    }
    return false;
}

bool
PluginManager::UnregisterPlugin (UnwindAssemblyCreateInstance create_callback)
{
    if (create_callback)
    {
        Mutex::Locker locker (GetUnwindAssemblyMutex ());
        UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
        
        UnwindAssemblyInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (pos->create_callback == create_callback)
            {
                instances.erase(pos);
                return true;
            }
        }
    }
    return false;
}

UnwindAssemblyCreateInstance
PluginManager::GetUnwindAssemblyCreateCallbackAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetUnwindAssemblyMutex ());
    UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
    if (idx < instances.size())
        return instances[idx].create_callback;
    return NULL;
}


UnwindAssemblyCreateInstance
PluginManager::GetUnwindAssemblyCreateCallbackForPluginName (const ConstString &name)
{
    if (name)
    {
        Mutex::Locker locker (GetUnwindAssemblyMutex ());
        UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
        
        UnwindAssemblyInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (name == pos->name)
                return pos->create_callback;
        }
    }
    return NULL;
}

#pragma mark MemoryHistory

struct MemoryHistoryInstance
{
    MemoryHistoryInstance() :
    name(),
    description(),
    create_callback(NULL)
    {
    }
    
    ConstString name;
    std::string description;
    MemoryHistoryCreateInstance create_callback;
};

typedef std::vector<MemoryHistoryInstance> MemoryHistoryInstances;

static Mutex &
GetMemoryHistoryMutex ()
{
    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
    return g_instances_mutex;
}

static MemoryHistoryInstances &
GetMemoryHistoryInstances ()
{
    static MemoryHistoryInstances g_instances;
    return g_instances;
}

bool
PluginManager::RegisterPlugin
(
 const ConstString &name,
 const char *description,
 MemoryHistoryCreateInstance create_callback
 )
{
    if (create_callback)
    {
        MemoryHistoryInstance instance;
        assert ((bool)name);
        instance.name = name;
        if (description && description[0])
            instance.description = description;
        instance.create_callback = create_callback;
        Mutex::Locker locker (GetMemoryHistoryMutex ());
        GetMemoryHistoryInstances ().push_back (instance);
    }
    return false;
}

bool
PluginManager::UnregisterPlugin (MemoryHistoryCreateInstance create_callback)
{
    if (create_callback)
    {
        Mutex::Locker locker (GetMemoryHistoryMutex ());
        MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
        
        MemoryHistoryInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (pos->create_callback == create_callback)
            {
                instances.erase(pos);
                return true;
            }
        }
    }
    return false;
}

MemoryHistoryCreateInstance
PluginManager::GetMemoryHistoryCreateCallbackAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetMemoryHistoryMutex ());
    MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
    if (idx < instances.size())
        return instances[idx].create_callback;
    return NULL;
}


MemoryHistoryCreateInstance
PluginManager::GetMemoryHistoryCreateCallbackForPluginName (const ConstString &name)
{
    if (name)
    {
        Mutex::Locker locker (GetMemoryHistoryMutex ());
        MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
        
        MemoryHistoryInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (name == pos->name)
                return pos->create_callback;
        }
    }
    return NULL;
}

#pragma mark InstrumentationRuntime

struct InstrumentationRuntimeInstance
{
    InstrumentationRuntimeInstance() :
    name(),
    description(),
    create_callback(NULL)
    {
    }
    
    ConstString name;
    std::string description;
    InstrumentationRuntimeCreateInstance create_callback;
    InstrumentationRuntimeGetType get_type_callback;
};

typedef std::vector<InstrumentationRuntimeInstance> InstrumentationRuntimeInstances;

static Mutex &
GetInstrumentationRuntimeMutex ()
{
    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
    return g_instances_mutex;
}

static InstrumentationRuntimeInstances &
GetInstrumentationRuntimeInstances ()
{
    static InstrumentationRuntimeInstances g_instances;
    return g_instances;
}

bool
PluginManager::RegisterPlugin
(
 const ConstString &name,
 const char *description,
 InstrumentationRuntimeCreateInstance create_callback,
 InstrumentationRuntimeGetType get_type_callback
 )
{
    if (create_callback)
    {
        InstrumentationRuntimeInstance instance;
        assert ((bool)name);
        instance.name = name;
        if (description && description[0])
            instance.description = description;
        instance.create_callback = create_callback;
        instance.get_type_callback = get_type_callback;
        Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
        GetInstrumentationRuntimeInstances ().push_back (instance);
    }
    return false;
}

bool
PluginManager::UnregisterPlugin (InstrumentationRuntimeCreateInstance create_callback)
{
    if (create_callback)
    {
        Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
        InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
        
        InstrumentationRuntimeInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (pos->create_callback == create_callback)
            {
                instances.erase(pos);
                return true;
            }
        }
    }
    return false;
}

InstrumentationRuntimeGetType
PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
    InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
    if (idx < instances.size())
        return instances[idx].get_type_callback;
    return NULL;
}

InstrumentationRuntimeCreateInstance
PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
    InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
    if (idx < instances.size())
        return instances[idx].create_callback;
    return NULL;
}


InstrumentationRuntimeCreateInstance
PluginManager::GetInstrumentationRuntimeCreateCallbackForPluginName (const ConstString &name)
{
    if (name)
    {
        Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
        InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
        
        InstrumentationRuntimeInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (name == pos->name)
                return pos->create_callback;
        }
    }
    return NULL;
}

#pragma mark TypeSystem


struct TypeSystemInstance
{
    TypeSystemInstance() :
    name(),
    description(),
    create_callback(NULL)
    {
    }

    ConstString name;
    std::string description;
    TypeSystemCreateInstance create_callback;
    TypeSystemEnumerateSupportedLanguages enumerate_callback;
};

typedef std::vector<TypeSystemInstance> TypeSystemInstances;

static Mutex &
GetTypeSystemMutex ()
{
    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
    return g_instances_mutex;
}

static TypeSystemInstances &
GetTypeSystemInstances ()
{
    static TypeSystemInstances g_instances;
    return g_instances;
}

bool
PluginManager::RegisterPlugin (const ConstString &name,
                               const char *description,
                               TypeSystemCreateInstance create_callback,
                               TypeSystemEnumerateSupportedLanguages enumerate_supported_languages_callback)
{
    if (create_callback)
    {
        TypeSystemInstance instance;
        assert ((bool)name);
        instance.name = name;
        if (description && description[0])
            instance.description = description;
        instance.create_callback = create_callback;
        instance.enumerate_callback = enumerate_supported_languages_callback;
        Mutex::Locker locker (GetTypeSystemMutex ());
        GetTypeSystemInstances ().push_back (instance);
    }
    return false;
}

bool
PluginManager::UnregisterPlugin (TypeSystemCreateInstance create_callback)
{
    if (create_callback)
    {
        Mutex::Locker locker (GetTypeSystemMutex ());
        TypeSystemInstances &instances = GetTypeSystemInstances ();

        TypeSystemInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (pos->create_callback == create_callback)
            {
                instances.erase(pos);
                return true;
            }
        }
    }
    return false;
}

TypeSystemCreateInstance
PluginManager::GetTypeSystemCreateCallbackAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetTypeSystemMutex ());
    TypeSystemInstances &instances = GetTypeSystemInstances ();
    if (idx < instances.size())
        return instances[idx].create_callback;
    return NULL;
}

TypeSystemCreateInstance
PluginManager::GetTypeSystemCreateCallbackForPluginName (const ConstString &name)
{
    if (name)
    {
        Mutex::Locker locker (GetTypeSystemMutex ());
        TypeSystemInstances &instances = GetTypeSystemInstances ();

        TypeSystemInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (name == pos->name)
                return pos->create_callback;
        }
    }
    return NULL;
}

TypeSystemEnumerateSupportedLanguages
PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetTypeSystemMutex ());
    TypeSystemInstances &instances = GetTypeSystemInstances ();
    if (idx < instances.size())
        return instances[idx].enumerate_callback;
    return NULL;
}

TypeSystemEnumerateSupportedLanguages
PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackForPluginName (const ConstString &name)
{
    if (name)
    {
        Mutex::Locker locker (GetTypeSystemMutex ());
        TypeSystemInstances &instances = GetTypeSystemInstances ();
        
        TypeSystemInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (name == pos->name)
                return pos->enumerate_callback;
        }
    }
    return NULL;
}

#pragma mark REPL

struct REPLInstance
{
    REPLInstance() :
    name(),
    description(),
    create_callback(NULL)
    {
    }
    
    ConstString name;
    std::string description;
    REPLCreateInstance create_callback;
    REPLEnumerateSupportedLanguages enumerate_languages_callback;
};

typedef std::vector<REPLInstance> REPLInstances;

static Mutex &
GetREPLMutex ()
{
    static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
    return g_instances_mutex;
}

static REPLInstances &
GetREPLInstances ()
{
    static REPLInstances g_instances;
    return g_instances;
}

bool
PluginManager::RegisterPlugin (const ConstString &name,
                               const char *description,
                               REPLCreateInstance create_callback,
                               REPLEnumerateSupportedLanguages enumerate_languages_callback)
{
    if (create_callback)
    {
        REPLInstance instance;
        assert ((bool)name);
        instance.name = name;
        if (description && description[0])
            instance.description = description;
        instance.create_callback = create_callback;
        instance.enumerate_languages_callback = enumerate_languages_callback;
        Mutex::Locker locker (GetREPLMutex ());
        GetREPLInstances ().push_back (instance);
    }
    return false;
}

bool
PluginManager::UnregisterPlugin (REPLCreateInstance create_callback)
{
    if (create_callback)
    {
        Mutex::Locker locker (GetREPLMutex ());
        REPLInstances &instances = GetREPLInstances ();
        
        REPLInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (pos->create_callback == create_callback)
            {
                instances.erase(pos);
                return true;
            }
        }
    }
    return false;
}

REPLCreateInstance
PluginManager::GetREPLCreateCallbackAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetREPLMutex ());
    REPLInstances &instances = GetREPLInstances ();
    if (idx < instances.size())
        return instances[idx].create_callback;
    return NULL;
}

REPLCreateInstance
PluginManager::GetREPLCreateCallbackForPluginName (const ConstString &name)
{
    if (name)
    {
        Mutex::Locker locker (GetREPLMutex ());
        REPLInstances &instances = GetREPLInstances ();
        
        REPLInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (name == pos->name)
                return pos->create_callback;
        }
    }
    return NULL;
}

REPLEnumerateSupportedLanguages
PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex (uint32_t idx)
{
    Mutex::Locker locker (GetREPLMutex ());
    REPLInstances &instances = GetREPLInstances ();
    if (idx < instances.size())
        return instances[idx].enumerate_languages_callback;
    return NULL;
}


REPLEnumerateSupportedLanguages
PluginManager::GetREPLSystemEnumerateSupportedLanguagesCallbackForPluginName (const ConstString &name)
{
    if (name)
    {
        Mutex::Locker locker (GetREPLMutex ());
        REPLInstances &instances = GetREPLInstances ();
        
        REPLInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (name == pos->name)
                return pos->enumerate_languages_callback;
        }
    }
    return NULL;
}

#pragma mark PluginManager

void
PluginManager::DebuggerInitialize (Debugger &debugger)
{
    // Initialize the DynamicLoader plugins
    {
        Mutex::Locker locker (GetDynamicLoaderMutex ());
        DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
    
        DynamicLoaderInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (pos->debugger_init_callback)
                pos->debugger_init_callback (debugger);
        }
    }

    // Initialize the JITLoader plugins
    {
        Mutex::Locker locker (GetJITLoaderMutex ());
        JITLoaderInstances &instances = GetJITLoaderInstances ();
    
        JITLoaderInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (pos->debugger_init_callback)
                pos->debugger_init_callback (debugger);
        }
    }

    // Initialize the Platform plugins
    {
        Mutex::Locker locker (GetPlatformInstancesMutex ());
        PlatformInstances &instances = GetPlatformInstances ();
    
        PlatformInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (pos->debugger_init_callback)
                pos->debugger_init_callback (debugger);
        }
    }

    // Initialize the Process plugins
    {
        Mutex::Locker locker (GetProcessMutex());
        ProcessInstances &instances = GetProcessInstances();
        
        ProcessInstances::iterator pos, end = instances.end();
        for (pos = instances.begin(); pos != end; ++ pos)
        {
            if (pos->debugger_init_callback)
                pos->debugger_init_callback (debugger);
        }
    }

    // Initialize the SymbolFile plugins
    {
        Mutex::Locker locker (GetSymbolFileMutex());
        for (auto& sym_file: GetSymbolFileInstances())
        {
            if (sym_file.debugger_init_callback)
                sym_file.debugger_init_callback (debugger);
        }
    }

    // Initialize the OperatingSystem plugins
    {
        Mutex::Locker locker(GetOperatingSystemMutex());
        for (auto &os : GetOperatingSystemInstances())
        {
            if (os.debugger_init_callback)
                os.debugger_init_callback(debugger);
        }
    }
}

// This is the preferred new way to register plugin specific settings.  e.g.
// This will put a plugin's settings under e.g. "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
static lldb::OptionValuePropertiesSP
GetDebuggerPropertyForPlugins (Debugger &debugger,
                                       const ConstString &plugin_type_name,
                                       const ConstString &plugin_type_desc,
                                       bool can_create)
{
    lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties());
    if (parent_properties_sp)
    {
        static ConstString g_property_name("plugin");
        
        OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, g_property_name);
        if (!plugin_properties_sp && can_create)
        {
            plugin_properties_sp.reset (new OptionValueProperties (g_property_name));
            parent_properties_sp->AppendProperty (g_property_name,
                                                  ConstString("Settings specify to plugins."),
                                                  true,
                                                  plugin_properties_sp);
        }
        
        if (plugin_properties_sp)
        {
            lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, plugin_type_name);
            if (!plugin_type_properties_sp && can_create)
            {
                plugin_type_properties_sp.reset (new OptionValueProperties (plugin_type_name));
                plugin_properties_sp->AppendProperty (plugin_type_name,
                                                      plugin_type_desc,
                                                      true,
                                                      plugin_type_properties_sp);
            }
            return plugin_type_properties_sp;
        }
    }
    return lldb::OptionValuePropertiesSP();
}

// This is deprecated way to register plugin specific settings.  e.g.
// "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME"
// and Platform generic settings would be under "platform.SETTINGNAME".
static lldb::OptionValuePropertiesSP
GetDebuggerPropertyForPluginsOldStyle (Debugger &debugger,
                                       const ConstString &plugin_type_name,
                                       const ConstString &plugin_type_desc,
                                       bool can_create)
{
    static ConstString g_property_name("plugin");
    lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties());
    if (parent_properties_sp)
    {
        OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty (NULL, plugin_type_name);
        if (!plugin_properties_sp && can_create)
        {
            plugin_properties_sp.reset (new OptionValueProperties (plugin_type_name));
            parent_properties_sp->AppendProperty (plugin_type_name,
                                                  plugin_type_desc,
                                                  true,
                                                  plugin_properties_sp);
        }
        
        if (plugin_properties_sp)
        {
            lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty (NULL, g_property_name);
            if (!plugin_type_properties_sp && can_create)
            {
                plugin_type_properties_sp.reset (new OptionValueProperties (g_property_name));
                plugin_properties_sp->AppendProperty (g_property_name,
                                                      ConstString("Settings specific to plugins"),
                                                      true,
                                                      plugin_type_properties_sp);
            }
            return plugin_type_properties_sp;
        }
    }
    return lldb::OptionValuePropertiesSP();
}

namespace {

typedef lldb::OptionValuePropertiesSP
GetDebuggerPropertyForPluginsPtr (Debugger&, const ConstString&, const ConstString&, bool can_create);

lldb::OptionValuePropertiesSP
GetSettingForPlugin (Debugger &debugger,
                     const ConstString &setting_name,
                     const ConstString &plugin_type_name,
                     GetDebuggerPropertyForPluginsPtr get_debugger_property= GetDebuggerPropertyForPlugins)
{
    lldb::OptionValuePropertiesSP properties_sp;
    lldb::OptionValuePropertiesSP plugin_type_properties_sp (get_debugger_property (debugger,
                                                                                    plugin_type_name,
                                                                                    ConstString(), // not creating to so we don't need the description
                                                                                    false));
    if (plugin_type_properties_sp)
        properties_sp = plugin_type_properties_sp->GetSubProperty (nullptr, setting_name);
    return properties_sp;
}

bool
CreateSettingForPlugin (Debugger &debugger,
                        const ConstString &plugin_type_name,
                        const ConstString &plugin_type_desc,
                        const lldb::OptionValuePropertiesSP &properties_sp,
                        const ConstString &description,
                        bool is_global_property,
                        GetDebuggerPropertyForPluginsPtr get_debugger_property = GetDebuggerPropertyForPlugins)
{
    if (properties_sp)
    {
        lldb::OptionValuePropertiesSP plugin_type_properties_sp (get_debugger_property (
            debugger, plugin_type_name, plugin_type_desc, true));
        if (plugin_type_properties_sp)
        {
            plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
                                                       description,
                                                       is_global_property,
                                                       properties_sp);
            return true;
        }
    }
    return false;
}

const char* kDynamicLoaderPluginName("dynamic-loader");
const char* kPlatformPluginName("platform");
const char* kProcessPluginName("process");
const char* kSymbolFilePluginName("symbol-file");
const char* kJITLoaderPluginName("jit-loader");

}

lldb::OptionValuePropertiesSP
PluginManager::GetSettingForDynamicLoaderPlugin (Debugger &debugger,
                                                 const ConstString &setting_name)
{
    return GetSettingForPlugin(debugger, setting_name, ConstString(kDynamicLoaderPluginName));
}

bool
PluginManager::CreateSettingForDynamicLoaderPlugin (Debugger &debugger,
                                                    const lldb::OptionValuePropertiesSP &properties_sp,
                                                    const ConstString &description,
                                                    bool is_global_property)
{
    return CreateSettingForPlugin(debugger,
                                  ConstString(kDynamicLoaderPluginName),
                                  ConstString("Settings for dynamic loader plug-ins"),
                                  properties_sp,
                                  description,
                                  is_global_property);
}


lldb::OptionValuePropertiesSP
PluginManager::GetSettingForPlatformPlugin (Debugger &debugger, const ConstString &setting_name)
{
    return GetSettingForPlugin(debugger,
                               setting_name,
                               ConstString(kPlatformPluginName),
                               GetDebuggerPropertyForPluginsOldStyle);
}

bool
PluginManager::CreateSettingForPlatformPlugin (Debugger &debugger,
                                               const lldb::OptionValuePropertiesSP &properties_sp,
                                               const ConstString &description,
                                               bool is_global_property)
{
    return CreateSettingForPlugin(debugger,
                                  ConstString(kPlatformPluginName),
                                  ConstString("Settings for platform plug-ins"),
                                  properties_sp,
                                  description,
                                  is_global_property,
                                  GetDebuggerPropertyForPluginsOldStyle);
}


lldb::OptionValuePropertiesSP
PluginManager::GetSettingForProcessPlugin (Debugger &debugger, const ConstString &setting_name)
{
    return GetSettingForPlugin(debugger, setting_name, ConstString(kProcessPluginName));
}

bool
PluginManager::CreateSettingForProcessPlugin (Debugger &debugger,
                                              const lldb::OptionValuePropertiesSP &properties_sp,
                                              const ConstString &description,
                                              bool is_global_property)
{
    return CreateSettingForPlugin(debugger,
                                  ConstString(kProcessPluginName),
                                  ConstString("Settings for process plug-ins"),
                                  properties_sp,
                                  description,
                                  is_global_property);
}

lldb::OptionValuePropertiesSP
PluginManager::GetSettingForSymbolFilePlugin (Debugger &debugger,
                                              const ConstString &setting_name)
{
    return GetSettingForPlugin(debugger, setting_name, ConstString(kSymbolFilePluginName));
}

bool
PluginManager::CreateSettingForSymbolFilePlugin (Debugger &debugger,
                                                 const lldb::OptionValuePropertiesSP &properties_sp,
                                                 const ConstString &description,
                                                 bool is_global_property)
{
    return CreateSettingForPlugin(debugger,
                                  ConstString(kSymbolFilePluginName),
                                  ConstString("Settings for symbol file plug-ins"),
                                  properties_sp,
                                  description,
                                  is_global_property);
}

lldb::OptionValuePropertiesSP
PluginManager::GetSettingForJITLoaderPlugin (Debugger &debugger,
                                             const ConstString &setting_name)
{
    return GetSettingForPlugin(debugger, setting_name, ConstString(kJITLoaderPluginName));
}

bool
PluginManager::CreateSettingForJITLoaderPlugin (Debugger &debugger,
                                                const lldb::OptionValuePropertiesSP &properties_sp,
                                                const ConstString &description,
                                                bool is_global_property)
{
    return CreateSettingForPlugin(debugger,
                                  ConstString(kJITLoaderPluginName),
                                  ConstString("Settings for JIT loader plug-ins"),
                                  properties_sp,
                                  description,
                                  is_global_property);
}

static const char *kOperatingSystemPluginName("os");

lldb::OptionValuePropertiesSP
PluginManager::GetSettingForOperatingSystemPlugin(Debugger &debugger, const ConstString &setting_name)
{
    lldb::OptionValuePropertiesSP properties_sp;
    lldb::OptionValuePropertiesSP plugin_type_properties_sp(
        GetDebuggerPropertyForPlugins(debugger, ConstString(kOperatingSystemPluginName),
                                      ConstString(), // not creating to so we don't need the description
                                      false));
    if (plugin_type_properties_sp)
        properties_sp = plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
    return properties_sp;
}

bool
PluginManager::CreateSettingForOperatingSystemPlugin(Debugger &debugger,
                                                     const lldb::OptionValuePropertiesSP &properties_sp,
                                                     const ConstString &description, bool is_global_property)
{
    if (properties_sp)
    {
        lldb::OptionValuePropertiesSP plugin_type_properties_sp(
            GetDebuggerPropertyForPlugins(debugger, ConstString(kOperatingSystemPluginName),
                                          ConstString("Settings for operating system plug-ins"), true));
        if (plugin_type_properties_sp)
        {
            plugin_type_properties_sp->AppendProperty(properties_sp->GetName(), description, is_global_property,
                                                      properties_sp);
            return true;
        }
    }
    return false;
}
