/**
   * Register all known HSP commands. This includes those defined by the admin in the config file as
   * well as all commands found automatically on the command path.
   */
  public void registerAllCommands() {
    // loop through all config-defined command and load them up
    Set<String> commands = commandConfig.getDefinedCommands();
    for (String cmd : commands) {
      registerConfigCommand(cmd);
    }

    Set<Class<? extends Command>> commandClasses = getCommandClasses();
    // now loop through all normal commands in the class path
    for (Class<? extends Command> clazz : commandClasses) {
      log.devDebug("checking found class ", clazz);
      registerDefaultCommand(clazz);
    }
  }
  /**
   * Given a command name, look for and register that command from the admin-configured command
   * definitions.
   *
   * @param cmd
   * @param classes
   */
  private void registerConfigCommand(String cmd) {
    log.devDebug("processing config defined command ", cmd);
    Map<String, Object> cmdParams = commandConfig.getCommandParameters(cmd);

    Class<? extends Command> cmdClass = null;
    String className = null;
    Object clazz = cmdParams.get("class");

    // if no class given, just assume the name of the commmand
    if (clazz == null) clazz = cmd;

    if (clazz != null && clazz instanceof String) {
      className = (String) clazz;

      // if class given, but no package given, assume default package
      if (className.indexOf('.') == -1) {
        String firstChar = className.substring(0, 1);
        String theRest = className.substring(1);
        className = firstChar.toUpperCase() + theRest;
        cmdClass = findCommandClass(className);
      }
    }

    // if we have no commandClass yet, but we do have a className, then
    // try to find that className.
    if (cmdClass == null && className != null) {
      cmdClass = findCommandClass(className);
    }

    if (cmdClass == null) {
      log.warn("No class defined or found for command ", cmd);
      return;
    }

    try {
      Command command = (Command) cmdClass.newInstance();
      command.setCommandName(cmd.toLowerCase()); // default to name of instance key
      register(command, cmdParams);
    } catch (ClassCastException e) {
      log.warn("class " + cmdClass + " does not implement Command interface");
    } catch (Exception e) {
      log.warn(e, "error loading class " + cmdClass);
    }
  }
  @SuppressWarnings("unchecked")
  public void register(Command command, Map<String, Object> cmdParams) {
    String cmdName = command.getCommandName();

    log.devDebug("register() command=", command, ",cmdParams=", cmdParams);
    command.setPlugin(plugin);
    command.setCommandParameters(cmdParams);

    if (cmdParams.containsKey("name")) cmdName = (String) cmdParams.get("name");

    // we never load the same command twice
    if (loadedCommands.contains(cmdName)) return;

    CraftServer cs = (CraftServer) Bukkit.getServer();
    SimpleCommandMap commandMap = cs.getCommandMap();

    try {
      Constructor<PluginCommand> constructor =
          PluginCommand.class.getDeclaredConstructor(String.class, Plugin.class);
      constructor.setAccessible(true);

      // construct a new PluginCommand object
      PluginCommand pc = constructor.newInstance(cmdName, plugin);
      pc.setExecutor(command);
      pc.setLabel(cmdName);
      if (command.getUsage() != null) pc.setUsage(command.getUsage());

      // don't set Permission node, not all permission plugins behave
      // with superperms command permissions nicely.
      //			pc.setPermission(command.getCommandPermissionNode());

      // check for aliases defined in the configuration
      Object o = cmdParams.get("aliases");
      if (o != null) {
        List<String> aliases = null;
        if (o instanceof List) {
          aliases = (List<String>) o;
        } else if (o instanceof String) {
          aliases = new ArrayList<String>(2);
          aliases.add((String) o);
        } else log.warn("invalid aliases defined for command ", cmdName, ": ", o);

        if (aliases == null) aliases = new ArrayList<String>(1);

        aliases.add("hsp" + command.getCommandName()); // all commands have "hsp" prefix alias
        pc.setAliases(aliases);
      }
      // otherwise set whatever the command has defined
      else {
        List<String> aliases = new ArrayList<String>(5);
        String[] strAliases = command.getCommandAliases();
        if (strAliases != null) {
          for (String alias : strAliases) {
            aliases.add(alias);
          }
        }
        aliases.add("hsp" + command.getCommandName()); // all commands have "hsp" prefix alias
        pc.setAliases(aliases);
      }

      // register it
      commandMap.register("hsp", pc);
      loadedCommands.add(cmdName);

      Debug.getInstance().devDebug("register() command ", command, " registered");
    } catch (Exception e) {
      e.printStackTrace();
    }
  }