private function composeMiniQuery($query, array $keywords, $required)
    {
        // Extract the mandatory keywords and consider the rest as optional keywords
        $mandatoryKeywords = array_splice($keywords, 0, $required);

        $combinations      = [];
        $combinationsCount = count($keywords);

        // Compute all the possible combinations of keywords to match the query for
        while ($combinationsCount > 0) {
            $combinations = array_merge($combinations, $this->getPossibleCombinations($keywords, $combinationsCount));
            $combinationsCount--;
        }

        // Try and match the best case query pattern
        foreach ($combinations as $combination) {
            $combination = array_merge($mandatoryKeywords, $combination);

            $regexp = implode('(.*) ', $combination) . ' (.*)';
            $regexp = '/^' . $regexp . '/is';

            if (preg_match($regexp, $query, $matches)) {
                return $this->shrinkParameters($matches, $combination);
            }
        }

        // Try and match the simplest query form that contains only the mandatory keywords
        $regexp = implode(' (.*)', $mandatoryKeywords) . ' (.*)';
        $regexp = '/^' . $regexp . '/is';

        if (preg_match($regexp, $query, $matches)) {
            return $this->shrinkParameters($matches, $mandatoryKeywords);
        }

        // Fallback in case we didn't managed to find any good match (can we actually have that happen?!)
        return substr($query, 0, $this->maxCharWidth);
    }