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 void visit(SelectStatement expression) {

      ObjectLevelReadQuery query = queryContext.getDatabaseQuery();

      // Create and prepare the query
      if (query == null) {
        query = buildReadAllQuery(expression);
        queryContext.setDatabasQuery(query);
        query.setJPQLString(jpqlQuery);
        ((JPQLCallQueryMechanism) query.getQueryMechanism()).getJPQLCall().setIsParsed(true);
      }

      // Now populate it
      expression.accept(buildVisitor(query));
    }
    /** {@inheritDoc} */
    @Override
    public void visit(UpdateStatement expression) {

      UpdateAllQuery query = queryContext.getDatabaseQuery();

      // Create and prepare the query
      if (query == null) {
        query = new UpdateAllQuery();
        queryContext.setDatabasQuery(query);
        query.setJPQLString(jpqlQuery);
        ((JPQLCallQueryMechanism) query.getQueryMechanism()).getJPQLCall().setIsParsed(true);
      }

      query.setSession(queryContext.getSession());
      query.setShouldDeferExecutionInUOW(false);

      // Now populate it
      UpdateQueryVisitor visitor = new UpdateQueryVisitor(queryContext, query);
      expression.accept(visitor);
    }