@Override
    public void run() {
      try {
        StopWatch stp2 = new StopWatch();
        stp2.start();
        JSONObject json = new JSONObject();
        job.setStatus("running");
        if (job.progress() == 100.0) {

          finalizeJob(job);
          return;
        }
        Vector<String> ids = new Vector<String>();
        Vector<String> original_names = new Vector<String>();

        String data = job.getNextDataBatch();

        if (data == null || data.equals("")) return;

        String[] lines = data.split("\n");

        if (job.containsId()) {
          for (int i = 0; i < lines.length; i++) {
            if (lines[i].trim().equals("")) continue;
            ids.add(NameUtil.getNameId(lines[i]));
          }
        }

        for (int i = 0; i < lines.length; i++) {
          original_names.add(NameUtil.processName(lines[i], job.containsId()));
        }

        String names = NameUtil.CleanNames(lines, job);

        if (names.equals("")) return;

        if (job.getType() == TnrsJob.NAME_MATCH_JOB) {

          TaxamatchInterface taxa_match = new TaxamatchInterface(tnrsBaseUrl);
          String result = taxa_match.queryTaxamatch(names, job);
          json = (JSONObject) JSONSerializer.toJSON(result);

        } else if (job.getType() == TnrsJob.PARSING_JOB) {

          json = gni_interface.parseNames(names);
        }
        if (job.outstandingNames() == 0) {
          JobHelper.persistJobInfo(baseFolder, job);
        }
        saveResults(job, json, ids, original_names, "");

        job.setStatus("idle");
        stp2.stop();
        log.info("overall :" + stp2.toString());
      } catch (Exception ex) {
        log.error(ExceptionUtils.getFullStackTrace(ex));
        job.setStatus("failed");
        ex.printStackTrace();
      }
    }
  public void sendSubmissionEmail(TnrsJob job) throws Exception {

    String job_type = "";
    if (job.getType() == TnrsJob.NAME_MATCH_JOB) {
      job_type = " matching ";
    } else {
      job_type = " parsing ";
    }

    Email response = new HtmlEmail();

    response.setHostName("localhost");
    response.setSmtpPort(25);
    response.setFrom("*****@*****.**");
    response.setSubject("TNRS Job submission");
    response.setMsg(
        "Your TNRS "
            + job_type
            + " job ("
            + job.getRequest().getOriginalFilename()
            + ") was successfully submitted on "
            + dateFormat.format(new Date())
            + ". \n\n"
            + "When your list is done processing, you will receive an email notification that contains instructions regarding retrieval of your results from the TNRS website at http://tnrs.iplantcollaborative.org/.\n\n"
            + "Please contact us at [email protected] if you have any difficulty retrieving your results. \n"
            + "\n\n You can check the status of your job in the 'Retrieve results' tab of the application using your email and the following key:  "
            + job.getRequest().getId()
            + ".\n\nTo update the status for your job in progress, please select the 'Retrieve results' button again. Your progress will update at this time.\n\n"
            + "Thank you, \n"
            + "iPlant Collaborative");
    response.addTo(job.getRequest().getEmail());
    response.send();
  }
  private void saveResults(
      TnrsJob job,
      JSONObject results,
      Vector<String> ids,
      Vector<String> original_names,
      String session_id)
      throws Exception {

    if (job.getType() == TnrsJob.PARSING_JOB) {
      ParsingResultsFile csv = new ParsingResultsFile(job, baseFolder);
      csv.writeJsonData(results.getJSONArray("parsedNames"), ids);

    } else {
      MatchingResultsFile csv = new MatchingResultsFile(job, baseFolder, session_id, false);
      TNRSResultsTransformer transformer = new TNRSResultsTransformer();
      JSONArray results_array = transformer.transform(results, job, ids, original_names);
      csv.writeJsonData(results_array, ids);
      csv.close();
    }
  }
    @Override
    public void handle(HttpExchange arg0) throws IOException {
      try {

        JSONObject json =
            (JSONObject) JSONSerializer.toJSON(IOUtils.toString(arg0.getRequestBody()));

        String email = json.getString("email");
        String key = json.getString("key");
        String session_id = json.getString("session_id");

        TnrsJob job = JobHelper.readJobInfo(baseFolder, email, key);

        if (job.getType() == TnrsJob.PARSING_JOB) {

          ParsingResultsFile results = new ParsingResultsFile(job, baseFolder);
          results.createFileForDownload(properties.getProperty("org.iplantc.folder.tmp"));

        } else {

          MatchingResultsFile results = new MatchingResultsFile(job, baseFolder, session_id, false);

          results.createFileForDownload(
              properties.getProperty("org.iplantc.tnrs.folder.tmp"), json);

          results.close();
        }

        String url = servicesUrl + "getcsv?id=" + key;

        HandlerHelper.writeResponseRequest(arg0, 200, url, null);
      } catch (Exception ex) {
        log.error(ExceptionUtils.getFullStackTrace(ex));
        ex.printStackTrace();
      }
    }