private DatabaseQuery populateQueryImp(
      CharSequence jpqlQuery, DatabaseQuery query, AbstractSession session) {

    try {
      // Parse the JPQL query with the most recent JPQL grammar
      JPQLExpression jpqlExpression =
          new JPQLExpression(jpqlQuery, DefaultEclipseLinkJPQLGrammar.instance(), isTolerant());

      // Create a context that caches the information contained in the JPQL query
      // (especially from the FROM clause)
      JPQLQueryContext queryContext = new JPQLQueryContext(jpqlGrammar());
      queryContext.cache(session, query, jpqlExpression, jpqlQuery);

      // Validate the JPQL query, which will use the JPQL grammar matching the validation level
      validate(queryContext, jpqlExpression);

      // Create the DatabaseQuery by visiting the parsed tree
      DatabaseQueryVisitor visitor = new DatabaseQueryVisitor(queryContext, jpqlQuery);
      jpqlExpression.accept(visitor);

      // Add the input parameter types to the DatabaseQuery
      if (query == null) {
        query = queryContext.getDatabaseQuery();
        addArguments(queryContext, query);
      }

      return query;
    } catch (JPQLException exception) {
      throw exception;
    } catch (Exception exception) {
      throw buildUnexpectedException(jpqlQuery, exception);
    }
  }
  /** {@inheritDoc} */
  @Override
  public Expression buildSelectionCriteria(
      String entityName, String selectionCriteria, AbstractSession session) {

    try {
      // Create the parsed tree representation of the selection criteria
      JPQLExpression jpqlExpression =
          new JPQLExpression(
              selectionCriteria,
              DefaultEclipseLinkJPQLGrammar.instance(),
              ConditionalExpressionBNF.ID,
              isTolerant());

      // Caches the info and add a virtual range variable declaration
      JPQLQueryContext queryContext = new JPQLQueryContext(jpqlGrammar());
      queryContext.cache(session, null, jpqlExpression, selectionCriteria);
      queryContext.addRangeVariableDeclaration(entityName, "this");

      // Validate the JPQL query, which will use the JPQL grammar matching the validation
      // level, for now, only validate the query statement because there could be an unknown
      // ending that is an order by clause
      validate(queryContext, jpqlExpression.getQueryStatement());

      // Create the Expression representing the selection criteria
      return queryContext.buildExpression(jpqlExpression.getQueryStatement());
    } catch (JPQLException exception) {
      throw exception;
    } catch (Exception exception) {
      throw buildUnexpectedException(selectionCriteria, exception);
    }
  }