/**
   * Returns a list of projects for the given arguments.
   *
   * @param projects the list to which the projects are added
   * @return a pair of Mode (single job, jobs from view or all) and view name - where view name will
   *     be null if mode != VIEW
   */
  Pair<Mode, String> getProjects(
      Sender sender, String[] args, Collection<AbstractProject<?, ?>> projects)
      throws CommandException {
    final Mode mode;
    String view = null;
    if (args.length >= 2) {
      if ("-v".equals(args[1])) {
        mode = Mode.VIEW;
        view = MessageHelper.getJoinedName(args, 2);
        getProjectsForView(projects, view);
      } else {
        mode = Mode.SINGLE;
        String jobName = MessageHelper.getJoinedName(args, 1);

        AbstractProject<?, ?> project = getJobProvider().getJobByName(jobName);
        if (project != null) {
          projects.add(project);
        } else {
          throw new CommandException(sender.getNickname() + ": " + UNKNOWN_JOB_STR + " " + jobName);
        }
      }
    } else if (args.length == 1) {
      mode = Mode.ALL;
      for (AbstractProject<?, ?> project : getJobProvider().getAllJobs()) {
        // add only top level project
        // sub project are accessible by their name but are not shown for visibility
        if (getJobProvider().isTopLevelJob(project)) {
          projects.add(project);
        }
      }
    } else {
      throw new CommandException(sender + ": 'args' must not be empty!");
    }
    return Pair.create(mode, view);
  }
  @Override
  protected String getReply(Bot bot, Sender sender, String[] args) {

    //    	if (!authorizationCheck()) {
    //    		return "Sorry, can't do that!";
    //    	}

    Collection<AbstractProject<?, ?>> projects = new ArrayList<AbstractProject<?, ?>>();

    final Pair<Mode, String> pair;
    try {
      pair = getProjects(sender, args, projects);
    } catch (CommandException e) {
      return getErrorReply(sender, e);
    }

    if (!projects.isEmpty()) {
      StringBuilder msg = new StringBuilder();

      switch (pair.getHead()) {
        case SINGLE:
          break;
        case ALL:
          msg.append(getCommandShortName()).append(" of all projects:\n");
          break;
        case VIEW:
          msg.append(getCommandShortName())
              .append(" of projects in view " + pair.getTail() + ":\n");
          break;
      }

      boolean first = true;
      for (AbstractProject<?, ?> project : projects) {
        if (!first) {
          msg.append("\n");
        } else {
          first = false;
        }

        msg.append(getMessageForJob(project));
      }
      return msg.toString();
    } else {
      return sender + ": no job found";
    }
  }