text: "use strict";
  
  var Logger = require("./logger"),
      _ = require("./utils/helpers");
  
  // Explicitly these modules here, so Browserify can grab them later
  require("./test/loopback");
  require("./test/test-adaptor");
  require("./test/test-driver");
  require("./test/ping");
  
  var missingModuleError = function(module) {
    var str = "Cannot find the '" + module + "' module.\n";
    str += "This problem might be fixed by installing it with ";
    str += "'npm install " + module + "' and trying again.";
  
    console.log(str);
  
    process.emit("SIGINT");
  };
  
  var Registry = module.exports = {
    data: {},
  
    register: function(module) {
      if (this.data[module]) {
        return this.data[module].module;
      }
  
      var pkg;
  
      try {
        pkg = require(module);
      } catch (e) {
        if (e.code === "MODULE_NOT_FOUND") {
          missingModuleError(module);
        }
  
        throw e;
      }
  
      this.data[module] = {
        module: pkg,
        adaptors: pkg.adaptors || [],
        drivers: pkg.drivers || [],
        dependencies: pkg.dependencies || []
      };
  
      this.logRegistration(module, this.data[module]);
  
      this.data[module].dependencies.forEach(function(dep) {
        Registry.register(dep);
      });
  
      return this.data[module].module;
    },
  
    findBy: function(prop, name) {
      // pluralize, if necessary
      if (prop.slice(-1) !== "s") {
        prop += "s";
      }
  
      return this.search(prop, name);
    },
  
    findByModule: function(module) {
      if (!this.data[module]) {
        return null;
      }
  
      return this.data[module].module;
    },
  
    logRegistration: function(name) {
      var module = this.data[name];
  
      Logger.debug("Registering module " + name);
  
      ["adaptors", "drivers", "dependencies"].forEach(function(field) {
        if (module[field].length) {
          Logger.debug("  " + field + ":");
          module[field].forEach(function(item) {
            Logger.debug("    - " + item);
          });
        }
      });
    },
  
    search: function(entry, value) {
      for (var name in this.data) {
        if (this.data.hasOwnProperty(name)) {
          var repo = this.data[name];
  
          if (repo[entry] && _.includes(repo[entry], value)) {
            return repo.module;
          }
        }
      }
  
      return false;
    }
  };
  
  // Default drivers/adaptors:
  ["loopback", "ping", "test-adaptor", "test-driver"].forEach(function(module) {
    Registry.register("./test/" + module);
  });
  