public HashMap<String, Object> rewrite(Query query,
                                           String dictKey) throws RuntimeException {

        Boolean rewritten = false;

        // Pass the original dict key to the next rewriter
        HashMap<String, Object> result = new HashMap<>();
        result.put(RewriterConstants.REWRITTEN, rewritten);
        result.put(RewriterConstants.DICT_KEY, dictKey);

        RewriterUtils.log(logger, query,
                         "In GenericExpansionRewriter, query used for dict retrieval=[" + dictKey + "]");

        // Retrieve flags for choosing between whole query match
        // or partial query match
        String partialPhraseMatch = getQPConfig(query, RewriterConstants.PARTIAL_PHRASE_MATCH);

        if(partialPhraseMatch==null) {
            RewriterUtils.error(logger, query, "Required param " + RewriterConstants.PARTIAL_PHRASE_MATCH +
                                               " is not set, skipping rewriter");
            throw new RuntimeException("Required param " + RewriterConstants.PARTIAL_PHRASE_MATCH +
                                       " is not set, skipping rewriter");
        }

        // Retrieve max number of rewrites allowed
        int maxNumRewrites = 0;
        String maxNumRewritesStr = getQPConfig(query, RewriterConstants.MAX_REWRITES);
        if(maxNumRewritesStr!=null) {
            maxNumRewrites = Integer.parseInt(maxNumRewritesStr);
            RewriterUtils.log(logger, query,
                              "Limiting max number of rewrites to: " + maxNumRewrites);
        } else {
            RewriterUtils.log(logger, query, "No limit on number of rewrites");
        }

        // Retrieve flags for choosing whether to add
        // the rewrites as phrase, default to false
        String rewritesAsUnitEquiv = getQPConfig(query, RewriterConstants.REWRITES_AS_UNIT_EQUIV);
        if(rewritesAsUnitEquiv==null) {
            rewritesAsUnitEquiv = "false";
        }

        Set<PhraseMatcher.Phrase> matches;

        // Partial Phrase Matching
        if(partialPhraseMatch.equalsIgnoreCase("true")) {
            RewriterUtils.log(logger, query, "Partial phrase matching");

            // Retrieve longest non overlapping matches
            matches = RewriterFeatures.getNonOverlappingPartialPhraseMatches(phraseMatcher, query);

        // Full Phrase Matching if set to anything else
        } else {
            RewriterUtils.log(logger, query, "Full phrase matching");

            // Retrieve longest non overlapping matches
            matches = RewriterFeatures.getNonOverlappingFullPhraseMatches(phraseMatcher, query);
        }

        if(matches==null) {
            return result;
        }

        // Add expansions to the query
        query = RewriterFeatures.addExpansions(query, matches, null, maxNumRewrites, false,
                                               rewritesAsUnitEquiv.equalsIgnoreCase("true"));

        rewritten = true;

        RewriterUtils.log(logger, query, "GenericExpansionRewriter final query: " + query.toDetailString());

        result.put(RewriterConstants.REWRITTEN, rewritten);

        return result;
    }
Main logic of rewriter<br>
- Retrieve rewrites from FSA dict<br>
- rewrite query using features that are enabled by user
container-search/src/main/java/com/yahoo/search/query/rewrite/rewriters/GenericExpansionRewriter.java