private void updateCommits(List<IndexCommit> commits) {
    // to be safe, we should only call delete on a commit point passed to us
    // in this specific call (may be across diff IndexWriter instances).
    // this will happen rarely, so just synchronize everything
    // for safety and to avoid race conditions

    synchronized (this) {
      long maxCommitAgeTimeStamp = -1L;
      IndexCommit newest = commits.get(commits.size() - 1);
      log.info("newest commit = " + newest.getVersion());

      int singleSegKept = (newest.getSegmentCount() == 1) ? 1 : 0;
      int totalKept = 1;

      // work our way from newest to oldest, skipping the first since we always want to keep it.
      for (int i = commits.size() - 2; i >= 0; i--) {
        IndexCommit commit = commits.get(i);

        // delete anything too old, regardless of other policies
        try {
          if (maxCommitAge != null) {
            if (maxCommitAgeTimeStamp == -1) {
              DateMathParser dmp = new DateMathParser(DateField.UTC, Locale.US);
              maxCommitAgeTimeStamp = dmp.parseMath(maxCommitAge).getTime();
            }
            if (commit.getTimestamp() < maxCommitAgeTimeStamp) {
              commit.delete();
              continue;
            }
          }
        } catch (Exception e) {
          log.warn("Exception while checking commit point's age for deletion", e);
        }

        if (singleSegKept < maxOptimizedCommitsToKeep && commit.getSegmentCount() == 1) {
          totalKept++;
          singleSegKept++;
          continue;
        }

        if (totalKept < maxCommitsToKeep) {
          totalKept++;
          continue;
        }

        commit.delete();
      }
    } // end synchronized
  }
  /**
   * Parses a String which may be a date followed by an optional math expression.
   *
   * @param now an optional fixed date to use as "NOW" in the DateMathParser
   * @param val the string to parse
   */
  public Date parseMathLenient(Date now, String val, SolrQueryRequest req) {
    String math = null;
    final DateMathParser p = new DateMathParser();

    if (null != now) p.setNow(now);

    if (val.startsWith(NOW)) {
      math = val.substring(NOW.length());
    } else {
      final int zz = val.indexOf(Z);
      if (0 < zz) {
        math = val.substring(zz + 1);
        try {
          // p.setNow(toObject(val.substring(0,zz)));
          p.setNow(parseDateLenient(val.substring(0, zz + 1), req));
        } catch (ParseException e) {
          throw new SolrException(
              SolrException.ErrorCode.BAD_REQUEST,
              "Invalid Date in Date Math String:'" + val + '\'',
              e);
        }
      } else {
        throw new SolrException(
            SolrException.ErrorCode.BAD_REQUEST, "Invalid Date String:'" + val + '\'');
      }
    }

    if (null == math || math.equals("")) {
      return p.getNow();
    }

    try {
      return p.parseMath(math);
    } catch (ParseException e) {
      throw new SolrException(
          SolrException.ErrorCode.BAD_REQUEST, "Invalid Date Math String:'" + val + '\'', e);
    }
  }
 @Override
 public Date parseAndAddGap(Date value, String gap) throws java.text.ParseException {
   final DateMathParser dmp = new DateMathParser();
   dmp.setNow(value);
   return dmp.parseMath(gap);
 }