@Override
  public void performService(Request request, Response response) {
    try {
      String username = request.getChallengeResponse().getIdentifier();

      if (username == null || username.equals("")) {
        response.setStatus(Status.CLIENT_ERROR_FORBIDDEN);
      } else if (request.getMethod().equals(Method.GET)) {
        String id = (String) request.getAttributes().get("id");
        String ret = null;

        try {
          if (id == null) ret = getAssessments(request, username);
          else
            ret =
                AssessmentIO.readAssessmentAsString(
                    vfs, id, (String) request.getAttributes().get("type"), username);

          if (ret != null) {
            response.setEntity(ret, MediaType.TEXT_XML);
            response.setStatus(Status.SUCCESS_OK);
          } else response.setStatus(Status.CLIENT_ERROR_NOT_FOUND);
        } catch (IOException e) {
          e.printStackTrace();
          response.setStatus(Status.SERVER_ERROR_INTERNAL);
        }
      } else if (request.getMethod().equals(Method.PUT)) {
        try {
          putAssessment(request, response, username);
        } catch (Throwable e) {
          e.printStackTrace();
        }
      } else if (request.getMethod().equals(Method.POST)) {
        String action = request.getResourceRef().getQueryAsForm().getFirstValue("action");
        if (action == null) {
          postAssessment(request, response, username);
        } else if (action.equalsIgnoreCase("fetch")) {
          try {
            String ret = getAssessments(request, username);

            if (ret != null) {
              response.setEntity(ret, MediaType.TEXT_XML);
              response.setStatus(Status.SUCCESS_OK);
            } else response.setStatus(Status.CLIENT_ERROR_NOT_FOUND);
          } catch (IOException e) {
            e.printStackTrace();
            response.setStatus(Status.SERVER_ERROR_INTERNAL);
          }
        } else if (action.equalsIgnoreCase("batch")) {
          String ret = batchCreate(request, username);

          if (ret != null) {
            response.setEntity(ret, MediaType.TEXT_XML);
            response.setStatus(Status.SUCCESS_OK);
          } else {
            response.setStatus(Status.SERVER_ERROR_INTERNAL);
          }
        }
      } else if (request.getMethod().equals(Method.DELETE)) {
        if (request.getResourceRef().getPath().startsWith("assessmentsByTaxon")) {
          String taxonID = (String) request.getAttributes().get("id");
          String type = (String) request.getAttributes().get("type");
          deleteAssessmentsForTaxon(taxonID, type, username, request, response);
        } else {
          String id = (String) request.getAttributes().get("id");
          String type = (String) request.getAttributes().get("type");
          deleteAssessment(request, response, id, type, username);
        }
      } else {
        response.setStatus(Status.CLIENT_ERROR_METHOD_NOT_ALLOWED);
      }
    } catch (Exception e) {
      e.printStackTrace();
      response.setStatus(Status.SERVER_ERROR_INTERNAL);
    }
  }
  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;
    }
  }
  /**
   * Centralized way to create ResourceStoreRequests, since we have to fill in various things in
   * Request context, like authenticated username, etc.
   *
   * @param isLocal
   * @return
   */
  protected ArtifactStoreRequest getResourceStoreRequest(
      Request request,
      boolean localOnly,
      String repositoryId,
      String g,
      String a,
      String v,
      String p,
      String c,
      String e)
      throws ResourceException {
    if (StringUtils.isBlank(p) && StringUtils.isBlank(e)) {
      // if packaging and extension is both blank, it is a bad request
      throw new ResourceException(
          Status.CLIENT_ERROR_BAD_REQUEST,
          "Deployment tried with both 'packaging' and/or 'extension' being empty! One of these values is mandatory!");
    }

    MavenRepository mavenRepository = getMavenRepository(repositoryId);

    // if extension is not given, fall-back to packaging and apply mapper
    if (StringUtils.isBlank(e)) {
      e = mavenRepository.getArtifactPackagingMapper().getExtensionForPackaging(p);
    }

    // clean up the classifier
    if (StringUtils.isBlank(c)) {
      c = null;
    }

    Gav gav = null;

    try {
      gav =
          new Gav(
              g,
              a,
              v,
              c,
              e,
              null,
              null,
              null,
              VersionUtils.isSnapshot(v),
              false,
              null,
              false,
              null);
    } catch (IllegalArtifactCoordinateException ex) {
      throw new ResourceException(
          Status.CLIENT_ERROR_BAD_REQUEST, "Illegal artifact coordinate.", ex);
    }

    ArtifactStoreRequest result = new ArtifactStoreRequest(mavenRepository, gav, localOnly);

    if (getLogger().isDebugEnabled()) {
      getLogger().debug("Created ArtifactStoreRequest request for " + result.getRequestPath());
    }

    // stuff in the originating remote address
    result
        .getRequestContext()
        .put(AccessManager.REQUEST_REMOTE_ADDRESS, getValidRemoteIPAddress(request));

    // stuff in the user id if we have it in request
    if (request.getChallengeResponse() != null
        && request.getChallengeResponse().getIdentifier() != null) {
      result
          .getRequestContext()
          .put(AccessManager.REQUEST_USER, request.getChallengeResponse().getIdentifier());
    }

    // this is HTTPS, get the cert and stuff it too for later
    if (request.isConfidential()) {
      result.getRequestContext().put(AccessManager.REQUEST_CONFIDENTIAL, Boolean.TRUE);

      List<?> certs = (List<?>) request.getAttributes().get("org.restlet.https.clientCertificates");

      if (certs != null) {
        result.getRequestContext().put(AccessManager.REQUEST_CERTIFICATES, certs);
      }
    }

    // put the incoming URLs
    result.setRequestAppRootUrl(getContextRoot(request).toString());
    result.setRequestUrl(request.getOriginalRef().toString());

    return result;
  }