//===-- PluginManager.cpp ---------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Core/PluginManager.h"

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

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

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

#include <map>
#include <memory>
#include <mutex>
#include <string>
#include <utility>
#include <vector>

#include <assert.h>

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 FileSystem::EnumerateDirectoryResult
LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft,
                   llvm::StringRef path) {
  //    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(path);
    FileSystem::Instance().Resolve(plugin_file_spec);

    if (PluginIsLoaded(plugin_file_spec))
      return FileSystem::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 FileSystem::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 FileSystem::eEnumerateDirectoryResultEnter;
  }

  return FileSystem::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 (FileSystem::Instance().Exists(dir_spec) &&
        dir_spec.GetPath(dir_path, sizeof(dir_path))) {
      FileSystem::Instance().EnumerateDirectory(dir_path, find_directories,
                                                find_files, find_other,
                                                LoadPluginCallback, nullptr);
    }
  }

  if (FileSpec dir_spec = HostInfo::GetUserPluginDir()) {
    if (FileSystem::Instance().Exists(dir_spec) &&
        dir_spec.GetPath(dir_path, sizeof(dir_path))) {
      FileSystem::Instance().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 &GetArchitectureMutex() {
    static std::mutex g_architecture_mutex;
    return 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(GetArchitectureMutex());
  GetArchitectureInstances().push_back({name, description, create_callback});
}

void PluginManager::UnregisterPlugin(
    ArchitectureCreateInstance create_callback) {
  std::lock_guard<std::mutex> guard(GetArchitectureMutex());
  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(GetArchitectureMutex());
  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);
}
