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

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

}

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

