class ExpandingQueryTransformer implements QueryTransformer {

    public static final PromptTemplate DEFAULT_PROMPT_TEMPLATE = PromptTemplate.from(
            "Generate {{n}} different versions of a provided user query. " +
                    "Each version should be worded differently, using synonyms or alternative sentence structures, " +
                    "but they should all retain the original meaning. " +
                    "These versions will be used to retrieve relevant documents. " +
                    "It is very important to provide each query version on a separate line, " +
                    "without enumerations, hyphens, or any additional formatting!\n" +
                    "User query: {{query}}"
    );
    public static final int DEFAULT_N = 3;

    protected final ChatLanguageModel chatLanguageModel;
    protected final PromptTemplate promptTemplate;
    protected final int n;

    public ExpandingQueryTransformer(ChatLanguageModel chatLanguageModel) {
        this(chatLanguageModel, DEFAULT_PROMPT_TEMPLATE, DEFAULT_N);
    }

    public ExpandingQueryTransformer(ChatLanguageModel chatLanguageModel, int n) {
        this(chatLanguageModel, DEFAULT_PROMPT_TEMPLATE, n);
    }

    public ExpandingQueryTransformer(ChatLanguageModel chatLanguageModel, PromptTemplate promptTemplate) {
        this(chatLanguageModel, ensureNotNull(promptTemplate, "promptTemplate"), DEFAULT_N);
    }

    @Builder
    public ExpandingQueryTransformer(ChatLanguageModel chatLanguageModel, PromptTemplate promptTemplate, Integer n) {
        this.chatLanguageModel = ensureNotNull(chatLanguageModel, "chatLanguageModel");
        this.promptTemplate = getOrDefault(promptTemplate, DEFAULT_PROMPT_TEMPLATE);
        this.n = ensureGreaterThanZero(getOrDefault(n, DEFAULT_N), "n");
    }

    @Override
    public Collection<Query> transform(Query query) {
        Prompt prompt = createPrompt(query);
        String response = chatLanguageModel.generate(prompt.text());
        return parse(response);
    }

    protected Prompt createPrompt(Query query) {<FILL_FUNCTION_BODY>}

    protected List<Query> parse(String queries) {
        return stream(queries.split("\n"))
                .filter(Utils::isNotNullOrBlank)
                .map(Query::from)
                .collect(toList());
    }
}

        Map<String, Object> variables = new HashMap<>();
        variables.put("query", query.text());
        variables.put("n", n);
        return promptTemplate.apply(variables);
    
<no_super_class>