@Post
  @Path("/reports")
  @LoggedIn
  public void addReport(
      String text,
      List<String> badint,
      List<String> comments,
      List<String> badintStart,
      List<String> badintEnd,
      List<String> badintRule,
      List<String> omissionClassification,
      List<String> customOmissionText,
      List<String> omissionComment,
      List<String> omissionReplaceBy,
      List<String> omissionStart,
      List<String> omissionEnd) {

    if (LOG.isDebugEnabled()) {
      LOG.debug("Adding new report.");
    }
    text = sanitizer.sanitize(text, false, true);

    comments = sanitizer.sanitize(comments, true);

    customOmissionText = sanitizer.sanitize(customOmissionText, false);

    omissionComment = sanitizer.sanitize(omissionComment, true);

    omissionReplaceBy = sanitizer.sanitize(omissionReplaceBy, false);

    errorEntryLogic.addErrorEntry(
        loggedUser.getUser(),
        text,
        badint,
        comments,
        badintStart,
        badintEnd,
        badintRule,
        omissionClassification,
        customOmissionText,
        omissionComment,
        omissionReplaceBy,
        omissionStart,
        omissionEnd);

    result.include("okMessage", "Problema reportado com sucesso!");
    result.include("gaEventErrorReported", true);

    if (LOG.isDebugEnabled()) {
      LOG.debug("New report added.");
    }
    result.redirectTo(getClass()).list();
  }
  @Post
  @Path("/reports/{errorEntry.id}/comments")
  public void addComment(ErrorEntry errorEntry, String newComment) {
    newComment = sanitizer.sanitize(newComment, true);
    ErrorEntry errorEntryFromDB = errorEntryDAO.retrieve(new Long(errorEntry.getId()));

    LOG.debug("errorEntry: " + errorEntryFromDB);
    LOG.debug("newComment: " + newComment);
    if (newComment.trim().isEmpty()) {
      validator.add(
          new ValidationMessage(
              ExceptionMessages.COMMENT_SHOULD_NOT_BE_EMPTY, ExceptionMessages.ERROR));
      validator
          .onErrorUse(Results.logic())
          .redirectTo(ErrorReportController.class)
          .details(errorEntryFromDB);
    } else if (newComment.trim().length() > COMMENT_MAX_SIZE) {
      validator.add(
          new ValidationMessage(
              ExceptionMessages.COMMENT_SHOULD_NOT_EXCEED_CHAR, ExceptionMessages.ERROR));
      validator
          .onErrorUse(Results.logic())
          .redirectTo(ErrorReportController.class)
          .details(errorEntryFromDB);
    } else {
      errorEntryLogic.addCommentToErrorEntry(
          errorEntryFromDB.getId(), loggedUser.getUser().getId(), newComment);
    }

    result.include("gaEventCommentAdded", true);

    result.redirectTo(ErrorReportController.class).details(errorEntryFromDB);
  }
 @Post
 @Path("/reports/{errorEntry.id}/comments/{comment.id}/answers")
 @LoggedIn
 public void addAnswerToComment(ErrorEntry errorEntry, Comment comment, String answer) {
   answer = sanitizer.sanitize(answer, true);
   errorEntryLogic.addAnswerToComment(comment.getId(), loggedUser.getUser().getId(), answer);
   result.include("gaEventCommentAdded", true);
   result.redirectTo(ErrorReportController.class).details(errorEntry);
 }
  @Put
  @Path("/reports/edit")
  @LoggedIn
  public void multipleEdit(
      Boolean applycomment,
      Boolean applypriority,
      Boolean applystate,
      Integer errorlist_lenght,
      Long[] errorEntryID,
      String newComment,
      String priority,
      String state) {
    if (loggedUser.getUser().getRole().getCanEditErrorReport()) {

      String comment = null;
      if (applycomment != null && applycomment) {
        comment = sanitizer.sanitize(newComment, true);
        ;
      }
      Priority priorityEnum = null;
      if (applypriority != null && applypriority) {
        priorityEnum = Enum.valueOf(Priority.class, priority);
      }
      State stateEnum = null;
      if (applystate != null && applystate) {
        stateEnum = Enum.valueOf(State.class, state);
      }
      List<ErrorEntry> entries = new ArrayList<ErrorEntry>();
      if (errorEntryID != null && errorEntryID.length > 0) {
        LOG.info("Selected errors: " + Arrays.toString(errorEntryID));

        for (int i = 0; i < errorEntryID.length; i++) {
          if (errorEntryID[i] != null) {
            LOG.info("Will get error " + i);
            ErrorEntry error = this.errorEntryDAO.retrieve(errorEntryID[i]);
            LOG.info("Got " + error);
            entries.add(error);
          }
        }
      }
      errorEntryLogic.multipleEdit(entries, priorityEnum, stateEnum, comment);
    } else {
      LOG.info("Invalid user tried to set priority: " + loggedUser.getUser());
    }

    result.redirectTo(getClass()).list();
  }
  @Post
  @Path("/reports/newtext")
  public void addReport(String text) {
    text = sanitizer.sanitize(text, false, true);
    try {
      if (text != null && text.length() >= 0) {
        if (text.length() > 255) {
          text = text.substring(0, 255);
        }

        if (!loggedUser.isLogged()) {
          // if not logged we save the text.
          if (LOG.isDebugEnabled()) {
            LOG.debug("Saving error report text before login: "******"Error text: " + text);
        }
        List<ProcessResult> pr = cogrooFacade.processText(text);
        if (LOG.isDebugEnabled()) {
          LOG.debug("Text processed. Results:");
          for (ProcessResult processResult : pr) {
            LOG.debug("... " + processResult.getTextAnnotatedWithErrors());
          }
        }
        result
            .include("analyzed", true)
            .include("cleanText", text)
            .include("annotatedText", cogrooFacade.getAnnotatedText(text, pr))
            .include("singleGrammarErrorList", cogrooFacade.asSingleGrammarErrorList(text, pr))
            .include("omissionCategoriesList", this.errorEntryLogic.getErrorCategoriesForUser())
            .include("processResultList", pr)
            .redirectTo(getClass())
            .addReport();
      } else {
        result.redirectTo(getClass()).addReport();
      }
    } catch (Exception e) {
      LOG.error("Error processing text: " + text, e);
    }
  }
  @Put
  @Path("/reports/{reportId}")
  @LoggedIn
  public void updateErrorReport(
      Long reportId,
      String type,
      String badintIndex,
      String badintType,
      List<String> badintStart,
      List<String> badintEnd,
      List<String> badintRule,
      String omissionCategory,
      String omissionCustom,
      String omissionReplaceBy,
      String omissionStart,
      String omissionEnd) {

    LOG.debug(
        "reportId: "
            + reportId
            + "\n"
            + "type: "
            + type
            + "\n"
            + "badintIndex: "
            + badintIndex
            + "\n"
            + "badintType: "
            + badintType
            + "\n"
            + "badintStart: "
            + badintStart
            + "\n"
            + "badintEnd: "
            + badintEnd
            + "\n"
            + "badintRule: "
            + badintRule
            + "\n"
            + "omissionCategory: "
            + omissionCategory
            + "\n"
            + "omissionCustom: "
            + omissionCustom
            + "\n"
            + "omissionReplaceBy: "
            + omissionReplaceBy
            + "\n"
            + "omissionStart: "
            + omissionStart
            + "\n"
            + "omissionEnd: "
            + omissionEnd);

    ErrorEntry errorEntryFromDB = this.errorEntryDAO.retrieve(reportId);
    ErrorEntry originalErrorEntry = null;
    try {
      originalErrorEntry = (ErrorEntry) errorEntryFromDB.clone();

    } catch (CloneNotSupportedException e) {
      LOG.error("Error cloning ErrorEntry object: ", e);
    }
    if (type == null) {
      if (errorEntryFromDB.getBadIntervention() != null) {
        type = "BADINT";
      } else {
        type = "OMISSION";
      }
    }
    if (type.equals("BADINT")) {
      GrammarCheckerBadIntervention newBadIntervention = null;
      if (errorEntryFromDB.getBadIntervention() == null) {
        newBadIntervention = new GrammarCheckerBadIntervention();
        errorEntryFromDB.setBadIntervention(newBadIntervention);
      } else {
        newBadIntervention = errorEntryFromDB.getBadIntervention();
      }

      newBadIntervention.setClassification(
          Enum.valueOf(BadInterventionClassification.class, badintType));
      newBadIntervention.setErrorEntry(errorEntryFromDB);
      newBadIntervention.setRule(badintRule.get(Integer.valueOf(badintIndex) - 1));

      errorEntryFromDB.setSpanStart(
          Integer.valueOf(badintStart.get(Integer.valueOf(badintIndex) - 1)));
      errorEntryFromDB.setSpanEnd(Integer.valueOf(badintEnd.get(Integer.valueOf(badintIndex) - 1)));

      this.errorEntryLogic.updateBadIntervention(errorEntryFromDB, originalErrorEntry);
    } else {
      int start = -1;
      int end = -1;

      if (omissionStart != null && omissionEnd != null) {
        start = Integer.parseInt(omissionStart);
        end = Integer.parseInt(omissionEnd);
      }

      GrammarCheckerOmission o = null;
      if (errorEntryFromDB.getOmission() == null) {
        o = new GrammarCheckerOmission();
        errorEntryFromDB.setOmission(o);
      } else {
        o = errorEntryFromDB.getOmission();
      }

      o.setCategory(omissionCategory);
      if (omissionCategory.equals(ErrorEntryLogic.CUSTOM)) {
        o.setCustomCategory(sanitizer.sanitize(omissionCustom, false));
      } else {
        o.setCustomCategory(null);
      }
      o.setErrorEntry(errorEntryFromDB);
      o.setReplaceBy(sanitizer.sanitize(omissionReplaceBy, false));

      errorEntryFromDB.setSpanStart(start);
      errorEntryFromDB.setSpanEnd(end);

      if (!(end > 0 && end > start)) {
        validator.add(
            new ValidationMessage(
                ExceptionMessages.ERROR_REPORT_OMISSION_INVALID_SELECTION,
                ExceptionMessages.ERROR));
      }
      if (omissionCategory.equals("custom")
          && (omissionCustom == null || omissionCustom.length() == 0)) {
        validator.add(
            new ValidationMessage(
                ExceptionMessages.ERROR_REPORT_OMISSION_MISSING_CUSTOM_CATEGORY,
                ExceptionMessages.ERROR));
      }
      if ((omissionReplaceBy == null || omissionReplaceBy.length() == 0)) {
        validator.add(
            new ValidationMessage(
                ExceptionMessages.ERROR_REPORT_OMISSION_MISSING_REPLACE, ExceptionMessages.ERROR));
      }
      if (validator.hasErrors()) {
        validator
            .onErrorUse(Results.logic())
            .redirectTo(ErrorReportController.class)
            .editDetails(errorEntryFromDB);
        return;
      }
      this.errorEntryLogic.updateOmission(errorEntryFromDB, originalErrorEntry);
    }

    result.include("gaEventErrorChanged", true);
    result.redirectTo(getClass()).details(errorEntryFromDB);
  }