/*
 * Copyright (c) 2006, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2006, 2021 IBM Corporation. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation
//
//     04/11/2017-2.6 Will Dazey
//       - 512386: Concat expression return type Boolean -> String
//     02/20/2018-2.7 Will Dazey
//       - 531062: Incorrect expression type created for CollectionExpression
//     05/11/2018-2.7 Will Dazey
//       - 534515: Incorrect return type set for CASE functions
//     IBM - Bug 537795: CASE THEN and ELSE scalar expression Constants should not be casted to CASE operand type
package org.eclipse.persistence.internal.jpa.jpql;

import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.expressions.ExpressionBuilder;
import org.eclipse.persistence.expressions.ExpressionMath;
import org.eclipse.persistence.internal.expressions.ConstantExpression;
import org.eclipse.persistence.internal.expressions.DateConstantExpression;
import org.eclipse.persistence.internal.expressions.MapEntryExpression;
import org.eclipse.persistence.internal.expressions.ParameterExpression;
import org.eclipse.persistence.internal.queries.ReportItem;
import org.eclipse.persistence.jpa.jpql.ExpressionTools;
import org.eclipse.persistence.jpa.jpql.JPQLQueryDeclaration.Type;
import org.eclipse.persistence.jpa.jpql.LiteralType;
import org.eclipse.persistence.jpa.jpql.parser.AbsExpression;
import org.eclipse.persistence.jpa.jpql.parser.AbstractEclipseLinkExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.AbstractExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.AbstractPathExpression;
import org.eclipse.persistence.jpa.jpql.parser.AbstractSchemaName;
import org.eclipse.persistence.jpa.jpql.parser.AdditionExpression;
import org.eclipse.persistence.jpa.jpql.parser.AllOrAnyExpression;
import org.eclipse.persistence.jpa.jpql.parser.AndExpression;
import org.eclipse.persistence.jpa.jpql.parser.AnonymousExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.ArithmeticFactor;
import org.eclipse.persistence.jpa.jpql.parser.AsOfClause;
import org.eclipse.persistence.jpa.jpql.parser.AvgFunction;
import org.eclipse.persistence.jpa.jpql.parser.BadExpression;
import org.eclipse.persistence.jpa.jpql.parser.BetweenExpression;
import org.eclipse.persistence.jpa.jpql.parser.CaseExpression;
import org.eclipse.persistence.jpa.jpql.parser.CastExpression;
import org.eclipse.persistence.jpa.jpql.parser.CoalesceExpression;
import org.eclipse.persistence.jpa.jpql.parser.CollectionExpression;
import org.eclipse.persistence.jpa.jpql.parser.CollectionMemberDeclaration;
import org.eclipse.persistence.jpa.jpql.parser.CollectionMemberExpression;
import org.eclipse.persistence.jpa.jpql.parser.CollectionValuedPathExpression;
import org.eclipse.persistence.jpa.jpql.parser.ComparisonExpression;
import org.eclipse.persistence.jpa.jpql.parser.ConcatExpression;
import org.eclipse.persistence.jpa.jpql.parser.ConnectByClause;
import org.eclipse.persistence.jpa.jpql.parser.ConstructorExpression;
import org.eclipse.persistence.jpa.jpql.parser.CountFunction;
import org.eclipse.persistence.jpa.jpql.parser.DatabaseType;
import org.eclipse.persistence.jpa.jpql.parser.DateTime;
import org.eclipse.persistence.jpa.jpql.parser.DeleteClause;
import org.eclipse.persistence.jpa.jpql.parser.DeleteStatement;
import org.eclipse.persistence.jpa.jpql.parser.DivisionExpression;
import org.eclipse.persistence.jpa.jpql.parser.EclipseLinkAnonymousExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.EclipseLinkExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.EmptyCollectionComparisonExpression;
import org.eclipse.persistence.jpa.jpql.parser.EntityTypeLiteral;
import org.eclipse.persistence.jpa.jpql.parser.EntryExpression;
import org.eclipse.persistence.jpa.jpql.parser.ExistsExpression;
import org.eclipse.persistence.jpa.jpql.parser.ExtractExpression;
import org.eclipse.persistence.jpa.jpql.parser.FromClause;
import org.eclipse.persistence.jpa.jpql.parser.FunctionExpression;
import org.eclipse.persistence.jpa.jpql.parser.GroupByClause;
import org.eclipse.persistence.jpa.jpql.parser.HavingClause;
import org.eclipse.persistence.jpa.jpql.parser.HierarchicalQueryClause;
import org.eclipse.persistence.jpa.jpql.parser.IdentificationVariable;
import org.eclipse.persistence.jpa.jpql.parser.IdentificationVariableDeclaration;
import org.eclipse.persistence.jpa.jpql.parser.InExpression;
import org.eclipse.persistence.jpa.jpql.parser.IndexExpression;
import org.eclipse.persistence.jpa.jpql.parser.InputParameter;
import org.eclipse.persistence.jpa.jpql.parser.JPQLExpression;
import org.eclipse.persistence.jpa.jpql.parser.Join;
import org.eclipse.persistence.jpa.jpql.parser.KeyExpression;
import org.eclipse.persistence.jpa.jpql.parser.KeywordExpression;
import org.eclipse.persistence.jpa.jpql.parser.LengthExpression;
import org.eclipse.persistence.jpa.jpql.parser.LikeExpression;
import org.eclipse.persistence.jpa.jpql.parser.LocateExpression;
import org.eclipse.persistence.jpa.jpql.parser.LowerExpression;
import org.eclipse.persistence.jpa.jpql.parser.MaxFunction;
import org.eclipse.persistence.jpa.jpql.parser.MinFunction;
import org.eclipse.persistence.jpa.jpql.parser.ModExpression;
import org.eclipse.persistence.jpa.jpql.parser.MultiplicationExpression;
import org.eclipse.persistence.jpa.jpql.parser.NotExpression;
import org.eclipse.persistence.jpa.jpql.parser.NullComparisonExpression;
import org.eclipse.persistence.jpa.jpql.parser.NullExpression;
import org.eclipse.persistence.jpa.jpql.parser.NullIfExpression;
import org.eclipse.persistence.jpa.jpql.parser.NumericLiteral;
import org.eclipse.persistence.jpa.jpql.parser.ObjectExpression;
import org.eclipse.persistence.jpa.jpql.parser.OnClause;
import org.eclipse.persistence.jpa.jpql.parser.OrExpression;
import org.eclipse.persistence.jpa.jpql.parser.OrderByClause;
import org.eclipse.persistence.jpa.jpql.parser.OrderByItem;
import org.eclipse.persistence.jpa.jpql.parser.OrderSiblingsByClause;
import org.eclipse.persistence.jpa.jpql.parser.RangeVariableDeclaration;
import org.eclipse.persistence.jpa.jpql.parser.RegexpExpression;
import org.eclipse.persistence.jpa.jpql.parser.ResultVariable;
import org.eclipse.persistence.jpa.jpql.parser.SelectClause;
import org.eclipse.persistence.jpa.jpql.parser.SelectStatement;
import org.eclipse.persistence.jpa.jpql.parser.SimpleFromClause;
import org.eclipse.persistence.jpa.jpql.parser.SimpleSelectClause;
import org.eclipse.persistence.jpa.jpql.parser.SimpleSelectStatement;
import org.eclipse.persistence.jpa.jpql.parser.SizeExpression;
import org.eclipse.persistence.jpa.jpql.parser.SqrtExpression;
import org.eclipse.persistence.jpa.jpql.parser.StartWithClause;
import org.eclipse.persistence.jpa.jpql.parser.StateFieldPathExpression;
import org.eclipse.persistence.jpa.jpql.parser.StringLiteral;
import org.eclipse.persistence.jpa.jpql.parser.SubExpression;
import org.eclipse.persistence.jpa.jpql.parser.SubstringExpression;
import org.eclipse.persistence.jpa.jpql.parser.SubtractionExpression;
import org.eclipse.persistence.jpa.jpql.parser.SumFunction;
import org.eclipse.persistence.jpa.jpql.parser.TableExpression;
import org.eclipse.persistence.jpa.jpql.parser.TableVariableDeclaration;
import org.eclipse.persistence.jpa.jpql.parser.TreatExpression;
import org.eclipse.persistence.jpa.jpql.parser.TrimExpression;
import org.eclipse.persistence.jpa.jpql.parser.TypeExpression;
import org.eclipse.persistence.jpa.jpql.parser.UnionClause;
import org.eclipse.persistence.jpa.jpql.parser.UnknownExpression;
import org.eclipse.persistence.jpa.jpql.parser.UpdateClause;
import org.eclipse.persistence.jpa.jpql.parser.UpdateItem;
import org.eclipse.persistence.jpa.jpql.parser.UpdateStatement;
import org.eclipse.persistence.jpa.jpql.parser.UpperExpression;
import org.eclipse.persistence.jpa.jpql.parser.ValueExpression;
import org.eclipse.persistence.jpa.jpql.parser.WhenClause;
import org.eclipse.persistence.jpa.jpql.parser.WhereClause;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.querykeys.ForeignReferenceQueryKey;
import org.eclipse.persistence.mappings.querykeys.QueryKey;
import org.eclipse.persistence.queries.ReportQuery;

/**
 * This {@link ExpressionVisitor} visits an {@link org.eclipse.persistence.jpa.jpql.parser.Expression
 * JPQL Expression} and creates the corresponding {@link org.eclipse.persistence.expressions.
 * Expression EclipseLink Expression}.
 *
 * @version 2.6
 * @since 2.3
 * @author Pascal Filion
 * @author John Bracken
 */
@SuppressWarnings("nls")
final class ExpressionBuilderVisitor implements EclipseLinkExpressionVisitor {

    /**
     * This visitor creates a list by retrieving either the single child or the children of the
     * {@link CollectionExpression}, which would be the child.
     */
    private ChildrenExpressionVisitor childrenExpressionVisitor;

    /**
     * Determines whether the target relationship is allowed to be <code>null</code>.
     */
    private boolean nullAllowed;

    /**
     * This {@link Comparator} compares two {@link Class} values and returned the appropriate numeric
     * type that takes precedence.
     */
    private Comparator<Class<?>> numericTypeComparator;

    /**
     * The context used to query information about the application metadata.
     */
    private final JPQLQueryContext queryContext;

    /**
     * The EclipseLink {@link Expression} that represents a visited parsed {@link org.eclipse
     * persistence.jpa.query.parser.Expression Expression}
     */
    private Expression queryExpression;

    /**
     * Keeps track of the type of an expression while traversing it.
     */
    private final Class<?>[] type;

    /**
     * The visitor responsible to create the {@link Expression Expressions} for the <b>WHEN</b> and
     * <b>THEN</b> expressions.
     */
    private WhenClauseExpressionVisitor whenClauseExpressionVisitor;

    /**
     * Creates a new <code>ExpressionBuilderVisitor</code>.
     *
     * @param queryContext The context used to query information about the application metadata and
     * cached information
     */
    ExpressionBuilderVisitor(JPQLQueryContext queryContext) {
        super();
        this.type = new Class<?>[1];
        this.queryContext = queryContext;
    }

    private void appendJoinVariables(org.eclipse.persistence.jpa.jpql.parser.Expression expression,
                                     ReportQuery subquery) {

        queryExpression = null;

        for (String variableName : collectOuterIdentificationVariables()) {
            Expression innerExpression = queryContext.getQueryExpression(variableName);
            Expression outerExpression = queryContext.getParent().getQueryExpressionImp(variableName);
            Expression equalExpression = innerExpression.equal(outerExpression);

            if (queryExpression == null) {
                queryExpression = equalExpression;
            }
            else {
                queryExpression = queryExpression.and(equalExpression);
            }
        }

        // Aggregate the WHERE clause with the joins expression
        if (queryExpression != null) {
            Expression whereClause = subquery.getSelectionCriteria();

            if (whereClause != null) {
                whereClause = whereClause.and(queryExpression);
            }
            else {
                whereClause = queryExpression;
            }

            subquery.setSelectionCriteria(whereClause);
        }
    }

    /**
     * Creates a new EclipseLink {@link Expression} by visiting the given JPQL {@link org.eclipse.
     * persistence.jpa.jpql.parser.Expression Expression}.
     *
     * @param expression The {@link org.eclipse.persistence.jpa.jpql.parser.Expression Expression} to
     * convert into an EclipseLink {@link Expression}
     * @param type The type of the expression
     * @return The EclipseLink {@link Expression} of the JPQL fragment
     */
    Expression buildExpression(org.eclipse.persistence.jpa.jpql.parser.Expression expression,
                               Class<?>[] type) {

        Class<?> oldType = this.type[0];
        Expression oldQueryExpression = queryExpression;

        try {
            this.type[0]         = null;
            this.queryExpression = null;

            expression.accept(this);

            type[0] = this.type[0];
            return queryExpression;
        }
        finally {
            this.type[0]         = oldType;
            this.queryExpression = oldQueryExpression;
        }
    }

    /**
     * Creates a new EclipseLink {@link Expression} by visiting the given JPQL {@link
     * CollectionValuedPathExpression} that is used in the <code><b>GROUP BY</b></code> clause.
     *
     * @param expression The {@link CollectionValuedPathExpression} to convert into an EclipseLink
     * {@link Expression}
     * @return The EclipseLink {@link Expression} representation of that path expression
     */
    Expression buildGroupByExpression(CollectionValuedPathExpression expression) {


        try {
            PathResolver resolver     = new PathResolver();
            resolver.length           = expression.pathSize() - 1;
            resolver.nullAllowed      = false;
            resolver.checkMappingType = false;

            expression.accept(resolver);

            return resolver.localExpression;
        }
        finally {
            this.type[0]         = null;
            this.queryExpression = null;
        }
    }

    /**
     * Creates a new EclipseLink {@link Expression} by visiting the given JPQL {@link
     * StateFieldPathExpression}. This method temporarily changes the null allowed flag if the state
     * field is a foreign reference mapping
     *
     * @param expression The {@link StateFieldPathExpression} to convert into an EclipseLink {@link
     * Expression}
     * @return The EclipseLink {@link Expression} representation of that path expression
     */
    Expression buildModifiedPathExpression(StateFieldPathExpression expression) {


        try {
            PathResolver resolver     = new PathResolver();
            resolver.length           = expression.pathSize();
            resolver.checkMappingType = true;

            expression.accept(resolver);

            return resolver.localExpression;
        }
        finally {
            this.type[0]         = null;
            this.queryExpression = null;
        }
    }

    /**
     * Creates a new {@link ReportQuery} by visiting the given {@link SimpleSelectStatement}.
     *
     * @param expression The {@link SimpleSelectStatement} to convert into a {@link ReportQuery}
     * @return A fully initialized {@link ReportQuery}
     */
    ReportQuery buildSubquery(SimpleSelectStatement expression) {

        // First create the subquery
        ReportQuery subquery = new ReportQuery();
        queryContext.newSubQueryContext(expression, subquery);

        try {
            // Visit the subquery to populate it
            ReportQueryVisitor visitor = new ReportQueryVisitor(queryContext, subquery);
            expression.accept(visitor);
            type[0] = visitor.type;

            // Add the joins between the subquery and the parent query
            appendJoinVariables(expression, subquery);

            return subquery;
        }
        finally {
            queryContext.disposeSubqueryContext();
        }
    }

    private List<org.eclipse.persistence.jpa.jpql.parser.Expression> children(org.eclipse.persistence.jpa.jpql.parser.Expression expression) {
        ChildrenExpressionVisitor visitor = childrenExpressionVisitor();
        try {
            expression.accept(visitor);
            return new LinkedList<>(visitor.expressions);
        }
        finally {
            visitor.expressions.clear();
        }
    }

    private ChildrenExpressionVisitor childrenExpressionVisitor() {
        if (childrenExpressionVisitor == null) {
            childrenExpressionVisitor = new ChildrenExpressionVisitor();
        }
        return childrenExpressionVisitor;
    }

    private Set<String> collectOuterIdentificationVariables() {

        // Retrieve the identification variables used in the current query
        Set<String> variableNames = new HashSet<>(queryContext.getUsedIdentificationVariables());

        // Now remove the local identification variables that are defined in JOIN expressions and
        // in collection member declarations
        for (Declaration declaration : queryContext.getDeclarations()) {
            variableNames.remove(declaration.getVariableName());
        }

        return variableNames;
    }

    @Override
    public void visit(AbsExpression expression) {

        // First create the expression from the encapsulated expression
        expression.getExpression().accept(this);

        // Now create the ABS expression
        queryExpression = ExpressionMath.abs(queryExpression);

        // Note: The type will be calculated when traversing the ABS's expression
    }

    @Override
    public void visit(AbstractSchemaName expression) {
        ClassDescriptor descriptor = queryContext.getDescriptor(expression.getText());
        type[0] = descriptor.getJavaClass();
        queryExpression = new ExpressionBuilder(type[0]);
    }

    @Override
    public void visit(AdditionExpression expression) {

        List<Class<?>> types = new ArrayList<>(2);

        // Create the left side of the addition expression
        expression.getLeftExpression().accept(this);
        Expression leftExpression = queryExpression;
        types.add(type[0]);

        // Create the right side of the addition expression
        expression.getRightExpression().accept(this);
        Expression rightExpression = queryExpression;
        types.add(type[0]);

        // Now create the addition expression
        queryExpression = ExpressionMath.add(leftExpression, rightExpression);

        // Set the expression type
        Collections.sort(types, NumericTypeComparator.instance());
        type[0] = types.get(0);
    }

    @Override
    public void visit(AllOrAnyExpression expression) {

        // First create the subquery
        ReportQuery subquery = buildSubquery((SimpleSelectStatement) expression.getExpression());

        // Now create the ALL|SOME|ANY expression
        String identifier = expression.getIdentifier();
        queryExpression = queryContext.getBaseExpression();

        if (identifier == AllOrAnyExpression.ALL) {
            queryExpression = queryExpression.all(subquery);
        }
        else if (identifier == AllOrAnyExpression.SOME) {
            queryExpression = queryExpression.some(subquery);
        }
        else if (identifier == AllOrAnyExpression.ANY) {
            queryExpression = queryExpression.any(subquery);
        }

        // Note: The type will be calculated when traversing the ABS's expression
    }

    @Override
    public void visit(AndExpression expression) {

        // Create the left side of the logical expression
        expression.getLeftExpression().accept(this);
        Expression leftExpression = queryExpression;

        // Create the right side of the logical expression
        expression.getRightExpression().accept(this);
        Expression rightExpression = queryExpression;

        // Now create the AND expression
        queryExpression = leftExpression.and(rightExpression);

        // Set the expression type
        type[0] = Boolean.class;
    }

    @Override
    public void visit(ArithmeticFactor expression) {

        // First create the Expression that is prepended with the unary sign
        expression.getExpression().accept(this);
        Expression arithmeticFactor = queryExpression;

        // Create an expression for the constant 0 (zero)
        queryExpression = new ConstantExpression(0, new ExpressionBuilder());

        // "- <something>" is really "0 - <something>"
        queryExpression = ExpressionMath.subtract(queryExpression, arithmeticFactor);

        // Note: The type will be calculated when traversing the sub-expression
    }

    @Override
    public void visit(AsOfClause expression) {
        expression.getExpression().accept(this);
    }

    @Override
    public void visit(AvgFunction expression) {

        // First create the expression from the encapsulated expression
        expression.getExpression().accept(this);

        // Mark the AVG expression distinct
        if (expression.hasDistinct()) {
            queryExpression = queryExpression.distinct();
        }

        // Now create the AVG expression
        queryExpression = queryExpression.average();

        // Set the expression type
        type[0] = Double.class;
    }

    @Override
    public void visit(BadExpression expression) {
        // Nothing to do
    }

    @Override
    public void visit(BetweenExpression expression) {

        // First create the Expression for the result expression
        expression.getExpression().accept(this);
        Expression resultExpression = queryExpression;

        // Create the expression for the lower bound expression
        expression.getLowerBoundExpression().accept(this);
        Expression lowerBoundExpression = queryExpression;

        // Create the expression for the upper bound expression
        expression.getUpperBoundExpression().accept(this);
        Expression upperBoundExpression = queryExpression;

        // Create the BETWEEN expression
        if (expression.hasNot()) {
            queryExpression = resultExpression.notBetween(lowerBoundExpression, upperBoundExpression);
        }
        else {
            queryExpression = resultExpression.between(lowerBoundExpression, upperBoundExpression);
        }

        // Set the expression type
        type[0] = Boolean.class;
    }

    @Override
    public void visit(CaseExpression expression) {

        Expression caseBaseExpression = queryExpression;

        Expression caseOperandExpression = null;
        // Create the case operand expression
        if (expression.hasCaseOperand()) {
            expression.getCaseOperand().accept(this);
            caseOperandExpression = queryExpression;
        }

        WhenClauseExpressionVisitor visitor = whenClauseExpressionVisitor();

        try {
            // Create the WHEN clauses
            expression.getWhenClauses().accept(visitor);

            // Create the ELSE clause
            expression.getElseExpression().accept(this);
            Expression elseExpression = queryExpression;
            visitor.types.add(type[0]);

            // Create the CASE expression
            if (caseOperandExpression != null) {
                queryExpression = caseOperandExpression.caseStatement(visitor.whenClauses, elseExpression);

                //Bug 537795
                //After we build the caseStatement, we need to retroactively fix the THEN/ELSE children's base
                if(queryExpression.isFunctionExpression()) {
                    Vector<Expression> children = ((org.eclipse.persistence.internal.expressions.FunctionExpression)queryExpression).getChildren();
                    int index = 1;
                    while(index <  children.size()) {
                        Expression when_else = children.get(index);
                        if(index+1 < children.size()) {
                            //Not at end, must be a THEN
                            children.get(index+1).setLocalBase(caseBaseExpression);
                        } else {
                            //At end, must be an ELSE
                            when_else.setLocalBase(caseBaseExpression);
                        }
                        index=index+2;
                    }
                }
            }
            else {
                queryExpression = queryContext.getBaseExpression();
                queryExpression = queryExpression.caseStatement(visitor.whenClauses, elseExpression);
            }

            // Set the expression type
            type[0] = queryContext.typeResolver().compareCollectionEquivalentTypes(visitor.types);
        }
        finally {
            visitor.dispose();
        }
    }

    @Override
    public void visit(CastExpression expression) {

        // First create the expression from the encapsulated expression
        expression.getExpression().accept(this);

        // Now create the CAST expression
        org.eclipse.persistence.jpa.jpql.parser.Expression databaseType = expression.getDatabaseType();
        queryExpression = queryExpression.cast(databaseType.toParsedText());

        // Set the expression type
        type[0] = Object.class;
    }

    @Override
    public void visit(CoalesceExpression expression) {

        List<Expression> expressions = new ArrayList<>();
        List<Class<?>> types = new LinkedList<>();

        //cache the type of the expression so untyped children have a default type
        Class<?> coalesceType = type[0];

        // Create the Expression for each scalar expression
        for (org.eclipse.persistence.jpa.jpql.parser.Expression child : expression.getExpression().children()) {
            child.accept(this);
            expressions.add(queryExpression);

            //get the expression type parsed from the child expression
            Class<?> childType = type[0];

            // Default the type on an untyped ParameterExpression to the cached expression type.
            // This is to help provide a valid type for null parameter when binding JDBC parameter types
            if (queryExpression.isParameterExpression()) {
                ParameterExpression paramExpression = (ParameterExpression) queryExpression;
                if (paramExpression.getType() == null || paramExpression.getType().equals(Object.class)) {
                    paramExpression.setType(coalesceType);
                    childType = coalesceType;
                }
            }

            types.add(childType);
        }

        // Create the COALESCE expression
        queryExpression = queryContext.getBaseExpression();
        queryExpression = queryExpression.coalesce(expressions);

        // Set the expression type
        type[0] = queryContext.typeResolver().compareCollectionEquivalentTypes(types);
    }

    @Override
    public void visit(CollectionExpression expression) {
        // Nothing to do, this should be handled by the owning expression
    }

    @Override
    public void visit(CollectionMemberDeclaration expression) {
        expression.getCollectionValuedPathExpression().accept(this);
    }

    @Override
    public void visit(CollectionMemberExpression expression) {

        // Create the expression for the entity expression
        expression.getEntityExpression().accept(this);
        Expression entityExpression = queryExpression;

        if (expression.hasNot()) {

            CollectionValuedPathExpression pathExpression = (CollectionValuedPathExpression) expression.getCollectionValuedPathExpression();

            // Retrieve the ExpressionBuilder from the collection-valued path expression's
            // identification variable and the variable name
            pathExpression.getIdentificationVariable().accept(this);
            Expression parentExpression = queryExpression;

            // Now create the actual expression
            Expression newBuilder = new ExpressionBuilder();
            Expression collectionBase = newBuilder;
            for (int i = 1; i < pathExpression.pathSize() - 1; i++) {
                // nested paths must be single valued.
                collectionBase = collectionBase.get(pathExpression.getPath(i));
            }
            String lastPath = pathExpression.getPath(pathExpression.pathSize() - 1);
            // The following code is copied from Expression.noneOf and altered a bit
            Expression criteria = newBuilder.equal(parentExpression).and(collectionBase.anyOf(lastPath).equal(entityExpression));
            ReportQuery subQuery = new ReportQuery();
            subQuery.setShouldRetrieveFirstPrimaryKey(true);
            subQuery.setSelectionCriteria(criteria);
            // subQuery has the same reference class as parentExpression (which is an ExpressionBuilder).
            subQuery.setReferenceClass(((ExpressionBuilder)parentExpression).getQueryClass());
            queryExpression = parentExpression.notExists(subQuery);
        }
        else {
            // Create the expression for the collection-valued path expression
            expression.getCollectionValuedPathExpression().accept(this);

            // Create the MEMBER OF expression
            queryExpression = queryExpression.equal(entityExpression);
        }
    }

    @Override
    public void visit(CollectionValuedPathExpression expression) {
        visitPathExpression(expression, nullAllowed, expression.pathSize());
    }

    @Override
    public void visit(ComparisonExpression expression) {

        ComparisonExpressionVisitor visitor = new ComparisonExpressionVisitor();

        // Create the left side of the comparison expression
        expression.getLeftExpression().accept(visitor);
        Expression leftExpression = queryExpression;

        // Create the right side of the comparison expression
        expression.getRightExpression().accept(visitor);
        Expression rightExpression = queryExpression;

        // Now create the comparison expression
        String comparaison = expression.getComparisonOperator();

        // =
        if (comparaison == ComparisonExpression.EQUAL) {
            queryExpression = leftExpression.equal(rightExpression);
        }
        // <>, !=
        else if (comparaison == ComparisonExpression.DIFFERENT ||
                 comparaison == ComparisonExpression.NOT_EQUAL) {

            queryExpression = leftExpression.notEqual(rightExpression);
        }
        // <
        else if (comparaison == ComparisonExpression.LOWER_THAN) {
            queryExpression = leftExpression.lessThan(rightExpression);
        }
        // <=
        else if (comparaison == ComparisonExpression.LOWER_THAN_OR_EQUAL) {
            queryExpression = leftExpression.lessThanEqual(rightExpression);
        }
        // >
        else if (comparaison == ComparisonExpression.GREATER_THAN) {
            queryExpression = leftExpression.greaterThan(rightExpression);
        }
        // <=
        else if (comparaison == ComparisonExpression.GREATER_THAN_OR_EQUAL) {
            queryExpression = leftExpression.greaterThanEqual(rightExpression);
        }
        else {
            throw new IllegalArgumentException("The comparison operator is unknown: " + comparaison);
        }

        // Set the expression type
        type[0] = Boolean.class;
    }

    @Override
    public void visit(ConcatExpression expression) {

        List<org.eclipse.persistence.jpa.jpql.parser.Expression> expressions = children(expression.getExpression());
        Expression newExpression = null;

        for (org.eclipse.persistence.jpa.jpql.parser.Expression child : expressions) {
            child.accept(this);
            if (newExpression == null) {
                newExpression = queryExpression;
            }
            else {
                newExpression = newExpression.concat(queryExpression);
            }
        }

        queryExpression = newExpression;

        // Set the expression type
       type[0] = String.class;
    }

    @Override
    public void visit(ConnectByClause expression) {
        expression.getExpression().accept(this);
    }

    @Override
    public void visit(ConstructorExpression expression) {
        // Nothing to do
    }

    @Override
    public void visit(CountFunction expression) {

        // Create the expression from the encapsulated expression
        expression.getExpression().accept(this);

        // Mark the expression has distinct
        if (expression.hasDistinct()) {
            queryExpression = queryExpression.distinct();
        }

        // Create the COUNT expression
        queryExpression = queryExpression.count();

        // Set the expression type
        type[0] = Long.class;
    }

    @Override
    public void visit(DatabaseType expression) {
        // Nothing to do
    }

    @Override
    public void visit(DateTime expression) {

        if (expression.isJDBCDate()) {
            queryExpression = queryContext.getBaseExpression();
            queryExpression = new DateConstantExpression(expression.getText(), queryExpression);
            String text = expression.getText();

            if (text.startsWith("{d")) {
                type[0] = Date.class;
            }
            else if (text.startsWith("{ts")) {
                type[0] = Timestamp.class;
            }
            else if (text.startsWith("{t")) {
                type[0] = Time.class;
            }
            else {
                type[0] = Object.class;
            }
        }
        else {
            queryExpression = queryContext.getBaseExpression();

            if (expression.isCurrentDate()) {
                queryExpression = queryExpression.currentDateDate();
                type[0] = Date.class;
            }
            else if (expression.isCurrentTime()) {
                queryExpression = queryExpression.currentTime();
                type[0] = Time.class;
            }
            else if (expression.isCurrentTimestamp()) {
                queryExpression = queryExpression.currentTimeStamp();
                type[0] = Timestamp.class;
            }
            else {
                throw new IllegalArgumentException("The DateTime is unknown: " + expression);
            }
        }
    }

    @Override
    public void visit(DeleteClause expression) {
        // Nothing to do
    }

    @Override
    public void visit(DeleteStatement expression) {
        // Nothing to do
    }

    @Override
    public void visit(DivisionExpression expression) {

        List<Class<?>> types = new ArrayList<>(2);

        // Create the left side of the division expression
        expression.getLeftExpression().accept(this);
        Expression leftExpression = queryExpression;
        types.add(type[0]);

        // Create the right side of the division expression
        expression.getRightExpression().accept(this);
        Expression rightExpression = queryExpression;
        types.add(type[0]);

        // Now create the division expression
        queryExpression = ExpressionMath.divide(leftExpression, rightExpression);

        // Set the expression type
        Collections.sort(types, NumericTypeComparator.instance());
        type[0] = types.get(0);
    }

    @Override
    public void visit(EmptyCollectionComparisonExpression expression) {

        CollectionValuedPathExpression collectionPath = (CollectionValuedPathExpression) expression.getExpression();
        int lastPathIndex = collectionPath.pathSize() - 1;
        String name = collectionPath.getPath(lastPathIndex);

        // Create the expression for the collection-valued path expression (except the last path)
        visitPathExpression(collectionPath, false, lastPathIndex);

        // Create the IS EMPTY expression
        if (expression.hasNot()) {
            queryExpression = queryExpression.notEmpty(name);
        }
        else {
            queryExpression = queryExpression.isEmpty(name);
        }

        // Set the expression type
        type[0] = Boolean.class;
    }

    @Override
    public void visit(EntityTypeLiteral expression) {
        ClassDescriptor descriptor = queryContext.getDescriptor(expression.getEntityTypeName());
        type[0] = descriptor.getJavaClass();
        queryExpression = new ConstantExpression(type[0], queryContext.getBaseExpression());
    }

    @Override
    public void visit(EntryExpression expression) {

        // Create the expression for the collection-valued path expression
        expression.getExpression().accept(this);

        // Now create the ENTRY expression
        MapEntryExpression entryExpression = new MapEntryExpression(queryExpression);
        entryExpression.returnMapEntry();
        queryExpression = entryExpression;

        // Set the expression type
        type[0] = Map.Entry.class;
    }

    @Override
    public void visit(ExistsExpression expression) {

        // First create the subquery
        ReportQuery subquery = buildSubquery((SimpleSelectStatement) expression.getExpression());

        // Replace the SELECT clause of the exists subquery by SELECT 1 to avoid problems with
        // databases not supporting multiple columns in the subquery SELECT clause in SQL. The
        // original select clause expressions might include relationship navigations which should
        // result in FK joins in the generated SQL, e.g. ... EXISTS (SELECT o.customer FROM Order
        // o ...). Add the select clause expressions as non fetch join attributes to the ReportQuery
        // representing the subquery. This make sure the FK joins get generated
        for (ReportItem item : subquery.getItems()) {
            Expression expr = item.getAttributeExpression();
            subquery.addNonFetchJoinedAttribute(expr);
        }

        subquery.clearItems();

        Expression one = new ConstantExpression(1, new ExpressionBuilder());
        subquery.addItem("one", one);
        subquery.dontUseDistinct();

        // Now create the EXISTS expression
        queryExpression = queryContext.getBaseExpression();

        if (expression.hasNot()) {
            queryExpression = queryExpression.notExists(subquery);
        }
        else {
            queryExpression = queryExpression.exists(subquery);
        }

        // Set the expression type
        type[0] = Boolean.class;
    }

    @Override
    public void visit(ExtractExpression expression) {

        // First create the expression from the encapsulated expression
        expression.getExpression().accept(this);

        // Now create the EXTRACT expression
        queryExpression = queryExpression.extract(expression.getDatePart());

        // Set the expression type
        type[0] = Object.class;
    }

    @Override
    public void visit(FromClause expression) {
        // Nothing to do
    }

    @Override
    public void visit(FunctionExpression expression) {

        String identifier   = expression.getIdentifier();
        String functionName = expression.getUnquotedFunctionName();

        // COLUMN
        if (identifier == org.eclipse.persistence.jpa.jpql.parser.Expression.COLUMN) {

            // Create the expression for the single child
            expression.getExpression().accept(this);

            // Create the expression representing a field in a data-level query
            queryExpression = queryExpression.getField(functionName);
        }
        else {

            List<org.eclipse.persistence.jpa.jpql.parser.Expression> expressions = children(expression.getExpression());

            // No arguments
            if (expressions.isEmpty()) {
                queryExpression = queryContext.getBaseExpression();

                // OPERATOR
                if (identifier == org.eclipse.persistence.jpa.jpql.parser.Expression.SQL) {
                    queryExpression = queryExpression.literal(functionName);
                }
                // FUNC/FUNCTION
                else {
                    queryExpression = queryExpression.getFunction(functionName);
                }
            }
            // One or more arguments
            else {

                // Create the Expressions for the rest
                List<Expression> queryExpressions = new ArrayList<>(expressions.size());

                for (org.eclipse.persistence.jpa.jpql.parser.Expression child : expressions) {
                    child.accept(this);
                    queryExpressions.add(queryExpression);
                }

                queryExpression = queryExpressions.remove(0);

                // SQL
                if (identifier == org.eclipse.persistence.jpa.jpql.parser.Expression.SQL) {
                    queryExpression = queryExpression.sql(functionName, queryExpressions);
                }
                // OPERATOR
                else if (identifier == org.eclipse.persistence.jpa.jpql.parser.Expression.OPERATOR) {
                    queryExpression = queryExpression.operator(functionName, queryExpressions);
                }
                // FUNC/FUNCTION
                else {
                    queryExpression = queryExpression.getFunctionWithArguments(functionName, queryExpressions);
                }
            }
        }

        // Set the expression type
        type[0] = Object.class;
    }

    @Override
    public void visit(GroupByClause expression) {
        // Nothing to do
    }

    @Override
    public void visit(HavingClause expression) {
        expression.getConditionalExpression().accept(this);
    }

    @Override
    public void visit(HierarchicalQueryClause expression) {
        // Nothing to do
    }

    @Override
    public void visit(IdentificationVariable expression) {

        // The identification variable is virtual, only do something
        // if it falsely represents a state field path expression
        if (expression.isVirtual()) {
            StateFieldPathExpression stateFieldPathExpression = expression.getStateFieldPathExpression();

            if (stateFieldPathExpression != null) {
                stateFieldPathExpression.accept(this);
                return;
            }
        }

        String variableName = expression.getVariableName();

        // Identification variable, it's important to use findQueryExpression() and not
        // getQueryExpression(). If the identification variable is defined by the parent
        // query, then the ExpressionBuilder have most likely been created already
        queryExpression = queryContext.findQueryExpression(variableName);

        // Retrieve the Declaration mapped to the variable name
        Declaration declaration = queryContext.findDeclaration(variableName);

        // A null Declaration would most likely mean it's coming from a
        // state field path expression that represents an enum constant
        if (declaration != null) {

            // The Expression was not created yet, which can happen if the identification
            // variable is declared in a parent query. If that is the case, create the
            // ExpressionBuilder and cache it for the current query
            if (queryExpression == null) {
                declaration.getBaseExpression().accept(this);
                queryContext.addQueryExpression(variableName, queryExpression);
            }

            // Retrieve the Entity type
            if (declaration.getType() == Type.RANGE) {
                type[0] = declaration.getDescriptor().getJavaClass();
            }
        }
    }

    @Override
    public void visit(IdentificationVariableDeclaration expression) {
        // Nothing to do
    }

    @Override
    public void visit(IndexExpression expression) {

        // Create the expression for the encapsulated expression
        expression.getExpression().accept(this);

        // Now create the INDEX expression
        queryExpression = queryExpression.index();

        // Set the expression type
        type[0] = Integer.class;
    }

    @Override
    public void visit(InExpression expression) {

        // Visit the left expression
        InExpressionExpressionBuilder visitor1 = new InExpressionExpressionBuilder();
        expression.getExpression().accept(visitor1);

        // Visit the IN items
        InExpressionBuilder visitor2 = new InExpressionBuilder();
        visitor2.hasNot               = expression.hasNot();
        visitor2.singleInputParameter = expression.isSingleInputParameter();
        visitor2.leftExpression       = queryExpression;
        expression.getInItems().accept(visitor2);

        // Set the expression type
        type[0] = Boolean.class;
    }

    @Override
    public void visit(InputParameter expression) {

        String parameterName = expression.getParameter();

        // Calculate the input parameter type
        type[0] = queryContext.getParameterType(expression);

        // Create the expression
        queryExpression = queryContext.getBaseExpression();
        queryExpression = queryExpression.getParameter(parameterName.substring(1), type[0]);

        // Cache the input parameter type
        queryContext.addInputParameter(expression, queryExpression);
    }

    @Override
    public void visit(Join expression) {
        try {
            nullAllowed = expression.isLeftJoin();
            expression.getJoinAssociationPath().accept(this);
        }
        finally {
            nullAllowed = false;
        }
    }

    @Override
    public void visit(JPQLExpression expression) {
        // Nothing to do
    }

    @Override
    public void visit(KeyExpression expression) {

        // First visit the parent Expression
        expression.getExpression().accept(this);

        // Now create the Expression of the KEY expression
        queryExpression = new MapEntryExpression(queryExpression);
    }

    @Override
    public void visit(KeywordExpression expression) {

        String keyword = expression.getText();
        Object value;

        if (keyword == KeywordExpression.NULL) {
            value   = null;
            type[0] = Object.class;
        }
        else if (keyword == KeywordExpression.TRUE) {
            value   = Boolean.TRUE;
            type[0] = Boolean.class;
        }
        else {
            value   = Boolean.FALSE;
            type[0] = Boolean.class;
        }

        queryExpression = queryContext.getBaseExpression();
        queryExpression = new ConstantExpression(value, queryExpression);
    }

    @Override
    public void visit(LengthExpression expression) {

        // Create the expression from the encapsulated expression
        expression.getExpression().accept(this);

        // Now create the LENGTH expression
        queryExpression = queryExpression.length();

        // Set the expression type
        type[0] = Integer.class;
    }

    @Override
    public void visit(LikeExpression expression) {

        // Create the first expression
        expression.getStringExpression().accept(this);
        Expression firstExpression = queryExpression;

        // Create the expression for the pattern value
        expression.getPatternValue().accept(this);
        Expression patternValue = queryExpression;

        // Create the LIKE expression with the escape character
        if (expression.hasEscapeCharacter()) {
            expression.getEscapeCharacter().accept(this);
            queryExpression = firstExpression.like(patternValue, queryExpression);
        }
        // Create the LIKE expression with no escape character
        else {
            queryExpression = firstExpression.like(patternValue);
        }

        // Negate the expression
        if (expression.hasNot()) {
            queryExpression = queryExpression.not();
        }

        // Set the expression type
        type[0] = Boolean.class;
    }

    @Override
    public void visit(LocateExpression expression) {

        // Create the string to find in the find in expression
        expression.getFirstExpression().accept(this);
        Expression findExpression = queryExpression;

        // Create the find in string expression
        expression.getSecondExpression().accept(this);
        Expression findInExpression = queryExpression;

        // Create the expression for the start position
        expression.getThirdExpression().accept(this);
        Expression startPositionExpression = queryExpression;

        // Create the LOCATE expression
        if (startPositionExpression != null) {
            queryExpression = findInExpression.locate(findExpression, startPositionExpression);
        }
        else {
            queryExpression = findInExpression.locate(findExpression);
        }

        // Set the expression type
        type[0] = Integer.class;
    }

    @Override
    public void visit(LowerExpression expression) {

        // Create the expression from the encapsulated expression
        expression.getExpression().accept(this);

        // Now create the LOWER expression
        queryExpression = queryExpression.toLowerCase();

        // Set the expression type
        type[0] = String.class;
    }

    @Override
    public void visit(MaxFunction expression) {

        // Create the expression from the encapsulated expression
        expression.getExpression().accept(this);

        // Mark the MAX expression has distinct
        if (expression.hasDistinct()) {
            queryExpression = queryExpression.distinct();
        }

        // Now create the MAX expression
        queryExpression = queryExpression.maximum();

        // Note: The type will be calculated when traversing the sub-expression
    }

    @Override
    public void visit(MinFunction expression) {

        // Create the expression from the encapsulated expression
        expression.getExpression().accept(this);

        // Mark the MIN expression has distinct
        if (expression.hasDistinct()) {
            queryExpression = queryExpression.distinct();
        }

        // Now create the MIN expression
        queryExpression = queryExpression.minimum();

        // Note: The type will be calculated when traversing the sub-expression
    }

    @Override
    public void visit(ModExpression expression) {

        // First create the Expression for the first expression
        expression.getFirstExpression().accept(this);
        Expression leftExpression = queryExpression;

        // Now create the Expression for the second expression
        expression.getSecondExpression().accept(this);
        Expression rightExpression = queryExpression;

        // Now create the MOD expression
        queryExpression = ExpressionMath.mod(leftExpression, rightExpression);

        // Set the expression type
        type[0] = Integer.class;
    }

    @Override
    public void visit(MultiplicationExpression expression) {

        List<Class<?>> types = new ArrayList<>(2);

        // Create the left side of the multiplication expression
        expression.getLeftExpression().accept(this);
        Expression leftExpression = queryExpression;
        types.add(type[0]);

        // Create the right side of the multiplication expression
        expression.getRightExpression().accept(this);
        Expression rightExpression = queryExpression;
        types.add(type[0]);

        // Now create the multiplication expression
        queryExpression = ExpressionMath.multiply(leftExpression, rightExpression);

        // Set the expression type
        Collections.sort(types, NumericTypeComparator.instance());
        type[0] = types.get(0);
    }

    @Override
    public void visit(NotExpression expression) {

        // Create the expression
        expression.getExpression().accept(this);

        // Negate the expression
        queryExpression = queryExpression.not();

        // Set the expression type
        type[0] = Boolean.class;
    }

    @Override
    public void visit(NullComparisonExpression expression) {

        // Create the expression first
        expression.getExpression().accept(this);

        // Mark it as NOT NULL
        if (expression.hasNot()) {
            queryExpression = queryExpression.notNull();
        }
        // Mark it as IS NULL
        else {
            queryExpression = queryExpression.isNull();
        }

        // Set the expression type
        type[0] = Boolean.class;
    }

    @Override
    public void visit(NullExpression expression) {
        queryExpression = null;
        type[0] = null;
    }

    @Override
    public void visit(NullIfExpression expression) {

        // Create the first expression
        expression.getFirstExpression().accept(this);
        Expression firstExpression = queryExpression;
        Class<?> actualType = type[0];

        // Create the second expression
        expression.getSecondExpression().accept(this);
        Expression secondExpression = queryExpression;

        // Now create the NULLIF expression
        queryExpression = firstExpression.nullIf(secondExpression);

        // Set the expression type
        type[0] = actualType;
    }

    @Override
    public void visit(NumericLiteral expression) {

        // Instantiate a Number object with the value
        type[0] = queryContext.getType(expression);

        // Special case for a long number, Long.parseLong() does not handle 'l|L'
        // but Double.parseDouble() and Float.parseFloat() do handle 'd|D' and 'f|F', respectively
        String text = expression.getText();

        if ((type[0] == Long.class) && (text.endsWith("L") || text.endsWith("l"))) {
            text = text.substring(0, text.length() - 1);
        }

        Number number = queryContext.newInstance(type[0], String.class, text);

        // Now create the numeric expression
        queryExpression = new ConstantExpression(number, queryContext.getBaseExpression());
    }

    @Override
    public void visit(ObjectExpression expression) {
        // Simply traverse the OBJECT's expression
        expression.getExpression().accept(this);
    }

    @Override
    public void visit(OnClause expression) {
        expression.getConditionalExpression().accept(this);
    }

    @Override
    public void visit(OrderByClause expression) {
        // Nothing to do
    }

    @Override
    public void visit(OrderByItem expression) {

        // Create the item
        expression.getExpression().accept(this);

        // Create the ordering item
        switch (expression.getOrdering()) {
            case ASC:  queryExpression = queryExpression.ascending();  break;
            case DESC: queryExpression = queryExpression.descending(); break;
        }

        // Create the null ordering item
        switch (expression.getNullOrdering()) {
            case NULLS_FIRST: queryExpression = queryExpression.nullsFirst(); break;
            case NULLS_LAST:  queryExpression = queryExpression.nullsLast();  break;
        }
    }

    @Override
    public void visit(OrderSiblingsByClause expression) {
        expression.getOrderByItems().accept(this);
    }

    @Override
    public void visit(OrExpression expression) {

        // Create the left side of the logical expression
        expression.getLeftExpression().accept(this);
        Expression leftExpression = queryExpression;

        // Create the right side of the logical expression
        expression.getRightExpression().accept(this);
        Expression rightExpression = queryExpression;

        // Now create the OR expression
        queryExpression = leftExpression.or(rightExpression);

        // Set the expression type
        type[0] = Boolean.class;
    }

    @Override
    public void visit(RangeVariableDeclaration expression) {

        IdentificationVariable variable = (IdentificationVariable) expression.getIdentificationVariable();
        Declaration declaration = queryContext.getDeclaration(variable.getVariableName());

        switch (declaration.getType()) {

            // If the Declaration is RangeDeclaration, then retrieve its Descriptor directly,
            // this will support two cases automatically, the "root" object is
            // 1) An abstract schema name (entity name) -> parsed as AbstractSchemaName
            // 2) A fully qualified class name -> parsed as a CollectionValuedPathExpression
            //    that cannot be visited
            case RANGE:
            case CLASS_NAME: {
                type[0] = declaration.getDescriptor().getJavaClass();
                queryExpression = new ExpressionBuilder(type[0]);
                break;
            }

            // The FROM subquery needs to be created differently than a regular subquery
            case SUBQUERY: {
                type[0] = null;
                queryExpression = declaration.getQueryExpression();
                break;
            }

            // This should be a derived path (CollectionValuedPathExpression) or a subquery
            default: {
                expression.getRootObject().accept(this);
                break;
            }
        }
    }

    @Override
    public void visit(RegexpExpression expression) {

        // Create the first expression
        expression.getStringExpression().accept(this);
        Expression firstExpression = queryExpression;

        // Create the expression for the pattern value
        expression.getPatternValue().accept(this);
        Expression patternValue = queryExpression;

        // Create the REGEXP expression
        queryExpression = firstExpression.regexp(patternValue);

        // Set the expression type
        type[0] = Boolean.class;
    }

    @Override
    public void visit(ResultVariable expression) {

        expression.getSelectExpression().accept(this);
        IdentificationVariable identificationVariable = (IdentificationVariable) expression.getResultVariable();
        String variableName = identificationVariable.getVariableName();
        queryContext.addQueryExpression(variableName, queryExpression);

        // Note: The type will be calculated when traversing the select expression
    }

    @Override
    public void visit(SelectClause expression) {
        // Nothing to do
    }

    @Override
    public void visit(SelectStatement expression) {
        // Nothing to do
    }

    @Override
    public void visit(SimpleFromClause expression) {
        // Nothing to do
    }

    @Override
    public void visit(SimpleSelectClause expression) {
        // Nothing to do
    }

    @Override
    public void visit(SimpleSelectStatement expression) {

        // First create the subquery
        ReportQuery subquery = buildSubquery(expression);

        // Now wrap the subquery
        queryExpression = queryContext.getBaseExpression();
        queryExpression = queryExpression.subQuery(subquery);
    }

    @Override
    public void visit(SizeExpression expression) {

        CollectionValuedPathExpression pathExpression = (CollectionValuedPathExpression) expression.getExpression();
        int lastIndex = pathExpression.pathSize() - 1;

        // Create the right chain of expressions
        visitPathExpression(pathExpression, false, lastIndex - 1);

        // Now create the SIZE expression
        String name = pathExpression.getPath(lastIndex);
        queryExpression = queryExpression.size(name);

        // Set the expression type
        type[0] = Integer.class;
    }

    @Override
    public void visit(SqrtExpression expression) {

        // First create the expression from the encapsulated expression
        expression.getExpression().accept(this);

        // Now create the SQRT expression
        queryExpression = ExpressionMath.sqrt(queryExpression);

        // Set the expression type
        type[0] = Double.class;
    }

    @Override
    public void visit(StartWithClause expression) {
        expression.getConditionalExpression().accept(this);
    }

    @Override
    public void visit(StateFieldPathExpression expression) {
        visitPathExpression(expression, false, expression.pathSize());
    }

    @Override
    public void visit(StringLiteral expression) {

        // Create the expression
        queryExpression = queryContext.getBaseExpression();
        queryExpression = new ConstantExpression(expression.getUnquotedText(), queryExpression);

        // Set the expression type
        type[0] = String.class;
    }

    @Override
    public void visit(SubExpression expression) {
        expression.getExpression().accept(this);
    }

    @Override
    public void visit(SubstringExpression expression) {

        // Create the first expression
        expression.getFirstExpression().accept(this);
        Expression firstExpression = queryExpression;

        // Create the second expression
        expression.getSecondExpression().accept(this);
        Expression secondExpression = queryExpression;

        // Create the third expression
        expression.getThirdExpression().accept(this);
        Expression thirdExpression = queryExpression;

        // Now create the SUBSTRING expression
        if (thirdExpression != null) {
            queryExpression = firstExpression.substring(secondExpression, thirdExpression);
        }
        else {
            queryExpression = firstExpression.substring(secondExpression);
        }

        // Set the expression type
        type[0] = String.class;
    }

    @Override
    public void visit(SubtractionExpression expression) {

        List<Class<?>> types = new ArrayList<>(2);

        // Create the left side of the subtraction expression
        expression.getLeftExpression().accept(this);
        Expression leftExpression = queryExpression;
        types.add(type[0]);

        // Create the right side of the subtraction expression
        expression.getRightExpression().accept(this);
        Expression rightExpression = queryExpression;
        types.add(type[0]);

        // Now create the subtraction expression
        queryExpression = ExpressionMath.subtract(leftExpression, rightExpression);

        // Set the expression type
        Collections.sort(types, NumericTypeComparator.instance());
        type[0] = types.get(0);
    }

    @Override
    public void visit(SumFunction expression) {

        // First create the expression from the encapsulated expression
        expression.getExpression().accept(this);

        // Mark the SUM expression distinct
        if (expression.hasDistinct()) {
            queryExpression = queryExpression.distinct();
        }

        // Now create the SUM expression
        queryExpression = queryExpression.sum();

        // Set the expression type
        type[0] = queryContext.typeResolver().convertSumFunctionType(type[0]);
    }

    @Override
    public void visit(TableExpression expression) {
        String tableName = queryContext.literal(expression.getExpression(), LiteralType.STRING_LITERAL);
        tableName = ExpressionTools.unquote(tableName);
        queryExpression = queryContext.getBaseExpression().getTable(tableName);
    }

    @Override
    public void visit(TableVariableDeclaration expression) {
        // Nothing to do
    }

    @Override
    public void visit(TreatExpression expression) {

        // First visit the parent Expression
        expression.getCollectionValuedPathExpression().accept(this);

        // Now downcast the Expression
        EntityTypeLiteral entityTypeLiteral = (EntityTypeLiteral) expression.getEntityType();
        ClassDescriptor entityType = queryContext.getDescriptor(entityTypeLiteral.getEntityTypeName());
        queryExpression = queryExpression.treat(entityType.getJavaClass());
    }

    @Override
    public void visit(TrimExpression expression) {

        // Create the TRIM character expression
        expression.getTrimCharacter().accept(this);
        Expression trimCharacter = queryExpression;

        // Create the string to trim
        expression.getExpression().accept(this);
        Expression stringExpression = queryExpression;

        switch (expression.getSpecification()) {
            case LEADING: {
                if (trimCharacter != null) {
                    queryExpression = stringExpression.leftTrim(trimCharacter);
                }
                else {
                    queryExpression = stringExpression.leftTrim();
                }
                break;
            }
            case TRAILING: {
                if (trimCharacter != null) {
                    queryExpression = stringExpression.rightTrim(trimCharacter);
                }
                else {
                    queryExpression = stringExpression.rightTrim();
                }
                break;
            }
            default: {
                if (trimCharacter != null) {
                    queryExpression = stringExpression.trim(trimCharacter);
                }
                else {
                    queryExpression = stringExpression.trim();
                }
                break;
            }
        }

        // Set the expression type
        type[0] = String.class;
    }

    @Override
    public void visit(TypeExpression expression) {

        // First create the Expression for the identification variable
        expression.getExpression().accept(this);

        // Create the TYPE expression
        queryExpression = queryExpression.type();

        // Note: The type will be calculated when traversing the select expression
    }

    @Override
    public void visit(UnionClause expression) {
        // Nothing to do
    }

    @Override
    public void visit(UnknownExpression expression) {
        queryExpression = null;
    }

    @Override
    public void visit(UpdateClause expression) {
        // Nothing to do
    }

    @Override
    public void visit(UpdateItem expression) {
        // Nothing to do
    }

    @Override
    public void visit(UpdateStatement expression) {
        // Nothing to do
    }

    @Override
    public void visit(UpperExpression expression) {

        // First create the expression from the encapsulated expression
        expression.getExpression().accept(this);

        // Now create the UPPER expression
        queryExpression = queryExpression.toUpperCase();

        // Set the expression type
        type[0] = String.class;
    }

    @Override
    public void visit(ValueExpression expression) {
        expression.getExpression().accept(this);
    }

    @Override
    public void visit(WhenClause expression) {
        // Nothing to do
    }

    @Override
    public void visit(WhereClause expression) {
        expression.getConditionalExpression().accept(this);
    }

    private void visitPathExpression(AbstractPathExpression expression,
                                     boolean nullAllowed,
                                     int lastIndex) {


        PathResolver resolver = new PathResolver();

        resolver.length           = lastIndex;
        resolver.nullAllowed      = nullAllowed;
        resolver.checkMappingType = false;
        resolver.localExpression  = null;
        resolver.descriptor       = null;

        expression.accept(resolver);

        queryExpression = resolver.localExpression;
    }

    private WhenClauseExpressionVisitor whenClauseExpressionVisitor() {
        if (whenClauseExpressionVisitor == null) {
            whenClauseExpressionVisitor = new WhenClauseExpressionVisitor();
        }
        return whenClauseExpressionVisitor;
    }

    // Made static for performance reasons.
    /**
     * This visitor creates a list by retrieving either the single child or the children of the
     * {@link CollectionExpression}, which would be the child.
     */
    private static class ChildrenExpressionVisitor extends AnonymousExpressionVisitor {

        /**
         * The list of {@link org.eclipse.persistence.jpa.jpql.parser.Expression Expression} that are
         * the children of an expression.
         */
        List<org.eclipse.persistence.jpa.jpql.parser.Expression> expressions;

        /**
         * Creates a new <code>ChildrenExpressionVisitor</code>.
         */
        ChildrenExpressionVisitor() {
            super();
            expressions = new ArrayList<>();
        }

        @Override
        public void visit(CollectionExpression expression) {
            for (org.eclipse.persistence.jpa.jpql.parser.Expression child : expression.children()) {
                expressions.add(child);
            }
        }

        @Override
        public void visit(NullExpression expression) {
            // Can't be added to the list
        }

        @Override
        protected void visit(org.eclipse.persistence.jpa.jpql.parser.Expression expression) {
            expressions.add(expression);
        }
    }

    /**
     * This visitor makes sure to properly handle an entity type literal being parsed as an
     * identification variable.
     */
    private class ComparisonExpressionVisitor extends EclipseLinkAnonymousExpressionVisitor {

        @Override
        public void visit(IdentificationVariable expression) {

            boolean found = false;

            if (!expression.isVirtual()) {

                ClassDescriptor descriptor = queryContext.getDescriptor(expression.getText());

                // Entity type name
                if (descriptor != null) {
                    type[0] = descriptor.getJavaClass();
                    queryExpression = new ConstantExpression(type[0], queryContext.getBaseExpression());
                    found = true;
                }
            }

            if (!found) {
                expression.accept(ExpressionBuilderVisitor.this);
            }
        }

        @Override
        protected void visit(org.eclipse.persistence.jpa.jpql.parser.Expression expression) {
            expression.accept(ExpressionBuilderVisitor.this);
        }
    }

    /**
     * This visitor takes care of creating the left expression of an <code><b>IN</b></code> expression
     * and make sure to support nested arrays.
     */
    private class InExpressionExpressionBuilder extends EclipseLinkAnonymousExpressionVisitor {

        @Override
        public void visit(CollectionExpression expression) {

            // Assume this is a nested array
            List<Expression> children = new LinkedList<>();

            for (org.eclipse.persistence.jpa.jpql.parser.Expression child : expression.children()) {
                child.accept(this);
                children.add(queryExpression);
            }

            queryExpression = new org.eclipse.persistence.internal.expressions.CollectionExpression(children, queryContext.getBaseExpression());
        }

        @Override
        public void visit(org.eclipse.persistence.jpa.jpql.parser.Expression expression) {
            expression.accept(ExpressionBuilderVisitor.this);
        }

        @Override
        public void visit(SubExpression expression) {
            expression.getExpression().accept(this);
        }
    }

    /**
     * This visitor takes care of creating the <code><b>IN</b></code> expression by visiting the items.
     */
    private class InExpressionBuilder extends EclipseLinkAnonymousExpressionVisitor {

        private boolean hasNot;
        private Expression leftExpression;
        private boolean singleInputParameter;

        /**
         * Creates a new <code>InExpressionBuilder</code>.
         */
        InExpressionBuilder() {
            super();
        }

        @Override
        public void visit(CollectionExpression expression) {

            Collection<Expression> expressions = new ArrayList<>();
            InItemExpressionVisitor visitor = new InItemExpressionVisitor();

            for (org.eclipse.persistence.jpa.jpql.parser.Expression child : expression.children()) {
                child.accept(visitor);
                expressions.add(queryExpression);
            }

            if (hasNot) {
                queryExpression = leftExpression.notIn(expressions);
            }
            else {
                queryExpression = leftExpression.in(expressions);
            }
        }

        @Override
        public void visit(IdentificationVariable expression) {

            boolean found = false;

            if (!expression.isVirtual()) {

                ClassDescriptor descriptor = queryContext.getDescriptor(expression.getText());

                // Entity type name
                if (descriptor != null) {
                    type[0] = descriptor.getJavaClass();
                    queryExpression = new ConstantExpression(type[0], queryContext.getBaseExpression());
                    found = true;
                }
            }

            if (!found) {
                expression.accept(ExpressionBuilderVisitor.this);
            }
        }

        @Override
        public void visit(InputParameter expression) {

            if (singleInputParameter) {
                String parameterName = expression.getParameter();

                // Create the expression with Collection as the default type
                queryExpression = queryContext.getBaseExpression();
                queryExpression = queryExpression.getParameter(parameterName.substring(1), Collection.class);

                // Cache the input parameter type, which is by default Collection
                queryContext.addInputParameter(expression, queryExpression);

                if (hasNot) {
                    queryExpression = leftExpression.notIn(queryExpression);
                }
                else {
                    queryExpression = leftExpression.in(queryExpression);
                }
            }
            else {
                visit((org.eclipse.persistence.jpa.jpql.parser.Expression) expression);
            }
        }

        @Override
        protected void visit(org.eclipse.persistence.jpa.jpql.parser.Expression expression) {

            expression.accept(ExpressionBuilderVisitor.this);

            Collection<Expression> expressions = new ArrayList<>();
            expressions.add(queryExpression);

            // Now create the IN expression
            if (hasNot) {
                queryExpression = leftExpression.notIn(expressions);
            }
            else {
                queryExpression = leftExpression.in(expressions);
            }
        }

        @Override
        public void visit(SimpleSelectStatement expression) {

            // First create the subquery
            ReportQuery subquery = buildSubquery(expression);

            // Now create the IN expression
            if (hasNot) {
                queryExpression = leftExpression.notIn(subquery);
            }
            else {
                queryExpression = leftExpression.in(subquery);
            }
        }

        private class InItemExpressionVisitor extends AnonymousExpressionVisitor {


            @Override
            public void visit(IdentificationVariable expression) {
                ClassDescriptor descriptor = queryContext.getDescriptor(expression.getVariableName());
                queryExpression = queryContext.getBaseExpression();
                queryExpression = new ConstantExpression(descriptor.getJavaClass(), queryExpression);
            }


            @Override
            public void visit(CollectionExpression expression) {

                // Assume this is a nested array
                List<Expression> children = new LinkedList<>();

                for (org.eclipse.persistence.jpa.jpql.parser.Expression child : expression.children()) {
                    child.accept(this);
                    children.add(queryExpression);
                }

                queryExpression = new org.eclipse.persistence.internal.expressions.CollectionExpression(children, queryContext.getBaseExpression());
            }


            @Override
            public void visit(SubExpression expression) {
                expression.getExpression().accept(this);
            }


            @Override
            protected void visit(org.eclipse.persistence.jpa.jpql.parser.Expression expression) {
                expression.accept(ExpressionBuilderVisitor.this);
            }
        }
    }

    private class PathResolver extends AbstractEclipseLinkExpressionVisitor {

        /**
         * Determines whether
         */
        boolean checkMappingType;

        /**
         * Keeps track of the {@link Declaration} when the identification variable maps to a "root"
         * object defined in the <code><b>FROM</b></code> clause.
         */
        private Declaration declaration;

        /**
         * Keeps track of the descriptor while traversing the path expression.
         */
        private ClassDescriptor descriptor;

        /**
         * The actual number of paths within the path expression that will be traversed in order to
         * create the EclipseLink {@link Expression}.
         */
        int length;

        /**
         * The EclipseLink {@link Expression} that was retrieved or created while traversing the path
         * expression.
         */
        Expression localExpression;

        /**
         * Determines whether the target relationship is allowed to be <code>null</code>.
         */
        boolean nullAllowed;

        /**
         * Resolves a database column.
         *
         * @param expression The path expression representing an identification variable mapping to a
         * database table followed by the column name
         */
        private void resolveColumn(AbstractPathExpression expression) {
            String path = expression.getPath(1);
            localExpression = localExpression.getField(path);
        }

        /**
         * Attempts to resolve the path expression as a fully qualified enum constant.
         *
         * @param expression The {@link AbstractPathExpression} that might represent an enum constant
         * @return <code>true</code> if the path was a fully qualified enum constant; <code>false</code>
         * if it's an actual path expression
         */
        protected boolean resolveEnumConstant(AbstractPathExpression expression) {

            String fullPath = expression.toParsedText();
            Class<?> enumType = queryContext.getEnumType(fullPath);

            if (enumType != null) {

                // Make sure we keep track of the enum type
                type[0] = enumType;

                // Retrieve the enum constant
                String path = expression.getPath(expression.pathSize() - 1);
                Enum<?> enumConstant = retrieveEnumConstant(enumType, path);

                // Create the Expression
                localExpression = new ConstantExpression(enumConstant, new ExpressionBuilder());

                return true;
            }

            return false;
        }

        private void resolvePath(AbstractPathExpression expression) {

            for (int index = expression.hasVirtualIdentificationVariable() ? 0 : 1, count = length; index < count; index++) {

                String path = expression.getPath(index);
                DatabaseMapping mapping = descriptor.getObjectBuilder().getMappingForAttributeName(path);
                boolean last = (index + 1 == count);
                boolean collectionMapping = false;

                // The path is a mapping
                if (mapping != null) {

                    // Make sure we keep track of its type
                    if (type != null) {
                        type[0] = queryContext.calculateMappingType(mapping);
                    }

                    // This will tell us how to create the Expression
                    collectionMapping = mapping.isCollectionMapping();

                    // Retrieve the reference descriptor so we can continue traversing the path
                    if (!last) {
                        descriptor = mapping.getReferenceDescriptor();
                    }
                    // Flag that needs to be modified for a special case
                    else if (checkMappingType) {
                        nullAllowed = mapping.isForeignReferenceMapping();
                    }
                }
                // No mapping is defined for the single path, check for a query key
                else {
                    QueryKey queryKey = descriptor.getQueryKeyNamed(path);

                    if (queryKey != null) {
                        // Make sure we keep track of its type
                        if (type != null) {
                            type[0] = queryContext.calculateQueryKeyType(queryKey);
                        }

                        // This will tell us how to create the Expression
                        collectionMapping = queryKey.isCollectionQueryKey();

                        // Retrieve the reference descriptor so we can continue traversing the path
                        if (!last && queryKey.isForeignReferenceQueryKey()) {
                            ForeignReferenceQueryKey referenceQueryKey = (ForeignReferenceQueryKey) queryKey;
                            descriptor = queryContext.getDescriptor(referenceQueryKey.getReferenceClass());
                        }
                    }
                    // Nothing was found
                    else {
                        break;
                    }
                }

                // Now create the Expression
                if (collectionMapping) {
                    if (last && nullAllowed) {
                        localExpression = localExpression.anyOfAllowingNone(path);
                    }
                    else {
                        localExpression = localExpression.anyOf(path);
                    }
                }
                else {
                    if (last && nullAllowed) {
                        localExpression = localExpression.getAllowingNull(path);
                    }
                    else {
                        localExpression = localExpression.get(path);
                    }
                }
            }
        }

        private void resolveVirtualPath(AbstractPathExpression expression) {
            String path = expression.getPath(1);
            localExpression = localExpression.get(path);
        }

        /**
         * Retrieves the actual {@link Enum} constant with the given name.
         *
         * @param type The {@link Enum} class used to retrieve the given name
         * @param name The name of the constant to retrieve
         * @return The {@link Enum} constant
         */
        private Enum<?> retrieveEnumConstant(Class<?> type, String name) {

            for (Enum<?> enumConstant : (Enum<?>[]) type.getEnumConstants()) {
                if (name.equals(enumConstant.name())) {
                    return enumConstant;
                }
            }

            return null;
        }

        @Override
        public void visit(CollectionValuedPathExpression expression) {
            visitPathExpression(expression);
        }

        @Override
        public void visit(EntryExpression expression) {

            IdentificationVariable identificationVariable = (IdentificationVariable) expression.getExpression();
            String variableName = identificationVariable.getVariableName();

            // Retrieve the Expression for the identification variable
            declaration = queryContext.findDeclaration(variableName);
            declaration.getBaseExpression().accept(ExpressionBuilderVisitor.this);
            localExpression = queryExpression;

            // Create the Map.Entry expression
            MapEntryExpression entryExpression = new MapEntryExpression(localExpression);
            entryExpression.returnMapEntry();
            localExpression = entryExpression;
        }

        @Override
        public void visit(IdentificationVariable expression) {

            expression.accept(ExpressionBuilderVisitor.this);
            localExpression = queryExpression;

            // It is possible the Expression is null, it happens when the path expression is an enum
            // constant. If so, then no need to retrieve the descriptor
            if (localExpression != null) {
                declaration = queryContext.findDeclaration(expression.getVariableName());
                descriptor = declaration.getDescriptor();
            }
        }

        @Override
        public void visit(KeyExpression expression) {

            IdentificationVariable identificationVariable = (IdentificationVariable) expression.getExpression();

            // Create the Expression for the identification variable
            identificationVariable.accept(ExpressionBuilderVisitor.this);
            localExpression = new MapEntryExpression(queryExpression);

            // Retrieve the mapping's key mapping's descriptor
            descriptor = queryContext.resolveDescriptor(expression);
        }

        @Override
        public void visit(StateFieldPathExpression expression) {
            visitPathExpression(expression);
        }

        @Override
        public void visit(TreatExpression expression) {

            expression.accept(ExpressionBuilderVisitor.this);
            localExpression = queryExpression;

            // Retrieve the mapping's key mapping's descriptor
            descriptor = queryContext.resolveDescriptor(expression);
        }

        @Override
        public void visit(ValueExpression expression) {

            IdentificationVariable identificationVariable = (IdentificationVariable) expression.getExpression();

            // Create the Expression for the identification variable
            identificationVariable.accept(ExpressionBuilderVisitor.this);
            localExpression = queryExpression;

            // Retrieve the mapping's reference descriptor
            declaration = queryContext.findDeclaration(identificationVariable.getVariableName());
            descriptor = declaration.getDescriptor();
        }

        private void visitPathExpression(AbstractPathExpression expression) {

            // First resolve the identification variable
            expression.getIdentificationVariable().accept(this);

            // The path expression is composed with an identification
            // variable that is mapped to a subquery as the "root" object
            if ((declaration != null) && (declaration.getType() == Type.SUBQUERY)) {
                resolveVirtualPath(expression);
                return;
            }

            // A null value would most likely mean it's coming from a
            // state field path expression that represents an enum constant
            if (localExpression == null) {
                boolean result = resolveEnumConstant(expression);
                if (result) {
                    return;
                }
            }

            // The path expression is mapping to a database table
            if ((declaration != null) && (declaration.getType() == Type.TABLE)) {
                resolveColumn(expression);
                return;
            }

            // Traverse the rest of the path expression
            resolvePath(expression);
        }
    }

    /**
     * This visitor is responsible to create the {@link Expression Expressions} for the <b>WHEN</b>
     * and <b>THEN</b> expressions.
     */
    private class WhenClauseExpressionVisitor extends AbstractExpressionVisitor {

        /**
         * Keeps tracks of the type of each <code><b>WHEN</b></code> clauses.
         */
        final List<Class<?>> types;

        /**
         * The map of <b>WHEN</b> expressions mapped to their associated <b>THEN</b> expression.
         */
        Map<Expression, Expression> whenClauses;

        /**
         * Creates a new <code>WhenClauseExpressionVisitor</code>.
         */
        WhenClauseExpressionVisitor() {
            super();
            types = new LinkedList<>();
            whenClauses = new LinkedHashMap<>();
        }

        /**
         * Disposes this visitor.
         */
        void dispose() {
            types.clear();
            whenClauses.clear();
        }

        @Override
        public void visit(CollectionExpression expression) {
            expression.acceptChildren(this);
        }

        @Override
        public void visit(WhenClause expression) {

            // Create the WHEN expression
            expression.getWhenExpression().accept(ExpressionBuilderVisitor.this);
            Expression whenExpression = queryExpression;

            // Create the THEN expression
            expression.getThenExpression().accept(ExpressionBuilderVisitor.this);
            Expression thenExpression = queryExpression;
            types.add(type[0]);

            whenClauses.put(whenExpression, thenExpression);
        }
    }
}
