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

#include "lldb/Core/PluginManager.h"

#include "lldb/Core/Debugger.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Utility/ConstString.h" // for ConstString
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StringList.h" // for StringList

#if defined(_WIN32)
#include "lldb/Host/windows/PosixApi.h" // for PATH_MAX
#endif

#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/FileSystem.h"  // for file_type, file_...
#include "llvm/Support/raw_ostream.h" // for fs

#include <map>    // for map<>::const_ite...
#include <memory> // for shared_ptr
#include <mutex>
#include <string>
#include <utility> // for pair
#include <vector>

#include <assert.h> // for assert

namespace lldb_private {
class CommandInterpreter;
}

using namespace lldb;
using namespace lldb_private;

enum PluginAction {
  ePluginRegisterInstance,
  ePluginUnregisterInstance,
  ePluginGetInstanceAtIndex
};

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

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

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

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

static std::recursive_mutex &GetPluginMapMutex() {
  static std::recursive_mutex g_plugin_map_mutex;
  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) {
  std::lock_guard<std::recursive_mutex> guard(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) {
  std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
  PluginTerminateMap &plugin_map = GetPluginMap();
  assert(plugin_map.find(plugin_file_spec) == plugin_map.end());
  plugin_map[plugin_file_spec] = plugin_info;
}

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

static FileSpec::EnumerateDirectoryResult
LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft,
                   const FileSpec &file_spec) {
  //    PluginManager *plugin_manager = (PluginManager *)baton;
  Status error;

  namespace fs = llvm::sys::fs;
  // 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 (ft == fs::file_type::regular_file || ft == fs::file_type::symlink_file ||
      ft == fs::file_type::type_unknown) {
    FileSpec plugin_file_spec(file_spec);
    plugin_file_spec.ResolvePath();

    if (PluginIsLoaded(plugin_file_spec))
      return FileSpec::eEnumerateDirectoryResultNext;
    else {
      PluginInfo plugin_info;

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

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

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

        return FileSpec::eEnumerateDirectoryResultNext;
      }
    }
  }

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

  return FileSpec::eEnumerateDirectoryResultNext;
}

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

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

void PluginManager::Terminate() {
  std::lock_guard<std::recursive_mutex> guard(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 nullptr).
    if (pos->second.library.isValid()) {
      if (pos->second.plugin_term_callback)
        pos->second.plugin_term_callback();
    }
  }
  plugin_map.clear();
}

#pragma mark ABI

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

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

typedef std::vector<ABIInstance> ABIInstances;

static std::recursive_mutex &GetABIInstancesMutex() {
  static std::recursive_mutex g_instances_mutex;
  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;
    std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
    GetABIInstances().push_back(instance);
    return true;
  }
  return false;
}

bool PluginManager::UnregisterPlugin(ABICreateInstance create_callback) {
  if (create_callback) {
    std::lock_guard<std::recursive_mutex> guard(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) {
  std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
  ABIInstances &instances = GetABIInstances();
  if (idx < instances.size())
    return instances[idx].create_callback;
  return nullptr;
}

ABICreateInstance
PluginManager::GetABICreateCallbackForPluginName(const ConstString &name) {
  if (name) {
    std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}

#pragma mark Architecture

struct ArchitectureInstance {
  ConstString name;
  std::string description;
  PluginManager::ArchitectureCreateInstance create_callback;
};

typedef std::vector<ArchitectureInstance> ArchitectureInstances;

static std::mutex g_architecture_mutex;

static ArchitectureInstances &GetArchitectureInstances() {
  static ArchitectureInstances g_instances;
  return g_instances;
}

void PluginManager::RegisterPlugin(const ConstString &name,
                                   llvm::StringRef description,
                                   ArchitectureCreateInstance create_callback) {
  std::lock_guard<std::mutex> guard(g_architecture_mutex);
  GetArchitectureInstances().push_back({name, description, create_callback});
}

void PluginManager::UnregisterPlugin(
    ArchitectureCreateInstance create_callback) {
  std::lock_guard<std::mutex> guard(g_architecture_mutex);
  auto &instances = GetArchitectureInstances();

  for (auto pos = instances.begin(), end = instances.end(); pos != end; ++pos) {
    if (pos->create_callback == create_callback) {
      instances.erase(pos);
      return;
    }
  }
  llvm_unreachable("Plugin not found");
}

std::unique_ptr<Architecture>
PluginManager::CreateArchitectureInstance(const ArchSpec &arch) {
  std::lock_guard<std::mutex> guard(g_architecture_mutex);
  for (const auto &instances : GetArchitectureInstances()) {
    if (auto plugin_up = instances.create_callback(arch))
      return plugin_up;
  }
  return nullptr;
}

#pragma mark Disassembler

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

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

typedef std::vector<DisassemblerInstance> DisassemblerInstances;

static std::recursive_mutex &GetDisassemblerMutex() {
  static std::recursive_mutex g_instances_mutex;
  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;
    std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
    GetDisassemblerInstances().push_back(instance);
    return true;
  }
  return false;
}

bool PluginManager::UnregisterPlugin(
    DisassemblerCreateInstance create_callback) {
  if (create_callback) {
    std::lock_guard<std::recursive_mutex> guard(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) {
  std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
  DisassemblerInstances &instances = GetDisassemblerInstances();
  if (idx < instances.size())
    return instances[idx].create_callback;
  return nullptr;
}

DisassemblerCreateInstance
PluginManager::GetDisassemblerCreateCallbackForPluginName(
    const ConstString &name) {
  if (name) {
    std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}

#pragma mark DynamicLoader

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

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

typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances;

static std::recursive_mutex &GetDynamicLoaderMutex() {
  static std::recursive_mutex g_instances_mutex;
  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;
    std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
    GetDynamicLoaderInstances().push_back(instance);
  }
  return false;
}

bool PluginManager::UnregisterPlugin(
    DynamicLoaderCreateInstance create_callback) {
  if (create_callback) {
    std::lock_guard<std::recursive_mutex> guard(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) {
  std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
  DynamicLoaderInstances &instances = GetDynamicLoaderInstances();
  if (idx < instances.size())
    return instances[idx].create_callback;
  return nullptr;
}

DynamicLoaderCreateInstance
PluginManager::GetDynamicLoaderCreateCallbackForPluginName(
    const ConstString &name) {
  if (name) {
    std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}

#pragma mark JITLoader

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

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

typedef std::vector<JITLoaderInstance> JITLoaderInstances;

static std::recursive_mutex &GetJITLoaderMutex() {
  static std::recursive_mutex g_instances_mutex;
  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;
    std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
    GetJITLoaderInstances().push_back(instance);
  }
  return false;
}

bool PluginManager::UnregisterPlugin(JITLoaderCreateInstance create_callback) {
  if (create_callback) {
    std::lock_guard<std::recursive_mutex> guard(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) {
  std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
  JITLoaderInstances &instances = GetJITLoaderInstances();
  if (idx < instances.size())
    return instances[idx].create_callback;
  return nullptr;
}

JITLoaderCreateInstance PluginManager::GetJITLoaderCreateCallbackForPluginName(
    const ConstString &name) {
  if (name) {
    std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}

#pragma mark EmulateInstruction

struct EmulateInstructionInstance {
  EmulateInstructionInstance()
      : name(), description(), create_callback(nullptr) {}

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

typedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances;

static std::recursive_mutex &GetEmulateInstructionMutex() {
  static std::recursive_mutex g_instances_mutex;
  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;
    std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
    GetEmulateInstructionInstances().push_back(instance);
  }
  return false;
}

bool PluginManager::UnregisterPlugin(
    EmulateInstructionCreateInstance create_callback) {
  if (create_callback) {
    std::lock_guard<std::recursive_mutex> guard(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) {
  std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
  EmulateInstructionInstances &instances = GetEmulateInstructionInstances();
  if (idx < instances.size())
    return instances[idx].create_callback;
  return nullptr;
}

EmulateInstructionCreateInstance
PluginManager::GetEmulateInstructionCreateCallbackForPluginName(
    const ConstString &name) {
  if (name) {
    std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}

#pragma mark OperatingSystem

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

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

typedef std::vector<OperatingSystemInstance> OperatingSystemInstances;

static std::recursive_mutex &GetOperatingSystemMutex() {
  static std::recursive_mutex g_instances_mutex;
  return g_instances_mutex;
}

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

bool PluginManager::RegisterPlugin(
    const ConstString &name, const char *description,
    OperatingSystemCreateInstance create_callback,
    DebuggerInitializeCallback debugger_init_callback) {
  if (create_callback) {
    OperatingSystemInstance instance;
    assert((bool)name);
    instance.name = name;
    if (description && description[0])
      instance.description = description;
    instance.create_callback = create_callback;
    instance.debugger_init_callback = debugger_init_callback;
    std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
    GetOperatingSystemInstances().push_back(instance);
  }
  return false;
}

bool PluginManager::UnregisterPlugin(
    OperatingSystemCreateInstance create_callback) {
  if (create_callback) {
    std::lock_guard<std::recursive_mutex> guard(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) {
  std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
  OperatingSystemInstances &instances = GetOperatingSystemInstances();
  if (idx < instances.size())
    return instances[idx].create_callback;
  return nullptr;
}

OperatingSystemCreateInstance
PluginManager::GetOperatingSystemCreateCallbackForPluginName(
    const ConstString &name) {
  if (name) {
    std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}

#pragma mark Language

struct LanguageInstance {
  LanguageInstance() : name(), description(), create_callback(nullptr) {}

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

typedef std::vector<LanguageInstance> LanguageInstances;

static std::recursive_mutex &GetLanguageMutex() {
  static std::recursive_mutex g_instances_mutex;
  return g_instances_mutex;
}

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

bool PluginManager::RegisterPlugin(const ConstString &name,
                                   const char *description,
                                   LanguageCreateInstance create_callback) {
  if (create_callback) {
    LanguageInstance instance;
    assert((bool)name);
    instance.name = name;
    if (description && description[0])
      instance.description = description;
    instance.create_callback = create_callback;
    std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
    GetLanguageInstances().push_back(instance);
  }
  return false;
}

bool PluginManager::UnregisterPlugin(LanguageCreateInstance create_callback) {
  if (create_callback) {
    std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
    LanguageInstances &instances = GetLanguageInstances();

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

LanguageCreateInstance
PluginManager::GetLanguageCreateCallbackAtIndex(uint32_t idx) {
  std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
  LanguageInstances &instances = GetLanguageInstances();
  if (idx < instances.size())
    return instances[idx].create_callback;
  return nullptr;
}

LanguageCreateInstance
PluginManager::GetLanguageCreateCallbackForPluginName(const ConstString &name) {
  if (name) {
    std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
    LanguageInstances &instances = GetLanguageInstances();

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

#pragma mark LanguageRuntime

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

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

typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;

static std::recursive_mutex &GetLanguageRuntimeMutex() {
  static std::recursive_mutex g_instances_mutex;
  return g_instances_mutex;
}

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

bool PluginManager::RegisterPlugin(
    const ConstString &name, const char *description,
    LanguageRuntimeCreateInstance create_callback,
    LanguageRuntimeGetCommandObject command_callback) {
  if (create_callback) {
    LanguageRuntimeInstance instance;
    assert((bool)name);
    instance.name = name;
    if (description && description[0])
      instance.description = description;
    instance.create_callback = create_callback;
    instance.command_callback = command_callback;
    std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
    GetLanguageRuntimeInstances().push_back(instance);
  }
  return false;
}

bool PluginManager::UnregisterPlugin(
    LanguageRuntimeCreateInstance create_callback) {
  if (create_callback) {
    std::lock_guard<std::recursive_mutex> guard(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) {
  std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
  LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
  if (idx < instances.size())
    return instances[idx].create_callback;
  return nullptr;
}

LanguageRuntimeGetCommandObject
PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx) {
  std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
  LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
  if (idx < instances.size())
    return instances[idx].command_callback;
  return nullptr;
}

LanguageRuntimeCreateInstance
PluginManager::GetLanguageRuntimeCreateCallbackForPluginName(
    const ConstString &name) {
  if (name) {
    std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}

#pragma mark SystemRuntime

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

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

typedef std::vector<SystemRuntimeInstance> SystemRuntimeInstances;

static std::recursive_mutex &GetSystemRuntimeMutex() {
  static std::recursive_mutex g_instances_mutex;
  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;
    std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
    GetSystemRuntimeInstances().push_back(instance);
  }
  return false;
}

bool PluginManager::UnregisterPlugin(
    SystemRuntimeCreateInstance create_callback) {
  if (create_callback) {
    std::lock_guard<std::recursive_mutex> guard(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) {
  std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
  SystemRuntimeInstances &instances = GetSystemRuntimeInstances();
  if (idx < instances.size())
    return instances[idx].create_callback;
  return nullptr;
}

SystemRuntimeCreateInstance
PluginManager::GetSystemRuntimeCreateCallbackForPluginName(
    const ConstString &name) {
  if (name) {
    std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}

#pragma mark ObjectFile

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

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

typedef std::vector<ObjectFileInstance> ObjectFileInstances;

static std::recursive_mutex &GetObjectFileMutex() {
  static std::recursive_mutex g_instances_mutex;
  return g_instances_mutex;
}

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

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

bool PluginManager::UnregisterPlugin(ObjectFileCreateInstance create_callback) {
  if (create_callback) {
    std::lock_guard<std::recursive_mutex> guard(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) {
  std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
  ObjectFileInstances &instances = GetObjectFileInstances();
  if (idx < instances.size())
    return instances[idx].create_callback;
  return nullptr;
}

ObjectFileCreateMemoryInstance
PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(uint32_t idx) {
  std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
  ObjectFileInstances &instances = GetObjectFileInstances();
  if (idx < instances.size())
    return instances[idx].create_memory_callback;
  return nullptr;
}

ObjectFileGetModuleSpecifications
PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex(
    uint32_t idx) {
  std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
  ObjectFileInstances &instances = GetObjectFileInstances();
  if (idx < instances.size())
    return instances[idx].get_module_specifications;
  return nullptr;
}

ObjectFileCreateInstance
PluginManager::GetObjectFileCreateCallbackForPluginName(
    const ConstString &name) {
  if (name) {
    std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}

ObjectFileCreateMemoryInstance
PluginManager::GetObjectFileCreateMemoryCallbackForPluginName(
    const ConstString &name) {
  if (name) {
    std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}

Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp,
                               const FileSpec &outfile) {
  Status error;
  std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
  ObjectFileInstances &instances = GetObjectFileInstances();

  ObjectFileInstances::iterator pos, end = instances.end();
  for (pos = instances.begin(); pos != end; ++pos) {
    if (pos->save_core && pos->save_core(process_sp, outfile, error))
      return error;
  }
  error.SetErrorString(
      "no ObjectFile plugins were able to save a core for this process");
  return error;
}

#pragma mark ObjectContainer

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

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

typedef std::vector<ObjectContainerInstance> ObjectContainerInstances;

static std::recursive_mutex &GetObjectContainerMutex() {
  static std::recursive_mutex g_instances_mutex;
  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;
    std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
    GetObjectContainerInstances().push_back(instance);
  }
  return false;
}

bool PluginManager::UnregisterPlugin(
    ObjectContainerCreateInstance create_callback) {
  if (create_callback) {
    std::lock_guard<std::recursive_mutex> guard(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) {
  std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
  ObjectContainerInstances &instances = GetObjectContainerInstances();
  if (idx < instances.size())
    return instances[idx].create_callback;
  return nullptr;
}

ObjectContainerCreateInstance
PluginManager::GetObjectContainerCreateCallbackForPluginName(
    const ConstString &name) {
  if (name) {
    std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}

ObjectFileGetModuleSpecifications
PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex(
    uint32_t idx) {
  std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
  ObjectContainerInstances &instances = GetObjectContainerInstances();
  if (idx < instances.size())
    return instances[idx].get_module_specifications;
  return nullptr;
}

#pragma mark Platform

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

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

typedef std::vector<PlatformInstance> PlatformInstances;

static std::recursive_mutex &GetPlatformInstancesMutex() {
  static std::recursive_mutex g_platform_instances_mutex;
  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) {
    std::lock_guard<std::recursive_mutex> guard(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) {
  std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
  PlatformInstances &instances = GetPlatformInstances();
  if (idx < instances.size())
    return instances[idx].name.GetCString();
  return nullptr;
}

const char *PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) {
  std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
  PlatformInstances &instances = GetPlatformInstances();
  if (idx < instances.size())
    return instances[idx].description.c_str();
  return nullptr;
}

bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) {
  if (create_callback) {
    std::lock_guard<std::recursive_mutex> guard(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) {
  std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
  PlatformInstances &instances = GetPlatformInstances();
  if (idx < instances.size())
    return instances[idx].create_callback;
  return nullptr;
}

PlatformCreateInstance
PluginManager::GetPlatformCreateCallbackForPluginName(const ConstString &name) {
  if (name) {
    std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}

size_t PluginManager::AutoCompletePlatformName(llvm::StringRef name,
                                               StringList &matches) {
  if (name.empty())
    return matches.GetSize();

  std::lock_guard<std::recursive_mutex> guard(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(nullptr),
        debugger_init_callback(nullptr) {}

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

typedef std::vector<ProcessInstance> ProcessInstances;

static std::recursive_mutex &GetProcessMutex() {
  static std::recursive_mutex g_instances_mutex;
  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;
    std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
    GetProcessInstances().push_back(instance);
  }
  return false;
}

const char *PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) {
  std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
  ProcessInstances &instances = GetProcessInstances();
  if (idx < instances.size())
    return instances[idx].name.GetCString();
  return nullptr;
}

const char *PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) {
  std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
  ProcessInstances &instances = GetProcessInstances();
  if (idx < instances.size())
    return instances[idx].description.c_str();
  return nullptr;
}

bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) {
  if (create_callback) {
    std::lock_guard<std::recursive_mutex> guard(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) {
  std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
  ProcessInstances &instances = GetProcessInstances();
  if (idx < instances.size())
    return instances[idx].create_callback;
  return nullptr;
}

ProcessCreateInstance
PluginManager::GetProcessCreateCallbackForPluginName(const ConstString &name) {
  if (name) {
    std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}

#pragma mark ScriptInterpreter

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

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

typedef std::vector<ScriptInterpreterInstance> ScriptInterpreterInstances;

static std::recursive_mutex &GetScriptInterpreterMutex() {
  static std::recursive_mutex g_instances_mutex;
  return g_instances_mutex;
}

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

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

bool PluginManager::UnregisterPlugin(
    ScriptInterpreterCreateInstance create_callback) {
  if (!create_callback)
    return false;
  std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
  ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();

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

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

ScriptInterpreterCreateInstance
PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx) {
  std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
  ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
  if (idx < instances.size())
    return instances[idx].create_callback;
  return nullptr;
}

lldb::ScriptInterpreterSP PluginManager::GetScriptInterpreterForLanguage(
    lldb::ScriptLanguage script_lang, CommandInterpreter &interpreter) {
  std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
  ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();

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

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

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

#pragma mark -
#pragma mark StructuredDataPlugin

// -----------------------------------------------------------------------------
// StructuredDataPlugin
// -----------------------------------------------------------------------------

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

  ConstString name;
  std::string description;
  StructuredDataPluginCreateInstance create_callback;
  DebuggerInitializeCallback debugger_init_callback;
  StructuredDataFilterLaunchInfo filter_callback;
};

typedef std::vector<StructuredDataPluginInstance> StructuredDataPluginInstances;

static std::recursive_mutex &GetStructuredDataPluginMutex() {
  static std::recursive_mutex g_instances_mutex;
  return g_instances_mutex;
}

static StructuredDataPluginInstances &GetStructuredDataPluginInstances() {
  static StructuredDataPluginInstances g_instances;
  return g_instances;
}

bool PluginManager::RegisterPlugin(
    const ConstString &name, const char *description,
    StructuredDataPluginCreateInstance create_callback,
    DebuggerInitializeCallback debugger_init_callback,
    StructuredDataFilterLaunchInfo filter_callback) {
  if (create_callback) {
    StructuredDataPluginInstance 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;
    instance.filter_callback = filter_callback;
    std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
    GetStructuredDataPluginInstances().push_back(instance);
  }
  return false;
}

bool PluginManager::UnregisterPlugin(
    StructuredDataPluginCreateInstance create_callback) {
  if (create_callback) {
    std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
    StructuredDataPluginInstances &instances =
        GetStructuredDataPluginInstances();

    StructuredDataPluginInstances::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;
}

StructuredDataPluginCreateInstance
PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx) {
  std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
  StructuredDataPluginInstances &instances = GetStructuredDataPluginInstances();
  if (idx < instances.size())
    return instances[idx].create_callback;
  return nullptr;
}

StructuredDataPluginCreateInstance
PluginManager::GetStructuredDataPluginCreateCallbackForPluginName(
    const ConstString &name) {
  if (name) {
    std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
    StructuredDataPluginInstances &instances =
        GetStructuredDataPluginInstances();

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

StructuredDataFilterLaunchInfo
PluginManager::GetStructuredDataFilterCallbackAtIndex(
    uint32_t idx, bool &iteration_complete) {
  std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
  StructuredDataPluginInstances &instances = GetStructuredDataPluginInstances();
  if (idx < instances.size()) {
    iteration_complete = false;
    return instances[idx].filter_callback;
  } else {
    iteration_complete = true;
  }
  return nullptr;
}

#pragma mark SymbolFile

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

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

typedef std::vector<SymbolFileInstance> SymbolFileInstances;

static std::recursive_mutex &GetSymbolFileMutex() {
  static std::recursive_mutex g_instances_mutex;
  return g_instances_mutex;
}

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

bool PluginManager::RegisterPlugin(
    const ConstString &name, const char *description,
    SymbolFileCreateInstance create_callback,
    DebuggerInitializeCallback debugger_init_callback) {
  if (create_callback) {
    SymbolFileInstance instance;
    assert((bool)name);
    instance.name = name;
    if (description && description[0])
      instance.description = description;
    instance.create_callback = create_callback;
    instance.debugger_init_callback = debugger_init_callback;
    std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
    GetSymbolFileInstances().push_back(instance);
  }
  return false;
}

bool PluginManager::UnregisterPlugin(SymbolFileCreateInstance create_callback) {
  if (create_callback) {
    std::lock_guard<std::recursive_mutex> guard(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) {
  std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
  SymbolFileInstances &instances = GetSymbolFileInstances();
  if (idx < instances.size())
    return instances[idx].create_callback;
  return nullptr;
}

SymbolFileCreateInstance
PluginManager::GetSymbolFileCreateCallbackForPluginName(
    const ConstString &name) {
  if (name) {
    std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}

#pragma mark SymbolVendor

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

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

typedef std::vector<SymbolVendorInstance> SymbolVendorInstances;

static std::recursive_mutex &GetSymbolVendorMutex() {
  static std::recursive_mutex g_instances_mutex;
  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;
    std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
    GetSymbolVendorInstances().push_back(instance);
  }
  return false;
}

bool PluginManager::UnregisterPlugin(
    SymbolVendorCreateInstance create_callback) {
  if (create_callback) {
    std::lock_guard<std::recursive_mutex> guard(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) {
  std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
  SymbolVendorInstances &instances = GetSymbolVendorInstances();
  if (idx < instances.size())
    return instances[idx].create_callback;
  return nullptr;
}

SymbolVendorCreateInstance
PluginManager::GetSymbolVendorCreateCallbackForPluginName(
    const ConstString &name) {
  if (name) {
    std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}

#pragma mark UnwindAssembly

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

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

typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances;

static std::recursive_mutex &GetUnwindAssemblyMutex() {
  static std::recursive_mutex g_instances_mutex;
  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;
    std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
    GetUnwindAssemblyInstances().push_back(instance);
  }
  return false;
}

bool PluginManager::UnregisterPlugin(
    UnwindAssemblyCreateInstance create_callback) {
  if (create_callback) {
    std::lock_guard<std::recursive_mutex> guard(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) {
  std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
  UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances();
  if (idx < instances.size())
    return instances[idx].create_callback;
  return nullptr;
}

UnwindAssemblyCreateInstance
PluginManager::GetUnwindAssemblyCreateCallbackForPluginName(
    const ConstString &name) {
  if (name) {
    std::lock_guard<std::recursive_mutex> guard(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 nullptr;
}

#pragma mark MemoryHistory

struct MemoryHistoryInstance {
  MemoryHistoryInstance() : name(), description(), create_callback(nullptr) {}

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

typedef std::vector<MemoryHistoryInstance> MemoryHistoryInstances;

static std::recursive_mutex &GetMemoryHistoryMutex() {
  static std::recursive_mutex g_instances_mutex;
  return g_instances_mutex;
}

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

bool PluginManager::RegisterPlugin(
    const ConstString &name, const char *description,
    MemoryHistoryCreateInstance create_callback) {
  if (create_callback) {
    MemoryHistoryInstance instance;
    assert((bool)name);
    instance.name = name;
    if (description && description[0])
      instance.description = description;
    instance.create_callback = create_callback;
    std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
    GetMemoryHistoryInstances().push_back(instance);
  }
  return false;
}

bool PluginManager::UnregisterPlugin(
    MemoryHistoryCreateInstance create_callback) {
  if (create_callback) {
    std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
    MemoryHistoryInstances &instances = GetMemoryHistoryInstances();

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

MemoryHistoryCreateInstance
PluginManager::GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx) {
  std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
  MemoryHistoryInstances &instances = GetMemoryHistoryInstances();
  if (idx < instances.size())
    return instances[idx].create_callback;
  return nullptr;
}

MemoryHistoryCreateInstance
PluginManager::GetMemoryHistoryCreateCallbackForPluginName(
    const ConstString &name) {
  if (name) {
    std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
    MemoryHistoryInstances &instances = GetMemoryHistoryInstances();

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

#pragma mark InstrumentationRuntime

struct InstrumentationRuntimeInstance {
  InstrumentationRuntimeInstance()
      : name(), description(), create_callback(nullptr) {}

  ConstString name;
  std::string description;
  InstrumentationRuntimeCreateInstance create_callback;
  InstrumentationRuntimeGetType get_type_callback;
};

typedef std::vector<InstrumentationRuntimeInstance>
    InstrumentationRuntimeInstances;

static std::recursive_mutex &GetInstrumentationRuntimeMutex() {
  static std::recursive_mutex g_instances_mutex;
  return g_instances_mutex;
}

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

bool PluginManager::RegisterPlugin(
    const ConstString &name, const char *description,
    InstrumentationRuntimeCreateInstance create_callback,
    InstrumentationRuntimeGetType get_type_callback) {
  if (create_callback) {
    InstrumentationRuntimeInstance instance;
    assert((bool)name);
    instance.name = name;
    if (description && description[0])
      instance.description = description;
    instance.create_callback = create_callback;
    instance.get_type_callback = get_type_callback;
    std::lock_guard<std::recursive_mutex> guard(
        GetInstrumentationRuntimeMutex());
    GetInstrumentationRuntimeInstances().push_back(instance);
  }
  return false;
}

bool PluginManager::UnregisterPlugin(
    InstrumentationRuntimeCreateInstance create_callback) {
  if (create_callback) {
    std::lock_guard<std::recursive_mutex> guard(
        GetInstrumentationRuntimeMutex());
    InstrumentationRuntimeInstances &instances =
        GetInstrumentationRuntimeInstances();

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

InstrumentationRuntimeGetType
PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx) {
  std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex());
  InstrumentationRuntimeInstances &instances =
      GetInstrumentationRuntimeInstances();
  if (idx < instances.size())
    return instances[idx].get_type_callback;
  return nullptr;
}

InstrumentationRuntimeCreateInstance
PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) {
  std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex());
  InstrumentationRuntimeInstances &instances =
      GetInstrumentationRuntimeInstances();
  if (idx < instances.size())
    return instances[idx].create_callback;
  return nullptr;
}

InstrumentationRuntimeCreateInstance
PluginManager::GetInstrumentationRuntimeCreateCallbackForPluginName(
    const ConstString &name) {
  if (name) {
    std::lock_guard<std::recursive_mutex> guard(
        GetInstrumentationRuntimeMutex());
    InstrumentationRuntimeInstances &instances =
        GetInstrumentationRuntimeInstances();

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

#pragma mark TypeSystem

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

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

typedef std::vector<TypeSystemInstance> TypeSystemInstances;

static std::recursive_mutex &GetTypeSystemMutex() {
  static std::recursive_mutex g_instances_mutex;
  return g_instances_mutex;
}

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

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

bool PluginManager::UnregisterPlugin(TypeSystemCreateInstance create_callback) {
  if (create_callback) {
    std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
    TypeSystemInstances &instances = GetTypeSystemInstances();

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

TypeSystemCreateInstance
PluginManager::GetTypeSystemCreateCallbackAtIndex(uint32_t idx) {
  std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
  TypeSystemInstances &instances = GetTypeSystemInstances();
  if (idx < instances.size())
    return instances[idx].create_callback;
  return nullptr;
}

TypeSystemCreateInstance
PluginManager::GetTypeSystemCreateCallbackForPluginName(
    const ConstString &name) {
  if (name) {
    std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
    TypeSystemInstances &instances = GetTypeSystemInstances();

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

TypeSystemEnumerateSupportedLanguages
PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex(
    uint32_t idx) {
  std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
  TypeSystemInstances &instances = GetTypeSystemInstances();
  if (idx < instances.size())
    return instances[idx].enumerate_callback;
  return nullptr;
}

TypeSystemEnumerateSupportedLanguages
PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackForPluginName(
    const ConstString &name) {
  if (name) {
    std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
    TypeSystemInstances &instances = GetTypeSystemInstances();

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

#pragma mark REPL

struct REPLInstance {
  REPLInstance() : name(), description(), create_callback(nullptr) {}

  ConstString name;
  std::string description;
  REPLCreateInstance create_callback;
  REPLEnumerateSupportedLanguages enumerate_languages_callback;
};

typedef std::vector<REPLInstance> REPLInstances;

static std::recursive_mutex &GetREPLMutex() {
  static std::recursive_mutex g_instances_mutex;
  return g_instances_mutex;
}

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

bool PluginManager::RegisterPlugin(
    const ConstString &name, const char *description,
    REPLCreateInstance create_callback,
    REPLEnumerateSupportedLanguages enumerate_languages_callback) {
  if (create_callback) {
    REPLInstance instance;
    assert((bool)name);
    instance.name = name;
    if (description && description[0])
      instance.description = description;
    instance.create_callback = create_callback;
    instance.enumerate_languages_callback = enumerate_languages_callback;
    std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
    GetREPLInstances().push_back(instance);
  }
  return false;
}

bool PluginManager::UnregisterPlugin(REPLCreateInstance create_callback) {
  if (create_callback) {
    std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
    REPLInstances &instances = GetREPLInstances();

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

REPLCreateInstance PluginManager::GetREPLCreateCallbackAtIndex(uint32_t idx) {
  std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
  REPLInstances &instances = GetREPLInstances();
  if (idx < instances.size())
    return instances[idx].create_callback;
  return nullptr;
}

REPLCreateInstance
PluginManager::GetREPLCreateCallbackForPluginName(const ConstString &name) {
  if (name) {
    std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
    REPLInstances &instances = GetREPLInstances();

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

REPLEnumerateSupportedLanguages
PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex(uint32_t idx) {
  std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
  REPLInstances &instances = GetREPLInstances();
  if (idx < instances.size())
    return instances[idx].enumerate_languages_callback;
  return nullptr;
}

REPLEnumerateSupportedLanguages
PluginManager::GetREPLSystemEnumerateSupportedLanguagesCallbackForPluginName(
    const ConstString &name) {
  if (name) {
    std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
    REPLInstances &instances = GetREPLInstances();

    REPLInstances::iterator pos, end = instances.end();
    for (pos = instances.begin(); pos != end; ++pos) {
      if (name == pos->name)
        return pos->enumerate_languages_callback;
    }
  }
  return nullptr;
}

#pragma mark PluginManager

void PluginManager::DebuggerInitialize(Debugger &debugger) {
  // Initialize the DynamicLoader plugins
  {
    std::lock_guard<std::recursive_mutex> guard(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
  {
    std::lock_guard<std::recursive_mutex> guard(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
  {
    std::lock_guard<std::recursive_mutex> guard(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
  {
    std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
    ProcessInstances &instances = GetProcessInstances();

    ProcessInstances::iterator pos, end = instances.end();
    for (pos = instances.begin(); pos != end; ++pos) {
      if (pos->debugger_init_callback)
        pos->debugger_init_callback(debugger);
    }
  }

  // Initialize the SymbolFile plugins
  {
    std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
    for (auto &sym_file : GetSymbolFileInstances()) {
      if (sym_file.debugger_init_callback)
        sym_file.debugger_init_callback(debugger);
    }
  }

  // Initialize the OperatingSystem plugins
  {
    std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
    for (auto &os : GetOperatingSystemInstances()) {
      if (os.debugger_init_callback)
        os.debugger_init_callback(debugger);
    }
  }

  // Initialize the StructuredDataPlugin plugins
  {
    std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
    for (auto &plugin : GetStructuredDataPluginInstances()) {
      if (plugin.debugger_init_callback)
        plugin.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(nullptr, g_property_name);
    if (!plugin_properties_sp && can_create) {
      plugin_properties_sp =
          std::make_shared<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(nullptr, plugin_type_name);
      if (!plugin_type_properties_sp && can_create) {
        plugin_type_properties_sp =
            std::make_shared<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(nullptr, plugin_type_name);
    if (!plugin_properties_sp && can_create) {
      plugin_properties_sp =
          std::make_shared<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(nullptr, g_property_name);
      if (!plugin_type_properties_sp && can_create) {
        plugin_type_properties_sp =
            std::make_shared<OptionValueProperties>(g_property_name);
        plugin_properties_sp->AppendProperty(
            g_property_name, ConstString("Settings specific to plugins"), true,
            plugin_type_properties_sp);
      }
      return plugin_type_properties_sp;
    }
  }
  return lldb::OptionValuePropertiesSP();
}

namespace {

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

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

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

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

} // anonymous namespace

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

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

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

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

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

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

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

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

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

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

static const char *kOperatingSystemPluginName("os");

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

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

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

bool PluginManager::CreateSettingForStructuredDataPlugin(
    Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
    const ConstString &description, bool is_global_property) {
  return CreateSettingForPlugin(
      debugger, ConstString(kStructuredDataPluginName),
      ConstString("Settings for structured data plug-ins"), properties_sp,
      description, is_global_property);
}
