code: Set<String> findMatchedWords(Explanation explanation) {
      Set<String> words = new HashSet<>();
      String description = explanation.getDescription();
      if (description.startsWith(Options.SUM_OF.toString())
          || description.startsWith(Options.PRODUCT_OF.toString())) {
        if (newArrayList(explanation.getDetails()).stream().allMatch(this::reachLastLevel)) {
          words.add(extractMatchedWords(explanation.getDetails()));
        } else {
          for (Explanation subExplanation : explanation.getDetails()) {
            words.addAll(findMatchedWords(subExplanation));
          }
        }
      } else if (description.startsWith(Options.MAX_OF.toString())) {
        Explanation maxExplanation =
            newArrayList(explanation.getDetails())
                .stream()
                .max(
                    (explanation1, explanation2) ->
                        Float.compare(explanation1.getValue(), explanation2.getValue()))
                .orElseThrow(
                    () ->
                        new IllegalStateException(
                            "explanation.getDetails() shouldn't return an empty array"));
        words.addAll(findMatchedWords(maxExplanation));
      } else if (description.startsWith(Options.WEIGHT.toString())) {
        words.add(getMatchedWord(description));
      }
      return words;
    }
docs: This method is able to recursively collect all the matched words from Elasticsearch Explanation
  document
  
  @return a set of matched words that are matched to different ontology terms