@Override
    public Result search(Query query, Execution execution) {
        RewriterUtils.log(logger, query, "Executing " + getRewriterName());

        // Check if rewriter is properly initialized
        if(!isOk) {
            RewriterUtils.error(logger, query, "Rewriter is not properly initialized");
            return execution.search(query);
        }

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

        // Retrieve metadata passed by previous rewriter
        HashMap<String, Object> rewriteMeta = RewriterUtils.getRewriteMeta(query);

        // This key would be updated by each rewriter to specify
        // the key to be used for dict retrieval in next
        // rewriter downstream. This controls whether the
        // next rewriter should use the rewritten query or the
        // original query for dict retrieval. e.g. rewriters
        // following misspell rewriter should use the rewritten
        // query by misspell rewriter for dict retrieval
        String prevDictKey = (String)rewriteMeta.get(RewriterConstants.DICT_KEY);

        // Whether the query has been rewritten
        Boolean prevRewritten = (Boolean)rewriteMeta.get(RewriterConstants.REWRITTEN);

        // Check if rewriter should be skipped if the query
        // has been rewritten
        if(prevRewritten && getSkipRewriterIfRewritten()) {
            RewriterUtils.log(logger, query, "Skipping rewriter since the " +
                              "query has been rewritten");
            return execution.search(query);
        }

        // Store rewriter result
        HashMap<String, Object> rewriterResult = null;
        query.getModel().getQueryTree(); // performance: parse query before cloning such that it is only done once
        Query originalQueryObj = query.clone();

        try {
            // Execute rewriter's main rewrite logic
            rewriterResult = rewrite(query, prevDictKey);

        } catch (RuntimeException e) {
            RewriterUtils.error(logger, originalQueryObj, "Error executing this rewriter, " +
                                "skipping to next rewriter: " + e.getMessage());
            return execution.search(originalQueryObj);
        }

        // Check if rewriter result is set properly
        if(rewriterResult==null) {
            RewriterUtils.error(logger, originalQueryObj, "Rewriter result are not set properly, " +
                                "skipping to next rewriter");
            return execution.search(originalQueryObj);
        }

        // Retrieve results from rewriter
        Boolean rewritten = (Boolean)rewriterResult.get(RewriterConstants.REWRITTEN);
        String dictKey = (String)rewriterResult.get(RewriterConstants.DICT_KEY);

        if(rewritten==null || dictKey==null) {
            RewriterUtils.error(logger, originalQueryObj, "Rewriter result are not set properly, " +
                                "skipping to next rewriter");
            return execution.search(originalQueryObj);
        }

        // Retrieve results from rewriter
        rewriteMeta.put(RewriterConstants.REWRITTEN, (rewritten || prevRewritten));
        rewriteMeta.put(RewriterConstants.DICT_KEY, dictKey);

        // Pass metadata to the next rewriter
        RewriterUtils.setRewriteMeta(query, rewriteMeta);

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

        return execution.search(query);
    }
Perform main rewrite logics for this searcher<br>
- Skip to next rewriter if query is previously
  rewritten and getSkipRewriterIfRewritten() is
  true for this rewriter<br>
- Execute rewriter's main rewrite logic<br>
- Pass to the next rewriter the query to be used
  for dictionary retrieval<br>
container-search/src/main/java/com/yahoo/search/query/rewrite/QueryRewriteSearcher.java