@Override
  protected void startAligner(Mapper.Context context) throws IOException, InterruptedException {
    if (redistribute) {
      getIdleCores(context);
      Logger.DEBUG("Redistributing cores: using " + threads);
    }
    int threadsToUse = threads;
    if (isPaired && threadsToUse > 1) threadsToUse /= 2;
    String[] command1 =
        CommandGenerator.bwaAln(
            bin,
            ref,
            "/dev/stdin",
            getFileName(tmpdir, taskId, true, 1),
            threadsToUse,
            alnCustomArgs);
    reads1 = new ProcessBuilderWrapper(command1, bin);
    reads1.setThreads(threadsToUse);
    reads1.startProcess(null, System.err);
    // check if alive.
    if (!reads1.isAlive()) throw new ProcessException("BWA aln", reads1.getExitState());

    File file1 = new File(getFileName(tmpdir, taskId, false, 1));
    if (!file1.exists()) {
      file1.createNewFile();
    }
    fastqFile1 = new BufferedWriter(new FileWriter(file1.getAbsoluteFile()));
    if (isPaired) {
      if (threads > 1) {
        String[] command2 =
            CommandGenerator.bwaAln(
                bin,
                ref,
                "/dev/stdin",
                getFileName(tmpdir, taskId, true, 2),
                threadsToUse,
                alnCustomArgs);
        reads2 = new ProcessBuilderWrapper(command2, bin);
        reads2.setThreads(threadsToUse);
        reads2.startProcess(null, System.err);
        if (!reads2.isAlive()) throw new ProcessException("BWA aln", reads2.getExitState());
      }
      File file2 = new File(getFileName(tmpdir, taskId, false, 2));
      if (!file2.exists()) {
        file2.createNewFile();
      }
      fastqFile2 = new BufferedWriter(new FileWriter(file2.getAbsoluteFile()));
    }
  }
  private void closeBWAAln() throws InterruptedException {
    try {
      // close the input stream
      reads1.getSTDINWriter().flush();
      reads1.getSTDINWriter().close();
      fastqFile1.close();
      if (isPaired) {
        fastqFile2.close();
        if (threads > 1) {
          reads2.getSTDINWriter().flush();
          reads2.getSTDINWriter().close();
        }
      }
    } catch (IOException ex) {
      Logger.EXCEPTION(ex);
      throw new ProcessException("BWA aln", -1);
    }

    int error = reads1.waitForCompletion();
    if (error != 0) throw new ProcessException("BWA aln", error);
    context.getCounter(HalvadeCounters.TIME_BWA_ALN).increment(reads1.getExecutionTime());
    if (isPaired) {
      if (threads == 1) {
        String[] command2 =
            CommandGenerator.bwaAln(
                bin,
                ref,
                getFileName(tmpdir, taskId, false, 2),
                getFileName(tmpdir, taskId, true, 2),
                threads,
                alnCustomArgs);
        reads2 = new ProcessBuilderWrapper(command2, bin);
        reads2.setThreads(threads);
        reads2.startProcess(null, System.err);
        if (!reads2.isAlive()) throw new ProcessException("BWA aln", reads2.getExitState());
      }
      error = reads2.waitForCompletion();
      if (error != 0) throw new ProcessException("BWA aln", error);
      context.getCounter(HalvadeCounters.TIME_BWA_ALN).increment(reads2.getExecutionTime());
    }
  }
  private void startBWASamXe() throws InterruptedException {
    String customArgs = HalvadeConf.getCustomArgs(context.getConfiguration(), "bwa", "sampe");
    String[] command =
        CommandGenerator.bwaSamXe(
            bin,
            ref,
            getFileName(tmpdir, taskId, true, 1),
            getFileName(tmpdir, taskId, false, 1),
            getFileName(tmpdir, taskId, true, 2),
            getFileName(tmpdir, taskId, false, 2),
            isPaired,
            threads,
            customArgs);
    samxe = new ProcessBuilderWrapper(command, bin);
    samxe.startProcess(null, System.err);
    if (!samxe.isAlive()) throw new ProcessException("BWA samXe", samxe.getExitState());

    // make a SAMstream handler
    ssh = new SAMStreamHandler(instance, context, false);
    ssh.start();
  }