@Override
  public BooleanQuery getFullQuery(SearchContext searchContext) throws SearchException {

    try {
      BooleanQuery contextQuery = new BooleanQueryImpl();

      addContext(contextQuery, searchContext);

      BooleanQuery searchQuery = new BooleanQueryImpl();

      addSearchKeywords(searchQuery, searchContext);

      BooleanQuery fullQuery = new BooleanQueryImpl();

      if (contextQuery.hasClauses()) {
        fullQuery.add(contextQuery, BooleanClauseOccur.MUST);
      }

      if (searchQuery.hasClauses()) {
        fullQuery.add(searchQuery, BooleanClauseOccur.MUST);
      }

      BooleanClause<Query>[] booleanClauses = searchContext.getBooleanClauses();

      if (booleanClauses != null) {
        for (BooleanClause<Query> booleanClause : booleanClauses) {
          fullQuery.add(booleanClause.getClause(), booleanClause.getBooleanClauseOccur());
        }
      }

      fullQuery.setQueryConfig(searchContext.getQueryConfig());

      return fullQuery;
    } catch (Exception e) {
      throw new SearchException(e);
    }
  }
  protected boolean contains(Query query1, Query query2) {
    if (query1 instanceof BooleanQuery) {
      BooleanQuery booleanQuery = (BooleanQuery) query1;

      for (BooleanClause<Query> booleanClause : booleanQuery.clauses()) {
        if (contains(booleanClause.getClause(), query2)) {
          return true;
        }
      }

      return false;
    } else if (query2 instanceof BooleanQuery) {
      BooleanQuery booleanQuery = (BooleanQuery) query2;

      for (BooleanClause<Query> booleanClause : booleanQuery.clauses()) {
        if (contains(query1, booleanClause.getClause())) {
          return true;
        }
      }

      return false;
    } else if ((query1 instanceof TermQuery) && (query2 instanceof TermQuery)) {

      TermQuery termQuery1 = (TermQuery) query1;

      QueryTerm queryTerm1 = termQuery1.getQueryTerm();

      String field1 = queryTerm1.getField();
      String value1 = queryTerm1.getValue();

      TermQuery termQuery2 = (TermQuery) query2;

      QueryTerm queryTerm2 = termQuery2.getQueryTerm();

      String field2 = queryTerm2.getField();
      String value2 = queryTerm2.getValue();

      if (field1.equals(field2) && value1.equals(value2)) {
        return true;
      }
    } else if ((query1 instanceof TermRangeQuery) && (query2 instanceof TermRangeQuery)) {

      TermRangeQuery termRangeQuery1 = (TermRangeQuery) query1;

      boolean includesLower1 = termRangeQuery1.includesLower();
      boolean includesUpper1 = termRangeQuery1.includesUpper();
      String lowerTerm1 = termRangeQuery1.getLowerTerm();
      String upperTerm1 = termRangeQuery1.getUpperTerm();

      TermRangeQuery termRangeQuery2 = (TermRangeQuery) query2;

      boolean includesLower2 = termRangeQuery2.includesLower();
      boolean includesUpper2 = termRangeQuery2.includesUpper();
      String lowerTerm2 = termRangeQuery2.getLowerTerm();
      String upperTerm2 = termRangeQuery2.getUpperTerm();

      if ((includesLower1 == includesLower2)
          && (includesUpper1 == includesUpper2)
          && lowerTerm1.equals(lowerTerm2)
          && upperTerm1.equals(upperTerm2)) {

        return true;
      }
    } else if ((query1 instanceof WildcardQuery) && (query2 instanceof WildcardQuery)) {

      WildcardQuery wildcardQuery1 = (WildcardQuery) query1;

      QueryTerm queryTerm1 = wildcardQuery1.getQueryTerm();

      String field1 = queryTerm1.getField();
      String value1 = queryTerm1.getValue();

      WildcardQuery wildcardQuery2 = (WildcardQuery) query2;

      QueryTerm queryTerm2 = wildcardQuery2.getQueryTerm();

      String field2 = queryTerm2.getField();
      String value2 = queryTerm2.getValue();

      if (field1.equals(field2) && value1.equals(value2)) {
        return true;
      }
    }

    return false;
  }