//===-- 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/lldb-python.h"

#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/Mutex.h"
#include "lldb/Interpreter/OptionValueProperties.h"

#include "llvm/ADT/StringRef.h"

using namespace lldb;
using namespace lldb_private;

enum PluginAction
{
    ePluginRegisterInstance,
    ePluginUnregisterInstance,
    ePluginGetInstanceAtIndex
};


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

struct PluginInfo
{
    void *plugin_handle;
    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;
}


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 = { NULL, NULL, NULL };
            uint32_t flags = Host::eDynamicLibraryOpenOptionLazy |
                             Host::eDynamicLibraryOpenOptionLocal |
                             Host::eDynamicLibraryOpenOptionLimitGetSymbol;

            plugin_info.plugin_handle = Host::DynamicLibraryOpen (plugin_file_spec, flags, error);
            if (plugin_info.plugin_handle)
            {
                bool success = false;
                plugin_info.plugin_init_callback = (PluginInitCallback)Host::DynamicLibraryGetSymbol (plugin_info.plugin_handle, "LLDBPluginInitialize", error);
                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 = (PluginTermCallback)Host::DynamicLibraryGetSymbol (plugin_info.plugin_handle, "LLDBPluginTerminate", error);
                }
                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.
                    Host::DynamicLibraryClose (plugin_info.plugin_handle);
                    plugin_info.plugin_handle = NULL;
                    plugin_info.plugin_init_callback = NULL;
                }

                // 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 enurating 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 (Host::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 (Host::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.plugin_handle)
        {
            if (pos->second.plugin_term_callback)
                pos->second.plugin_term_callback();
            Host::DynamicLibraryClose (pos->second.plugin_handle);
        }
    }
    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 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(NULL)
    {
    }
    
    ConstString name;
    std::string description;
    OperatingSystemCreateInstance create_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)
{
    if (create_callback)
    {
        OperatingSystemInstance instance;
        assert ((bool)name);
        instance.name = name;
        if (description && description[0])
            instance.description = description;
        instance.create_callback = create_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 LanguageRuntime


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

    ConstString name;
    std::string description;
    LanguageRuntimeCreateInstance create_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
)
{
    if (create_callback)
    {
        LanguageRuntimeInstance instance;
        assert ((bool)name);
        instance.name = name;
        if (description && description[0])
            instance.description = description;
        instance.create_callback = create_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;
}

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 ObjectFile

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

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

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)
{
    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.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;
}



#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 SymbolFile

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

    ConstString name;
    std::string description;
    SymbolFileCreateInstance create_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
)
{
    if (create_callback)
    {
        SymbolFileInstance instance;
        assert ((bool)name);
        instance.name = name;
        if (description && description[0])
            instance.description = description;
        instance.create_callback = create_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;
}

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 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);
        }
    }

}

// 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();
}


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

bool
PluginManager::CreateSettingForDynamicLoaderPlugin (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("dynamic-loader"),
                                                                                                ConstString("Settings for dynamic loader 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;
}


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

bool
PluginManager::CreateSettingForPlatformPlugin (Debugger &debugger,
                                                    const lldb::OptionValuePropertiesSP &properties_sp,
                                                    const ConstString &description,
                                                    bool is_global_property)
{
    if (properties_sp)
    {
        lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPluginsOldStyle (debugger,
                                                                                                        ConstString("platform"),
                                                                                                        ConstString("Settings for platform 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;
}


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

bool
PluginManager::CreateSettingForProcessPlugin (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("process"),
                                                                                                ConstString("Settings for process 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;
}

