//===-- 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(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(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(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(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(
    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(
    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(
    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(
    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(
    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(
    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(
    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(
    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(
    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(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(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;
  LanguageRuntimeGetExceptionPrecondition precondition_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(
    ConstString name, const char *description,
    LanguageRuntimeCreateInstance create_callback,
    LanguageRuntimeGetCommandObject command_callback,
    LanguageRuntimeGetExceptionPrecondition precondition_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;
    instance.precondition_callback = precondition_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;
}

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

LanguageRuntimeCreateInstance
PluginManager::GetLanguageRuntimeCreateCallbackForPluginName(
    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(
    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(
    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(
    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(
    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(
    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(
    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(
    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(
    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(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(
    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(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(
    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,
                                               Debugger &debugger) {
  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(debugger);
  }

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

#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(
    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(
    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(
    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(
    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(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(
    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(
    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(
    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(
    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(
    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(
    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(
    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(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(
    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(
    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(
    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(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(
    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, ConstString plugin_type_name,
    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, ConstString plugin_type_name,
    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 &, ConstString ,
                                 ConstString , bool can_create);

lldb::OptionValuePropertiesSP
GetSettingForPlugin(Debugger &debugger, ConstString setting_name,
                    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, ConstString plugin_type_name,
    ConstString plugin_type_desc,
    const lldb::OptionValuePropertiesSP &properties_sp,
    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, ConstString setting_name) {
  return GetSettingForPlugin(debugger, setting_name,
                             ConstString(kDynamicLoaderPluginName));
}

bool PluginManager::CreateSettingForDynamicLoaderPlugin(
    Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
    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,
                                           ConstString setting_name) {
  return GetSettingForPlugin(debugger, setting_name,
                             ConstString(kPlatformPluginName),
                             GetDebuggerPropertyForPluginsOldStyle);
}

bool PluginManager::CreateSettingForPlatformPlugin(
    Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
    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,
                                          ConstString setting_name) {
  return GetSettingForPlugin(debugger, setting_name,
                             ConstString(kProcessPluginName));
}

bool PluginManager::CreateSettingForProcessPlugin(
    Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
    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,
                                             ConstString setting_name) {
  return GetSettingForPlugin(debugger, setting_name,
                             ConstString(kSymbolFilePluginName));
}

bool PluginManager::CreateSettingForSymbolFilePlugin(
    Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
    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,
                                            ConstString setting_name) {
  return GetSettingForPlugin(debugger, setting_name,
                             ConstString(kJITLoaderPluginName));
}

bool PluginManager::CreateSettingForJITLoaderPlugin(
    Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
    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, 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,
    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, ConstString setting_name) {
  return GetSettingForPlugin(debugger, setting_name,
                             ConstString(kStructuredDataPluginName));
}

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