private void deleteAssessment(
      Request request,
      Response response,
      final String assessmentID,
      final String assessmentType,
      final String username) {
    try {
      AssessmentData assessment =
          AssessmentIO.readAssessment(vfs, assessmentID, assessmentType, username);
      boolean deleted = AssessmentIO.trashAssessment(vfs, assessment, username);

      if (deleted) {
        String log = "<assessment user=\"" + username;
        log += "\" status=\"" + assessmentType.toLowerCase().replace("_status", "");
        log +=
            "\" date=\""
                + new Date().toString()
                + "\" node=\""
                + assessment.getSpeciesName()
                + "\">"
                + assessmentID
                + "</assessment>";

        trashBuffer.addEvent(DocumentUtils.createDocumentFromString(log));
        trashBuffer.flush();

        // remove from recent
        final Request req =
            new Request(
                Method.DELETE,
                "riap://host/recentAssessments/" + username + assessmentType + "/" + assessmentID);
        Response resp = getContext().getClientDispatcher().handle(req);
        if (!(resp.getStatus()).isSuccess()) {
          System.out.println("Unable to delete assessment from recent.");
        } else {
          // node.removeAssessment(pubAssessments.get(i));
          System.out.println("Assessment deleted from recent.");
        }

        response.setStatus(Status.SUCCESS_OK);
      } else response.setStatus(Status.CLIENT_ERROR_LOCKED);
    } catch (Exception e) {
      SysDebugger.getInstance().println("Could not find assessment " + assessmentID);
      e.printStackTrace();
      response.setStatus(Status.CLIENT_ERROR_NOT_FOUND);
    }
  }
  private AssessmentData doCreateAssessmentForBatch(
      String user, AssessmentFilter filter, boolean useTemplate, TaxonNode taxon) {
    AssessmentFilter draftFilter = filter.deepCopy();
    draftFilter.setDraft(false);
    draftFilter.setRecentPublished(true);
    draftFilter.setAllPublished(false);

    AssessmentFilterHelper helper = new AssessmentFilterHelper(draftFilter);

    AssessmentData curAss = null;

    if (useTemplate) {
      List<AssessmentData> assessments = helper.getAssessments(taxon.getId() + "", vfs);
      if (assessments.size() == 0) {
        draftFilter.getRegions().clear();
        draftFilter.getRegions().add(AssessmentData.GLOBAL_ID);
        assessments = helper.getAssessments(taxon.getId() + "", vfs);
      }

      if (assessments.size() == 0) {
        System.out.println("No template exists for species " + taxon.getFullName());
        curAss = new AssessmentData(); // No template exists...
      } else {
        curAss = assessments.get(0).deepCopy();
      }
    } else curAss = new AssessmentData();

    curAss.setRegionIDs(filter.getRegions());
    if (!filter.getRegions().contains("-1")) curAss.setEndemic(false);
    curAss.setType(AssessmentData.DRAFT_ASSESSMENT_STATUS);
    curAss.setAssessmentID("new");
    curAss.setSpeciesID(taxon.getId() + "");
    curAss.setSpeciesName(taxon.getFullName());
    return curAss;
  }
  private void deleteAssessmentsForTaxon(
      String taxonID, String type, String user, Request request, Response response) {
    List<AssessmentData> assessments = AssessmentIO.readAllAssessmentsForTaxon(vfs, taxonID, user);
    for (AssessmentData cur : assessments) {
      deleteAssessment(request, response, cur.getAssessmentID(), cur.getType(), user);

      // If it's locked, force the release and delete again. Taxomatic operations are almighty.
      if (response.getStatus() == Status.CLIENT_ERROR_LOCKED) {
        Lock lock =
            FileLocker.impl.getAssessmentPersistentLock(cur.getAssessmentID(), cur.getType());
        FileLocker.impl.persistentEagerRelease(
            cur.getAssessmentID(), cur.getType(), lock.getUsername());
        deleteAssessment(request, response, cur.getAssessmentID(), cur.getType(), user);
      }
    }
  }
  /**
   * @param assessment
   * @param username
   * @param speciesID
   * @param displayName
   * @return
   */
  private AssessmentIOWriteResult assignIDAndSave(AssessmentData assessment, String username)
      throws RegionConflictException {
    if (assessment.getAssessmentID().equals("new")) {
      if (assessment.getType().equals(BaseAssessment.DRAFT_ASSESSMENT_STATUS))
        assessment.setAssessmentID(getNextDraftID(vfs, assessment.getSpeciesID()));
      else if (assessment.getType().equals(BaseAssessment.PUBLISHED_ASSESSMENT_STATUS))
        assessment.setAssessmentID(pubIDFactory.getNextIDAsString());
      else // TODO: Figure out if we're going to need multiple user assessments per species.
      assessment.setAssessmentID(assessment.getSpeciesID());
    }

    return saveAssessment(assessment, username);
  }
  private void putAssessment(Request request, Response response, String username) {
    try {
      NativeDocument doc = NativeDocumentFactory.newNativeDocument();
      doc.parse(request.getEntity().getText());
      AssessmentParser parser = new AssessmentParser(doc);
      AssessmentData assessment = parser.getAssessment();

      AssessmentIOWriteResult result = assignIDAndSave(assessment, username);
      if (result.status.isSuccess()) {
        response.setEntity(assessment.getAssessmentID(), MediaType.TEXT_PLAIN);
        response.setStatus(Status.SUCCESS_OK);
      } else {
        response.setStatus(Status.CLIENT_ERROR_EXPECTATION_FAILED);
      }
    } catch (RegionConflictException e) {
      response.setStatus(Status.CLIENT_ERROR_CONFLICT);
    } catch (Exception e) {
      response.setStatus(Status.SERVER_ERROR_INTERNAL);
    }
  }
  private AssessmentIOWriteResult saveAssessment(AssessmentData assessment, String username)
      throws RegionConflictException {
    if (assessment.getType().equals(BaseAssessment.DRAFT_ASSESSMENT_STATUS)) {
      List<AssessmentData> compareTo =
          AssessmentIO.readAllDraftAssessments(vfs, assessment.getSpeciesID());

      for (AssessmentData cur : compareTo) {
        if (cur.getRegionIDs().containsAll(assessment.getRegionIDs())
            || cur.isGlobal() && assessment.isGlobal()) {
          if (!cur.getAssessmentID().equals(assessment.getAssessmentID()))
            throw new RegionConflictException();
        }
      }
    }

    return AssessmentIO.writeAssessment(assessment, username, vfs, true);
  }
  private void postAssessment(Request request, Response response, String username) {
    try {
      String entity = request.getEntity().getText();

      NativeDocument doc = NativeDocumentFactory.newNativeDocument();
      doc.parse(entity);
      AssessmentParser parser = new AssessmentParser(doc);
      AssessmentData assessment = parser.getAssessment();

      VFSPath assessmentUrl = new VFSPath(ServerPaths.getPathForAssessment(assessment, username));

      if (vfs.exists(assessmentUrl)) {
        Status status =
            FileLocker.impl.persistentLockAssessment(
                assessment.getAssessmentID(),
                BaseAssessment.DRAFT_ASSESSMENT_STATUS,
                LockType.SAVE_LOCK,
                username);

        if (status.isSuccess()) {
          AssessmentIOWriteResult result = saveAssessment(assessment, username);
          if (result.status.isSuccess()) {
            response.setEntity(result.newLastModified + "", MediaType.TEXT_PLAIN);
            response.setStatus(status);
          } else {
            response.setStatus(Status.CLIENT_ERROR_EXPECTATION_FAILED);
          }
        } else {
          response.setStatus(status);
        }
      }
    } catch (RegionConflictException e) {
      response.setStatus(Status.CLIENT_ERROR_CONFLICT);
    } catch (Exception e) {
      e.printStackTrace();
      response.setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
    }
  }
  public static void processAssessment(AssessmentData currentAssessment) {
    FuzzyExpImpl expert = new FuzzyExpImpl();
    ExpertResult expertResult = expert.doAnalysis(currentAssessment);

    currentAssessment.setCategoryCriteria(expertResult.getCriteriaString());
    currentAssessment.setCrCriteria(expertResult.getCriteriaStringCR());
    currentAssessment.setEnCriteria(expertResult.getCriteriaStringEN());
    currentAssessment.setVuCriteria(expertResult.getCriteriaStringVU());

    if (expertResult.getResult() != null) {
      currentAssessment.setCategoryFuzzyResult(
          expertResult.getLeft() + "," + expertResult.getBest() + "," + expertResult.getRight());
      currentAssessment.setCategoryAbbreviation(expertResult.getAbbreviatedCategory());

      if (currentAssessment.isRegional()
          && currentAssessment.getDataMap().containsKey(CanonicalNames.RegionExpertQuestions)) {
        ArrayList<String> regionalExpString =
            (ArrayList<String>)
                currentAssessment.getDataMap().get(CanonicalNames.RegionExpertQuestions);
        String[] regionalExpData = regionalExpString.get(0).split(",");

        if (regionalExpData.length > 2) {
          String upDown = regionalExpData[0];
          String amount = regionalExpData[1];
          String category = currentAssessment.getCategoryAbbreviation();

          if (upDown.equals(RegionalExpertQuestions.UPGRADE)) {
            int amountUp = Integer.valueOf(amount);
            category = slideCategory(amountUp, category);
          } else if (upDown.equals(RegionalExpertQuestions.DOWNGRADE)) {
            int amountDown = Integer.valueOf(amount);
            category = slideCategory(-1 * amountDown, category);
          }

          currentAssessment.setCategoryAbbreviation(category);
        }
      } else {
        System.out.println("Couldn't find regional expert question data.");
      }

    } else {
      currentAssessment.setCategoryFuzzyResult("-1,-1,-1");
      currentAssessment.setCategoryAbbreviation("DD");
    }
  }
  private String batchCreate(Request request, String username) {
    NativeDocument doc = NativeDocumentFactory.newNativeDocument();
    StringBuffer successfulIDs = new StringBuffer();
    StringBuffer extantIDs = new StringBuffer();
    StringBuffer unsuccessfulIDs = new StringBuffer();

    try {
      String text = request.getEntity().getText();
      doc.parse(text);

      AssessmentFilter filter =
          AssessmentFilter.parseXML(
              doc.getDocumentElement()
                  .getElementsByTagName(AssessmentFilter.HEAD_TAG)
                  .elementAt(0));

      NativeNodeList nodes = doc.getDocumentElement().getElementsByTagName("taxon");
      boolean useTemplate =
          Boolean.parseBoolean(
              doc.getDocumentElement()
                  .getElementsByTagName("useTemplate")
                  .elementAt(0)
                  .getTextContent());
      System.out.println("Using template? " + useTemplate);

      for (int i = 0; i < nodes.getLength(); i++) {
        TaxonNode taxon = TaxaIO.readNode(nodes.elementAt(i).getTextContent(), vfs);
        AssessmentData curAss = null;

        curAss =
            doCreateAssessmentForBatch(
                request.getChallengeResponse().getIdentifier(), filter, useTemplate, taxon);

        try {
          AssessmentIOWriteResult result = assignIDAndSave(curAss, username);
          if (result.status.isSuccess())
            successfulIDs.append(
                curAss.getSpeciesName() + (i == nodes.getLength() - 1 ? "" : ", "));
          else
            unsuccessfulIDs.append(
                curAss.getSpeciesName() + (i == nodes.getLength() - 1 ? "" : ", "));
        } catch (RegionConflictException e) {
          extantIDs.append(curAss.getSpeciesName() + (i == nodes.getLength() - 1 ? "" : ", "));
        }
      }

      StringBuilder ret = new StringBuilder();
      if (unsuccessfulIDs.length() > 0)
        ret.append(
            "<div>Unable to create an assessment for the following species: "
                + unsuccessfulIDs
                + "</div>\r\n");
      if (extantIDs.length() > 0)
        ret.append(
            "<div>The following species already have draft assessments with the specific locality: "
                + extantIDs
                + "</div>\r\n");
      if (successfulIDs.length() > 0)
        ret.append(
            "<div>Successfully created an assessment for the following species: "
                + successfulIDs
                + "</div>\r\n");

      return ret.toString();
    } catch (IOException e) {
      e.printStackTrace();
      return null;
    } catch (NullPointerException e) {
      e.printStackTrace();
      return null;
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    }
  }