@Override
  public Query rewrite(IndexReader reader) throws IOException {
    final Term[] terms = phraseQuery.getTerms();
    final int[] positions = phraseQuery.getPositions();

    boolean isOptimizable = phraseQuery.getSlop() == 0
        && n >= 2 // non-overlap n-gram cannot be optimized
        && terms.length >= 3; // short ones can't be optimized

    if (isOptimizable) {
      for (int i = 1; i < positions.length; ++i) {
        if (positions[i] != positions[i-1] + 1) {
          isOptimizable = false;
          break;
        }
      }
    }
    
    if (isOptimizable == false) {
      return phraseQuery.rewrite(reader);
    }

    PhraseQuery.Builder builder = new PhraseQuery.Builder();
    for (int i = 0; i < terms.length; ++i) {
      if (i % n == 0 || i == terms.length - 1) {
        builder.add(terms[i], i);
      }
    }
    return builder.build();
  }