public static List<PhraseMatcher.Phrase> getNonOverlappingMatchesInAndItem(
                                             List<PhraseMatcher.Phrase> allMatches,
                                             Query query)
                                             throws RuntimeException {
        RewriterUtils.log(logger, query, "Retrieving longest non-overlapping matches in subtree");

        if (allMatches==null || allMatches.isEmpty())
            return null;

        if(allMatches.size()==1) {
            RewriterUtils.log(logger, query, "Only one match in subtree");
            return allMatches;
        }

        // Phrase are sorted based on length, if both have the
        // same length, the lefter one ranks higher
        RewriterUtils.log(logger, query, "Sorting the phrases");
        PhraseLength phraseLength = new PhraseLength();
        Collections.sort(allMatches, phraseLength);

        // Create a bitset with length equal to the number of
        // items in the subtree
        int numWords = allMatches.get(0).getOwner().getItemCount();
        BitSet matchPos = new BitSet(numWords);

        // Removing matches that are overlapping with previously selected ones
        RewriterUtils.log(logger, query, "Removing matches that are overlapping " +
                                         "with previously selected ones");
        ListIterator<Phrase> allMatchesIter = allMatches.listIterator();
        while(allMatchesIter.hasNext()) {
            PhraseMatcher.Phrase currMatch = allMatchesIter.next();
            PhraseMatcher.Phrase.MatchIterator matchIter = currMatch.itemIterator();
            if(matchIter.hasNext() && matchIter.next().isFilter()) {
                RewriterUtils.log(logger, query, "Removing filter item" + currMatch);
                allMatchesIter.remove();
                continue;
            }

            BitSet currMatchPos = new BitSet(numWords);
            currMatchPos.set(currMatch.getStartIndex(),
                             currMatch.getLength()+currMatch.getStartIndex());
            if(currMatchPos.intersects(matchPos)) {
                RewriterUtils.log(logger, query, "Removing " + currMatch);
                allMatchesIter.remove();
            } else {
                RewriterUtils.log(logger, query, "Keeping " + currMatch);
                matchPos.or(currMatchPos);
            }
        }
        return allMatches;
    }
<p>Retrieve the longest, from left to right non overlapping substrings in
AndItem based on FSA dictionary</p>

e.g. subtree: (modern AND new AND york AND city AND travel)<br>
     dictionary:<br>
                 mny\tmodern new york<br>
                 mo\tmodern<br>
                 modern\tn/a<br>
                 modern new york\tn/a<br>
                 new york\tn/a<br>
                 new york city\tn/a<br>
                 new york city travel\tn/a<br>
                 new york company\tn/a<br>
                 ny\tnew york<br>
                 nyc\tnew york city\tnew york company<br>
                 nyct\tnew york city travel<br>
     allMatches:<br>
                 modern<br>
                 modern new york<br>
                 new york<br>
                 new york city<br>
                 new york city travel<br>
     return: <br>
             modern<br>
             new york city travel<br>
@param allMatches All matches within the subtree
@param query Query object from the searcher
@return Matching phrases
container-search/src/main/java/com/yahoo/search/query/rewrite/RewriterFeatures.java