@Override
  boolean processReadPair(Read r1, Read r2) {
    assert (r2 == null);
    final byte[] quals = r1.quality, bases = r1.bases;
    final byte[] match =
        (r1.match == null ? null : !r1.shortmatch() ? r1.match : Read.toLongMatchString(r1.match));
    if (match == null || quals == null || bases == null) {
      return false;
    }

    int subs = 0;
    int indels = 0;
    for (int qpos = 0, mpos = 0, last = quals.length - 1; mpos < match.length; mpos++) {

      final byte m = match[mpos];
      final byte mprev = match[Tools.max(mpos - 1, 0)];
      final byte mnext = match[Tools.min(mpos + 1, match.length - 1)];

      final byte q1 = quals[qpos];
      final byte b2 = bases[qpos];

      int sub = 0, indel = 0;
      if (m == 'S') {
        sub = 1;
      } else if (m == 'I') {
        indel = 1;
      } else if (m == 'm') {
        if (mprev == 'D' || mnext == 'D') {
          indel = 1;
        }
      } else if (m == 'D') {
        // do nothing
      } else if (m == 'C') {
        // do nothing
      } else {
        throw new RuntimeException(
            "Bad symbol m='"
                + ((char) m)
                + "'\n"
                + new String(match)
                + "\n"
                + new String(bases)
                + "\n");
      }
      subs += sub;
      indels += indel;
      if (q1 >= minq && q1 <= maxq) {
        if (sub > 0 || (indel > 0 && countIndels)) {
          return true;
        }
      }

      if (m != 'D') {
        qpos++;
      }
    }
    return keepPerfect && subs == 0 && indels == 0;
  }
  private final void pair(ArrayList<Read> buffer1, ArrayList<Read> buffer2) {
    final int len1 = buffer1.size(), len2 = buffer2.size();
    assert (ALLOW_UNEQUAL_LENGTHS || len1 == len2)
        : "\nThere appear to be different numbers of reads in the paired input files."
            + "\nThe pairing may have been corrupted by an upstream process.  It may be fixable by running repair.sh.";
    final int lim = Tools.min(len1, len2);

    for (int i = 0; i < lim; i++) {
      Read a = buffer1.get(i);
      Read b = buffer2.get(i);

      assert (a.numericID == b.numericID)
          : "\n"
              + a.numericID
              + ", "
              + b.numericID
              + "\n"
              + a.toText(false)
              + "\n"
              + b.toText(false)
              + "\n";
      assert (a.mate == null)
          : "Please set interleaved=false when using dual input files.\n"
              + a.id
              + "\n"
              + a.mate.id
              + "\n"
              + b.id
              + "\n"
              + producer1
              + "\n"
              + producer2;
      assert (b.mate == null) : "Please set interleaved=false when using dual input files.";
      a.mate = b;
      b.mate = a;

      assert (a.pairnum() == 0);
      b.setPairnum(1);
      //		assert(a.pairnum()!=b.pairnum());
    }

    if (len1 > len2) {
      // do nothing;
    } else if (len2 > len1) {
      for (int i = lim; i < len2; i++) {
        Read b = buffer2.get(i);
        b.setPairnum(0);
        buffer1.add(b);
      }
    }
  }