/**
   * INTERNAL METHOD<br>
   * Builds the email message from a template and a bunch of variables (passed in and otherwise)
   *
   * @param messageTemplate
   * @param eval
   * @param group
   * @param replacementValues a map of String -> String representing $keys in the template to
   *     replace with text values
   * @return the processed message template with replacements and logic handled
   */
  public String makeEmailMessage(
      String messageTemplate,
      EvalEvaluation eval,
      EvalGroup group,
      Map<String, String> replacementValues) {
    // replace the text of the template with real values
    if (replacementValues == null) {
      replacementValues = new HashMap<String, String>();
    }
    replacementValues.put("EvalTitle", eval.getTitle());

    // use a date which is related to the current users locale
    DateFormat df =
        DateFormat.getDateInstance(
            DateFormat.MEDIUM, commonLogic.getUserLocale(commonLogic.getCurrentUserId()));

    replacementValues.put("EvalStartDate", df.format(eval.getStartDate()));
    String dueDate = "--------";
    if (eval.getDueDate() != null) {
      dueDate = df.format(eval.getDueDate());
    }
    replacementValues.put("EvalDueDate", dueDate);
    String viewDate = null;
    if (eval.getViewDate() != null) {
      viewDate = df.format(eval.getDueDate());
    } else {
      viewDate = dueDate;
    }
    replacementValues.put("EvalResultsDate", viewDate);
    replacementValues.put("EvalGroupTitle", group.title);

    // ensure that the if-then variables are set to false if they are unset
    if (!replacementValues.containsKey("ShowAddItemsText")) {
      replacementValues.put("ShowAddItemsText", "false");
    }
    if (!replacementValues.containsKey("ShowOptInText")) {
      replacementValues.put("ShowOptInText", "false");
    }
    if (!replacementValues.containsKey("ShowOptOutText")) {
      replacementValues.put("ShowOptOutText", "false");
    }

    // generate URLs to the evaluation
    String evalEntityURL = null;
    if (group != null && group.evalGroupId != null) {
      // get the URL directly to the evaluation with group context included
      Long assignGroupId = evaluationService.getAssignGroupId(eval.getId(), group.evalGroupId);
      EvalAssignGroup assignGroup = evaluationService.getAssignGroupById(assignGroupId);
      if (assignGroup != null) {
        evalEntityURL = commonLogic.getEntityURL(assignGroup);
      }
    }

    if (evalEntityURL == null) {
      // just get the URL to the evaluation without group context
      evalEntityURL = commonLogic.getEntityURL(eval);
    }

    // all URLs are identical because the user permissions determine access uniquely
    replacementValues.put("URLtoTakeEval", evalEntityURL);
    replacementValues.put("URLtoAddItems", evalEntityURL);
    replacementValues.put("URLtoOptIn", evalEntityURL);
    replacementValues.put("URLtoOptOut", evalEntityURL);
    replacementValues.put("URLtoViewResults", evalEntityURL);
    replacementValues.put("URLtoSystem", commonLogic.getServerUrl());

    return TextTemplateLogicUtils.processTextTemplate(messageTemplate, replacementValues);
  }