/*
 * Copyright (c) 2006, 2021 Oracle and/or its affiliates. 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
//
package org.eclipse.persistence.jpa.jpql.tools;

import static org.eclipse.persistence.jpa.jpql.parser.AbstractExpression.DOT;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.ALL;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.AS;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.AS_OF;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.CONNECT_BY;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.EXCEPT;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.FROM;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.INTERSECT;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.NOT_EQUAL;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.NULLS_FIRST;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.NULLS_LAST;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.ORDER_SIBLINGS_BY;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.REGEXP;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.SCN;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.SELECT;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.START_WITH;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.TABLE;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.TIMESTAMP;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.UNION;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.WHERE;

import java.util.List;

import org.eclipse.persistence.jpa.jpql.EclipseLinkVersion;
import org.eclipse.persistence.jpa.jpql.ExpressionTools;
import org.eclipse.persistence.jpa.jpql.LiteralType;
import org.eclipse.persistence.jpa.jpql.parser.AbstractEclipseLinkExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.AbstractFromClause;
import org.eclipse.persistence.jpa.jpql.parser.AbstractPathExpression;
import org.eclipse.persistence.jpa.jpql.parser.AbstractSelectStatement;
import org.eclipse.persistence.jpa.jpql.parser.AsOfClause;
import org.eclipse.persistence.jpa.jpql.parser.CastExpression;
import org.eclipse.persistence.jpa.jpql.parser.CollectionExpression;
import org.eclipse.persistence.jpa.jpql.parser.CollectionValuedPathExpressionBNF;
import org.eclipse.persistence.jpa.jpql.parser.ConnectByClause;
import org.eclipse.persistence.jpa.jpql.parser.DatabaseType;
import org.eclipse.persistence.jpa.jpql.parser.DefaultEclipseLinkJPQLGrammar;
import org.eclipse.persistence.jpa.jpql.parser.EclipseLinkExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.Expression;
import org.eclipse.persistence.jpa.jpql.parser.ExtractExpression;
import org.eclipse.persistence.jpa.jpql.parser.FromClause;
import org.eclipse.persistence.jpa.jpql.parser.HierarchicalQueryClause;
import org.eclipse.persistence.jpa.jpql.parser.JPQLGrammar;
import org.eclipse.persistence.jpa.jpql.parser.OrderByItem;
import org.eclipse.persistence.jpa.jpql.parser.OrderByItem.Ordering;
import org.eclipse.persistence.jpa.jpql.parser.OrderSiblingsByClause;
import org.eclipse.persistence.jpa.jpql.parser.PatternValueBNF;
import org.eclipse.persistence.jpa.jpql.parser.RegexpExpression;
import org.eclipse.persistence.jpa.jpql.parser.ScalarExpressionBNF;
import org.eclipse.persistence.jpa.jpql.parser.SelectStatement;
import org.eclipse.persistence.jpa.jpql.parser.SimpleFromClause;
import org.eclipse.persistence.jpa.jpql.parser.SimpleSelectStatement;
import org.eclipse.persistence.jpa.jpql.parser.StartWithClause;
import org.eclipse.persistence.jpa.jpql.parser.TableExpression;
import org.eclipse.persistence.jpa.jpql.parser.TableVariableDeclaration;
import org.eclipse.persistence.jpa.jpql.parser.UnionClause;
import org.eclipse.persistence.jpa.jpql.tools.ContentAssistProposals.ClassType;
import org.eclipse.persistence.jpa.jpql.tools.resolver.Declaration;

/**
 * This extension over the default content assist visitor adds the additional support EclipseLink
 * provides.
 * <p>
 * Provisional API: This interface is part of an interim API that is still under development and
 * expected to change significantly before reaching stability. It is available at this early stage
 * to solicit feedback from pioneering adopters on the understanding that any code that uses this
 * API will almost certainly be broken (repeatedly) as the API evolves.
 *
 * @version 2.5.1
 * @since 2.4
 * @author Pascal Filion
 */
@SuppressWarnings("unused") // unused used for the import statement: see bug 330740
public class EclipseLinkContentAssistVisitor extends AbstractContentAssistVisitor
                                             implements EclipseLinkExpressionVisitor {

    /**
     * Creates a new <code>EclipseLinkContentAssistVisitor</code>.
     *
     * @param queryContext The context used to query information about the query
     * @exception NullPointerException The {@link JPQLQueryContext} cannot be <code>null</code>
     */
    public EclipseLinkContentAssistVisitor(JPQLQueryContext queryContext) {
        super(queryContext);
    }

    @Override
    protected AcceptableTypeVisitor buildAcceptableTypeVisitor() {
        return new AcceptableTypeVisitor();
    }

    @Override
    protected AppendableExpressionVisitor buildAppendableExpressionVisitor() {
        return new AppendableExpressionVisitor(this);
    }

    @Override
    protected EndingQueryPositionBuilder buildEndingQueryPositionBuilder() {
        return new EndingQueryPositionBuilder(this);
    }

    @Override
    protected FollowingClausesVisitor buildFollowingClausesVisitor() {
        return new FollowingClausesVisitor();
    }

    @Override
    protected FromClauseCollectionHelper buildFromClauseCollectionHelper() {
        return new FromClauseCollectionHelper(this);
    }

    @Override
    protected FromClauseStatementHelper buildFromClauseStatementHelper() {
        return new FromClauseStatementHelper(this);
    }

    @Override
    protected GroupByClauseCollectionHelper buildGroupByClauseCollectionHelper() {
        return new GroupByClauseCollectionHelper(this);
    }

    @Override
    protected IncompleteCollectionExpressionVisitor buildIncompleteCollectionExpressionVisitor() {
        return new IncompleteCollectionExpressionVisitor();
    }

    @Override
    protected OrderByClauseStatementHelper buildOrderByClauseStatementHelper() {
        return new OrderByClauseStatementHelper(this);
    }

    @Override
    protected SimpleFromClauseStatementHelper buildSimpleFromClauseStatementHelper() {
        return new SimpleFromClauseStatementHelper(this);
    }

    protected TableExpressionVisitor buildTableExpressionVisitor() {
        return new TableExpressionVisitor();
    }

    protected UnionClauseStatementHelper buildUnionClauseStatementHelper() {
        return new UnionClauseStatementHelper();
    }

    /**
     * Returns the enum constant of the EclipseLink version specified in the {@link JPQLQueryContext}.
     *
     * @return The EclipseLink version specified or the default version (i.e. the version of the
     * current release)
     * @since 2.5
     */
    protected EclipseLinkVersion getEcliseLinkVersion() {
        return EclipseLinkVersion.value(queryContext.getProviderVersion());
    }

    @Override
    protected JPQLGrammar getLatestGrammar() {
        return DefaultEclipseLinkJPQLGrammar.instance();
    }

    protected TableExpressionVisitor getTableExpressionVisitor() {
        TableExpressionVisitor visitor = getHelper(TableExpressionVisitor.class);
        if (visitor == null) {
            visitor = buildTableExpressionVisitor();
            registerHelper(TableExpressionVisitor.class, visitor);
        }
        return visitor;
    }

    protected String getTableName(String variableName) {

        Declaration declaration = queryContext.getDeclaration(variableName);
        Expression baseExpression = (declaration != null) ? declaration.getBaseExpression() : null;

        if ((baseExpression != null) && isTableExpression(baseExpression)) {
           return queryContext.literal(baseExpression, LiteralType.STRING_LITERAL);
        }

        return null;
    }

    protected UnionClauseStatementHelper getUnionClauseStatementHelper() {
        UnionClauseStatementHelper helper = getHelper(UnionClauseStatementHelper.class);
        if (helper == null) {
            helper = buildUnionClauseStatementHelper();
            registerHelper(UnionClauseStatementHelper.class, helper);
        }
        return helper;
    }

    @Override
    protected void initialize() {
        super.initialize();
        identifierFilters.put(REGEXP,    VALID_IDENTIFIER_FILTER);
        identifierFilters.put(NOT_EQUAL, VALID_IDENTIFIER_FILTER);
    }

    @Override
    protected boolean isJoinFetchIdentifiable() {
        EclipseLinkVersion version = EclipseLinkVersion.value(queryContext.getProviderVersion());
        return version.isNewerThanOrEqual(EclipseLinkVersion.VERSION_2_4);
    }

    protected boolean isTableExpression(Expression expression) {
        TableExpressionVisitor visitor = getTableExpressionVisitor();
        try {
            visitor.expression = expression;
            expression.accept(visitor);
            return visitor.valid;
        }
        finally {
            visitor.valid = false;
            visitor.expression = null;
        }
    }

    @Override
    public void visit(AsOfClause expression) {
        super.visit(expression);
        int position = queryPosition.getPosition(expression) - corrections.peek();

        // Within "AS OF"
        if (isPositionWithin(position, AS_OF)) {
            proposals.addIdentifier(AS_OF);
        }
        // After "AS OF"
        else if (expression.hasSpaceAfterIdentifier()) {

            int length = AS_OF.length() + SPACE_LENGTH;

            // Right after "AS OF "
            if (position == length) {
                addIdentifier(SCN);
                addIdentifier(TIMESTAMP);

                if (!expression.hasScn() &&
                    !expression.hasTimestamp()) {

                    addIdentificationVariables();
                    addFunctionIdentifiers(ScalarExpressionBNF.ID);
                }
            }
            // After "AS OF SCN" or "AS OF TIMESTAMP"
            else if (expression.hasScn() ||
                     expression.hasSpaceAfterIdentifier()) {

                // SCN
                if (expression.hasScn() && isPositionWithin(position, length, SCN)) {
                    proposals.addIdentifier(SCN);
                    proposals.addIdentifier(TIMESTAMP);
                }
                // TIMESTAMP
                else if (expression.hasTimestamp() && isPositionWithin(position, length, TIMESTAMP)) {
                    proposals.addIdentifier(SCN);
                    proposals.addIdentifier(TIMESTAMP);
                }
                else {

                    if (expression.hasScn()) {
                        length += SCN.length();
                    }
                    else if (expression.hasTimestamp()) {
                        length += TIMESTAMP.length();
                    }

                    // After "AS OF SCN " or "AS OF TIMESTAMP "
                    if (expression.hasSpaceAfterCategory()) {
                        addIdentificationVariables();
                        addFunctionIdentifiers(ScalarExpressionBNF.ID);
                    }
                }
            }
        }
    }

    @Override
    public void visit(CastExpression expression) {
        super.visit(expression);
        int position = queryPosition.getPosition(expression) - corrections.peek();
        String identifier = expression.getIdentifier();

        // Within CAST
        if (isPositionWithin(position, identifier)) {
            addIdentifier(identifier);
            addIdentificationVariables();
            addFunctionIdentifiers(expression.getParent().findQueryBNF(expression));
        }
        // After "CAST("
        else if (expression.hasLeftParenthesis()) {
            int length = identifier.length() + 1 /* '(' */;

            // Right after "CAST("
            if (position == length) {
                addIdentificationVariables();
                addFunctionIdentifiers(expression.getEncapsulatedExpressionQueryBNFId());
            }
            else if (expression.hasExpression()) {
                Expression scalarExpression = expression.getExpression();

                if (isComplete(scalarExpression)) {
                    length += scalarExpression.getLength();

                    if (expression.hasSpaceAfterExpression()) {
                        length++;

                        // Right before "AS" or database type
                        if (position == length) {
                            addAggregateIdentifiers(expression.getEncapsulatedExpressionQueryBNFId());
                            proposals.addIdentifier(AS);
                        }
                        // Within "AS"
                        else if (isPositionWithin(position, length, AS)) {
                            proposals.addIdentifier(AS);
                        }
                    }
                }
            }
        }
    }

    @Override
    public void visit(ConnectByClause expression) {
        super.visit(expression);
        int position = queryPosition.getPosition(expression) - corrections.peek();

        // Within "CONNECT BY"
        if (isPositionWithin(position, CONNECT_BY)) {
            proposals.addIdentifier(CONNECT_BY);
        }
        // After "CONNECT BY"
        else if (expression.hasSpaceAfterConnectBy()) {

            int length = CONNECT_BY.length() + SPACE_LENGTH;

            // Right after "CONNECT BY "
            if (position == length) {
                addIdentificationVariables();
                addFunctionIdentifiers(CollectionValuedPathExpressionBNF.ID);
            }
        }
    }

    @Override
    public void visit(DatabaseType expression) {
        super.visit(expression);
        // Nothing to do, this is database specific
    }

    @Override
    public void visit(ExtractExpression expression) {
        super.visit(expression);
        int position = queryPosition.getPosition(expression) - corrections.peek();
        String identifier = expression.getIdentifier();

        // Within "EXTRACT"
        if (isPositionWithin(position, identifier)) {
            proposals.addIdentifier(identifier);
            addFunctionIdentifiers(expression);
        }
        // After "EXTRACT("
        else if (expression.hasLeftParenthesis()) {
            int length = identifier.length() + 1 /* '(' */;

            // Right after "EXTRACT("
            if (position == length) {
                // Nothing to do, unless we show basic date parts
            }

            if (expression.hasDatePart()) {
                String datePart = expression.getDatePart();

                // Within "<date part>"
                if (isPositionWithin(position, length, datePart)) {
                    // Nothing to do, unless we show basic date parts
                }

                length += datePart.length();

                // After "<date part> "
                if (expression.hasSpaceAfterDatePart()) {
                    length++;

                    // Right before "FROM"
                    if (position == length) {
                        addIdentifier(FROM);

                        // Only add the scalar expression's functions if it is not specified
                        // or the FROM identifier is not present
                        if (!expression.hasExpression() || !expression.hasFrom()) {
                            addIdentificationVariables();
                            addFunctionIdentifiers(expression.getEncapsulatedExpressionQueryBNFId());
                        }
                    }
                }
            }

            if (expression.hasFrom()) {

                // Within "FROM"
                if (isPositionWithin(position, length, FROM)) {
                    proposals.addIdentifier(FROM);

                    // Only add the scalar expression's functions if it is not specified
                    if (!expression.hasExpression()) {
                        addIdentificationVariables();
                        addFunctionIdentifiers(expression.getEncapsulatedExpressionQueryBNFId());
                    }
                }

                length += 4 /* FROM */;

                if (expression.hasSpaceAfterFrom()) {
                    length++;
                }

                // Right after "FROM "
                if (position == length) {
                    addIdentificationVariables();
                    addFunctionIdentifiers(expression.getEncapsulatedExpressionQueryBNFId());
                }
            }
        }
    }

    @Override
    public void visit(HierarchicalQueryClause expression) {
        super.visit(expression);
        int position = queryPosition.getPosition(expression) - corrections.peek();

        // At the beginning of the clause
        if (position == 0) {
            addIdentifier(START_WITH);

            if (!expression.hasStartWithClause()) {
                addIdentifier(CONNECT_BY);
            }
        }
        else {
            int length = 0;

            // After the start with clause
            if (expression.hasStartWithClause()) {
                length += expression.getStartWithClause().getLength();

                // Right after the start with clause
                if (hasVirtualSpace() && (position == length + SPACE_LENGTH)) {
                    addIdentifier(CONNECT_BY);
                }
                // After the start with clause
                else if (expression.hasSpaceAfterStartWithClause()) {
                    length++;

                    // Right after the start with clause
                    if (position == length) {
                        addIdentifier(CONNECT_BY);
                    }
                }
            }

            length += expression.getConnectByClause().getLength();

            // Right after the connect by clause
            if (hasVirtualSpace() && (position == length + SPACE_LENGTH)) {
                addIdentifier(ORDER_SIBLINGS_BY);
            }
            // After the connect by clause
            else if (expression.hasSpaceAfterConnectByClause()) {
                length++;

                if (position == length) {
                    addIdentifier(ORDER_SIBLINGS_BY);
                }
            }
        }
    }

    @Override
    public void visit(OrderByItem expression) {
        super.visit(expression);
        int position = queryPosition.getPosition(expression) - corrections.peek();

        // After the order by item
        if (expression.hasExpression()) {
            int length = expression.getExpression().getLength();

            if (expression.hasSpaceAfterExpression()) {
                length++;

                // Right after the order by item
                if (position == length) {

                    // Only add "NULLS FIRST" and "NULLS LAST" if the ordering is not specified
                    if (expression.getOrdering() == Ordering.DEFAULT) {
                        proposals.addIdentifier(NULLS_FIRST);
                        proposals.addIdentifier(NULLS_LAST);
                    }
                }
                else {
                    length += expression.getActualOrdering().length();

                    if (position > length) {
                        if (expression.hasSpaceAfterOrdering()) {
                            length += SPACE_LENGTH;

                            // Right before "NULLS FIRST" or "NULLS LAST"
                            if (position == length) {
                                proposals.addIdentifier(NULLS_FIRST);
                                proposals.addIdentifier(NULLS_LAST);
                            }
                            else {
                                String nullOrdering = expression.getActualNullOrdering();

                                // Within "NULLS FIRST" or "NULLS LAST"
                                if (isPositionWithin(position, length, nullOrdering)) {
                                    proposals.addIdentifier(NULLS_FIRST);
                                    proposals.addIdentifier(NULLS_LAST);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    @Override
    public void visit(OrderSiblingsByClause expression) {
        if (!isLocked(expression)) {
            super.visit(expression);
            visitCollectionExpression(expression, ORDER_SIBLINGS_BY, getOrderByClauseCollectionHelper());
        }
    }

    @Override
    public void visit(RegexpExpression expression) {
        super.visit(expression);
        int position = queryPosition.getPosition(expression) - corrections.peek();
        int length = 0;

        if (expression.hasStringExpression()) {
            length += expression.getStringExpression().getLength();

            if (expression.hasSpaceAfterStringExpression()) {
                length += SPACE_LENGTH;
            }
        }

        // Within "REGEXP"
        if (isPositionWithin(position, length, REGEXP)) {
            proposals.addIdentifier(REGEXP);
        }
        // After "REGEXP"
        else {
            length += 6 /* REGEXP */;

            // After "REGEXP "
            if (expression.hasSpaceAfterIdentifier()) {
                length += SPACE_LENGTH;

                // Right after "REGEXP "
                addIdentificationVariables();
                addFunctionIdentifiers(PatternValueBNF.ID);
            }
        }
    }

    @Override
    public void visit(StartWithClause expression) {
        if (!isLocked(expression)) {
            super.visit(expression);
            visitCollectionExpression(expression, expression.getIdentifier(), getConditionalClauseCollectionHelper());
        }
    }

    @Override
    public void visit(TableExpression expression) {
        super.visit(expression);
        int position = queryPosition.getPosition(expression);

        // Within "TABLE"
        if (isPositionWithin(position, TABLE)) {
            proposals.addIdentifier(TABLE);
        }
        // After '('
        else if (expression.hasLeftParenthesis()) {
            int length = TABLE.length() + SPACE_LENGTH;

            // Right after '('
            if (position == length) {
                proposals.setTableNamePrefix(ExpressionTools.EMPTY_STRING);
            }
            else {
                Expression nameExpression = expression.getExpression();
                String tableName = queryContext.literal(nameExpression, LiteralType.STRING_LITERAL);

                if (tableName.length() == 0) {
                    tableName = queryContext.literal(nameExpression, LiteralType.IDENTIFICATION_VARIABLE);
                }

                int tableNameLength = tableName.length();

                // Within the string literal representing the table name
                if ((position > length) && (position <= length + tableNameLength)) {
                    String prefix = tableName.substring(0, position - length);
                    prefix = ExpressionTools.unquote(prefix);
                    proposals.setTableNamePrefix(prefix);
                }
            }
        }
    }

    @Override
    public void visit(TableVariableDeclaration expression) {
        super.visit(expression);

        TableExpression tableExpression = expression.getTableExpression();
        int position = queryPosition.getPosition(expression) - corrections.peek();
        int length = tableExpression.getLength();

        // After "TABLE()"
        if (expression.hasSpaceAfterTableExpression()) {
            length += SPACE_LENGTH;

            // Right after "TABLE() "
            if (isPositionWithin(position, length, AS) &&
                isComplete(tableExpression)) {

                addIdentifier(AS);
            }
        }
    }

    @Override
    public void visit(UnionClause expression) {
        super.visit(expression);
        int position = queryPosition.getPosition(expression) - corrections.peek();
        String identifier = expression.getIdentifier();

        // Within <identifier>
        if (isPositionWithin(position, identifier)) {
            proposals.addIdentifier(EXCEPT);
            proposals.addIdentifier(INTERSECT);
            proposals.addIdentifier(UNION);
        }
        // After "<identifier> "
        else if (expression.hasSpaceAfterIdentifier()) {
            int length = identifier.length() + SPACE_LENGTH;

            // Right after "<identifier> "
            if (position == length) {
                proposals.addIdentifier(ALL);

                if (!expression.hasAll()) {
                    addIdentifier(SELECT);
                }
            }
            // Within "ALL"
            else if (isPositionWithin(position, length, ALL)) {
                addIdentifier(ALL);
            }
            else {
                if ((position == length) && !expression.hasAll()) {
                    proposals.addIdentifier(SELECT);
                }
                else {

                    if (expression.hasAll()) {
                        length += 3 /* ALL */;
                    }

                    // After "ALL "
                    if (expression.hasSpaceAfterAll()) {
                        length += SPACE_LENGTH;

                        // Right after "ALL "
                        if (position == length) {
                            proposals.addIdentifier(SELECT);
                        }
                    }
                }
            }
        }
    }

    @Override
    protected void visitThirdPartyPathExpression(AbstractPathExpression expression,
                                                 String variableName) {

        // Check to see if a column name can be resolved
        int position = queryPosition.getPosition(expression);
        String text = expression.toActualText();
        int dotIndex = text.indexOf(DOT);
        int secondDotIndex = (dotIndex > -1) ? text.indexOf(DOT, dotIndex + 1) : -1;

        // The cursor position is after the first dot and either there is no second dot or the
        // position is before the second dot, which means a table name and column names could
        // potentially be resolved
        if ((secondDotIndex == -1) || (position < secondDotIndex)) {
            String tableName = getTableName(variableName);

            if (tableName != ExpressionTools.EMPTY_STRING) {
                tableName = ExpressionTools.unquote(tableName);
                proposals.setTableName(tableName, text.substring(dotIndex + 1, position));
            }
        }
    }

    // Made static final for performance reasons.
    protected static final class AcceptableTypeVisitor extends AbstractContentAssistVisitor.AcceptableTypeVisitor {
    }

    // Made static final for performance reasons.
    protected static final class AppendableExpressionVisitor extends AbstractContentAssistVisitor.AppendableExpressionVisitor
                                                implements EclipseLinkExpressionVisitor {
        AppendableExpressionVisitor(AbstractContentAssistVisitor visitor) {
            super(visitor);
        }

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

        @Override
        public void visit(CastExpression expression) {
            appendable = !conditionalExpression &&
                      expression.hasRightParenthesis();
        }

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

        @Override
        public void visit(DatabaseType expression) {
            // Always complete since it's a single word
        }

        @Override
        public void visit(ExtractExpression expression) {
            appendable = !conditionalExpression &&
                      expression.hasRightParenthesis();
        }

        @Override
        public void visit(HierarchicalQueryClause expression) {

            if (expression.hasOrderSiblingsByClause()) {
                expression.getOrderSiblingsByClause().accept(this);
            }
            else if (expression.hasConnectByClause()) {
                expression.getConnectByClause().accept(this);
            }
            else if (expression.hasStartWithClause()) {
                expression.getStartWithClause().accept(this);
            }
        }

        @Override
        public void visit(OrderSiblingsByClause expression) {

            if (expression.hasOrderByItems()) {
                clauseOfItems = true;
                expression.getOrderByItems().accept(this);
                clauseOfItems = false;
            }
        }

        @Override
        public void visit(RegexpExpression expression) {
            if (expression.hasPatternValue()) {
                expression.getPatternValue().accept(this);
            }
        }

        @Override
        public void visit(StartWithClause expression) {

            if (expression.hasConditionalExpression()) {
                conditionalExpression = true;
                expression.getConditionalExpression().accept(this);
                conditionalExpression = false;
            }
        }

        @Override
        public void visit(TableExpression expression) {
            appendable = !conditionalExpression &&
                      expression.hasRightParenthesis();
        }

        @Override
        public void visit(TableVariableDeclaration expression) {
            if (expression.hasIdentificationVariable()) {
                expression.getIdentificationVariable().accept(this);
            }
        }

        @Override
        public void visit(UnionClause expression) {
            if (expression.hasQuery()) {
                expression.getQuery().accept(this);
            }
        }
    }

    // Made static final for performance reasons.
    protected static final class EndingQueryPositionBuilder extends AbstractContentAssistVisitor.EndingQueryPositionBuilder
                                               implements EclipseLinkExpressionVisitor {

        protected EndingQueryPositionBuilder(AbstractContentAssistVisitor visitor) {
            super(visitor);
        }

        @Override
        public void visit(AsOfClause expression) {

            if (badExpression) {
                return;
            }

            if (expression.hasExpression()) {
                expression.getExpression().accept(this);
            }

            if (queryPosition.getExpression() == null) {
                queryPosition.setExpression(expression);
            }

            queryPosition.addPosition(expression, expression.getLength() - correction);
        }

        @Override
        public void visit(CastExpression expression) {

            if (badExpression) {
                return;
            }

            if (expression.hasScalarExpression() &&
               !expression.hasAs() &&
               !expression.hasDatabaseType() &&
               !expression.hasRightParenthesis()) {

                expression.getExpression().accept(this);
            }

            if (queryPosition.getExpression() == null) {
                queryPosition.setExpression(expression);
            }

            queryPosition.addPosition(expression, expression.getLength() - correction);
        }

        @Override
        public void visit(ConnectByClause expression) {

            if (badExpression) {
                return;
            }

            if (expression.hasExpression()) {
                expression.getExpression().accept(this);
            }

            if (queryPosition.getExpression() == null) {
                queryPosition.setExpression(expression);
            }

            queryPosition.addPosition(expression, expression.getLength() - correction);
        }

        @Override
        public void visit(DatabaseType expression) {
            visitAbstractDoubleEncapsulatedExpression(expression);
        }

        @Override
        public void visit(ExtractExpression expression) {
            visitAbstractSingleEncapsulatedExpression(expression);
        }

        @Override
        public void visit(HierarchicalQueryClause expression) {

            if (badExpression) {
                return;
            }

            if (expression.hasOrderSiblingsByClause()) {
                expression.getOrderSiblingsByClause().accept(this);
            }
            else if (expression.hasConnectByClause()) {
                expression.getConnectByClause().accept(this);
                if (expression.hasSpaceAfterConnectByClause()) {
                    virtualSpace = true;
                }
            }
            else if (expression.hasStartWithClause()) {
                expression.getStartWithClause().accept(this);
                if (expression.hasSpaceAfterStartWithClause()) {
                    virtualSpace = true;
                }
            }

            if (queryPosition.getExpression() == null) {
                queryPosition.setExpression(expression);
            }

            queryPosition.addPosition(expression, expression.getLength() - correction);
        }

        @Override
        public void visit(OrderSiblingsByClause expression) {

            if (badExpression) {
                return;
            }

            if (expression.hasOrderByItems()) {
                expression.getOrderByItems().accept(this);
            }

            if (queryPosition.getExpression() == null) {
                queryPosition.setExpression(expression);
            }

            queryPosition.addPosition(expression, expression.getLength() - correction);
        }

        @Override
        public void visit(RegexpExpression expression) {

            if (badExpression) {
                return;
            }

            if (expression.hasPatternValue()) {
                expression.getPatternValue().accept(this);
            }

            if (queryPosition.getExpression() == null) {
                queryPosition.setExpression(expression);
            }

            queryPosition.addPosition(expression, expression.getLength() - correction);
        }

        @Override
        public void visit(StartWithClause expression) {
            visitAbstractConditionalClause(expression);
        }

        @Override
        public void visit(TableExpression expression) {
            visitAbstractSingleEncapsulatedExpression(expression);
        }

        @Override
        public void visit(TableVariableDeclaration expression) {

            if (badExpression) {
                return;
            }

            if (expression.hasIdentificationVariable()) {
                expression.getIdentificationVariable().accept(this);
            }
            else if (!expression.hasAs()) {
                expression.getTableExpression().accept(this);
            }

            if (queryPosition.getExpression() == null) {
                queryPosition.setExpression(expression);
            }

            queryPosition.addPosition(expression, expression.getLength() - correction);
        }

        @Override
        public void visit(UnionClause expression) {

            if (badExpression) {
                return;
            }

            if (expression.hasQuery()) {
                expression.getQuery().accept(this);
            }

            if (queryPosition.getExpression() == null) {
                queryPosition.setExpression(expression);
            }

            queryPosition.addPosition(expression, expression.getLength() - correction);
        }
    }

    // Made static final for performance reasons.
    /**
     * This visitor adds support for the additional clauses provided by EclipseLink, such as the
     */
    protected static final class FollowingClausesVisitor extends AbstractContentAssistVisitor.FollowingClausesVisitor {

        protected boolean hasAsOfClause;
        protected boolean hasConnectByClause;
        protected boolean hasOrderSiblingsByClause;
        protected boolean hasStartWithClause;
        protected boolean introspect;

        @Override
        public void dispose() {
            super.dispose();
            hasAsOfClause            = false;
            hasConnectByClause       = false;
            hasStartWithClause       = false;
            hasOrderSiblingsByClause = false;
        }

        @Override
        protected boolean hasFromClause(AbstractSelectStatement expression) {

            introspect = true;
            expression.getFromClause().accept(this);
            introspect = false;

            if (afterIdentifier == SELECT) {

                if (beforeIdentifier == START_WITH) {
                    return expression.hasFromClause();
                }

                if (beforeIdentifier == CONNECT_BY) {
                    return expression.hasFromClause() ||
                           hasStartWithClause;
                }

                if (beforeIdentifier == ORDER_SIBLINGS_BY) {
                    return expression.hasFromClause() ||
                           hasStartWithClause         ||
                           hasConnectByClause;
                }

                if (beforeIdentifier == AS_OF) {
                    return expression.hasFromClause() ||
                           hasStartWithClause         ||
                           hasConnectByClause         ||
                           hasOrderSiblingsByClause;
                }

                if (beforeIdentifier == WHERE) {
                    return expression.hasFromClause() ||
                           hasStartWithClause         ||
                           hasConnectByClause         ||
                           hasOrderSiblingsByClause   ||
                           hasAsOfClause;
                }
            }
            else if (afterIdentifier == FROM) {

                if (beforeIdentifier == CONNECT_BY) {
                    return hasStartWithClause;
                }

                if (beforeIdentifier == ORDER_SIBLINGS_BY) {
                    return hasStartWithClause ||
                           hasConnectByClause;
                }

                if (beforeIdentifier == AS_OF) {
                    return hasStartWithClause ||
                           hasConnectByClause ||
                           hasOrderSiblingsByClause;
                }

                if (beforeIdentifier == WHERE) {
                    return hasStartWithClause       ||
                           hasConnectByClause       ||
                           hasOrderSiblingsByClause ||
                           hasAsOfClause;
                }
            }
            else if (afterIdentifier == START_WITH) {

                if (beforeIdentifier == ORDER_SIBLINGS_BY) {
                    return hasConnectByClause;
                }

                if (beforeIdentifier == AS_OF) {
                    return hasConnectByClause ||
                           hasOrderSiblingsByClause;
                }

                if (beforeIdentifier == WHERE) {
                    return hasConnectByClause       ||
                           hasOrderSiblingsByClause ||
                           hasAsOfClause;
                }
            }
            else if (afterIdentifier == CONNECT_BY) {

                if (beforeIdentifier == AS_OF) {
                    return hasOrderSiblingsByClause;
                }

                if (beforeIdentifier == WHERE) {
                    return hasOrderSiblingsByClause ||
                           hasAsOfClause;
                }
            }
            else if (afterIdentifier == ORDER_SIBLINGS_BY) {

                if (beforeIdentifier == WHERE) {
                    return hasAsOfClause;
                }
            }

            return false;
        }

        @Override
        public void visit(FromClause expression) {

            if (!introspect) {
                super.visit(expression);
            }
            else {
                hasAsOfClause = expression.hasAsOfClause();

                if (expression.hasHierarchicalQueryClause()) {
                    expression.getHierarchicalQueryClause().accept(this);
                }
            }
        }

        public void visit(HierarchicalQueryClause expression) {

            if (!introspect) {
                super.visit(expression);
            }
            else {
                hasConnectByClause       = expression.hasConnectByClause();
                hasStartWithClause       = expression.hasStartWithClause();
                hasOrderSiblingsByClause = expression.hasOrderSiblingsByClause();
            }
        }

        @Override
        public void visit(SimpleFromClause expression) {

            if (!introspect) {
                super.visit(expression);
            }
            else {
                hasAsOfClause = expression.hasAsOfClause();

                if (expression.hasHierarchicalQueryClause()) {
                    expression.getHierarchicalQueryClause().accept(this);
                }
            }
        }
    }

    protected class FromClauseCollectionHelper extends AbstractContentAssistVisitor.FromClauseCollectionHelper {

        protected FromClauseCollectionHelper(AbstractContentAssistVisitor visitor) {
            super(visitor);
        }

        @Override
        public void addAtTheEndOfChild(AbstractFromClause expression,
                                       CollectionExpression collectionExpression,
                                       int index,
                                       boolean hasComma,
                                       boolean virtualSpace) {

             super.addAtTheEndOfChild(expression, collectionExpression, index, hasComma, virtualSpace);
             boolean end = (index + 1 == collectionExpression.childrenSize());

            // At the end of a range variable declaration, the following clauses can be added
            // Example: "SELECT e FROM Employee e |"
            // Example: "SELECT e FROM Employee e, Address a |"
             // Example: "SELECT e FROM Employee e |, Address a " <- Not valid to add the clauses
            if (((index == 0) || hasComma) && end && virtualSpace) {

                if (isComplete(collectionExpression.getChild(0))) {

                    EclipseLinkContentAssistVisitor.this.addIdentifier(START_WITH);

                    if (!hasClausesDefinedBetween(expression, FROM, CONNECT_BY)) {
                        EclipseLinkContentAssistVisitor.this.addIdentifier(CONNECT_BY);
                    }

                    if (!hasClausesDefinedBetween(expression, FROM, ORDER_SIBLINGS_BY)) {
                        EclipseLinkContentAssistVisitor.this.addIdentifier(CONNECT_BY);
                    }

                    if (!hasClausesDefinedBetween(expression, FROM, AS_OF)) {
                        EclipseLinkContentAssistVisitor.this.addIdentifier(AS_OF);
                    }
                }
            }
            // Special case to handle a range variable declaration that can also
            // be either the beginning of the following clauses
            // Example: "SELECT e FROM Employee o o|" <- Valid
            // Example: "SELECT e FROM Employee o, Address a o|" <- Valid
            // Example: "SELECT e FROM Employee o|" <- Not valid
            else if ((index > 0) && end && !hasComma) {

                addCompositeIdentifier(START_WITH, 4 /* START - 1 */);

                if (!hasClausesDefinedBetween(expression, FROM, CONNECT_BY)) {
                    addCompositeIdentifier(CONNECT_BY, 6 /* CONNECT - 1 */);
                }

                if (!hasClausesDefinedBetween(expression, FROM, ORDER_SIBLINGS_BY)) {
                    addCompositeIdentifier(ORDER_SIBLINGS_BY, 4 /* ORDER - 1 */);
                }

                // AS OF clause
                if (!hasClausesDefinedBetween(expression, FROM, AS_OF)) {
                    addCompositeIdentifier(AS_OF, 1 /* AS - 1 */);
                }
            }
        }

        @Override
        public void addTheBeginningOfChild(AbstractFromClause expression,
                                           CollectionExpression collectionExpression,
                                           int index,
                                           boolean hasComma) {

            super.addTheBeginningOfChild(expression, collectionExpression, index, hasComma);

            // 1. At the beginning of the FROM declaration, fully qualified class names are valid proposals
            // 2. To be valid elsewhere, the declarations have to be separated by a comma
            //    "SELECT e FROM Employee e W|" <- entity names are not valid proposals, only 'WHERE' is
            if ((index == 0) || hasComma) {
                proposals.setClassNamePrefix(word, ClassType.INSTANTIABLE);
            }

            // The identifier for a TABLE declaration can only be added after
            // the first declaration, as long as there is a comma before it
            // "SELECT e FROM Employee e, |" <- 'TABLE' is a valid proposal
            // "SELECT e FROM Employee e, T|" <- 'TABLE' is a valid proposal
            // "SELECT e FROM Employee e T|" <- 'TABLE' is NOT a valid proposal
            if ((index > 0) && hasComma) {
                EclipseLinkContentAssistVisitor.this.addIdentifier(TABLE);
            }

            // Add the "internal" clauses of the FROM clause defined by EclipseLink
            // only if it ends the FROM clause expression
            if (collectionExpression != null) {
                boolean end = (index + 1 == collectionExpression.childrenSize());

                 if (end && !hasComma) {

                    EclipseLinkContentAssistVisitor.this.addIdentifier(START_WITH);

                    if (!hasClausesDefinedBetween(expression, FROM, CONNECT_BY)) {
                        EclipseLinkContentAssistVisitor.this.addIdentifier(CONNECT_BY);
                    }

                    if (!hasClausesDefinedBetween(expression, FROM, ORDER_SIBLINGS_BY)) {
                        EclipseLinkContentAssistVisitor.this.addIdentifier(CONNECT_BY);
                    }

                    if (!hasClausesDefinedBetween(expression, FROM, AS_OF)) {
                        EclipseLinkContentAssistVisitor.this.addIdentifier(AS_OF);
                    }
                 }
            }
        }
    }

    protected class FromClauseStatementHelper extends AbstractContentAssistVisitor.FromClauseStatementHelper {

        protected FromClauseStatementHelper(AbstractContentAssistVisitor visitor) {
            super(visitor);
        }

        @Override
        public void addInternalClauseProposals(SelectStatement expression) {
            super.addInternalClauseProposals(expression);

            if (!hasClausesDefinedBetween(expression, FROM, WHERE)) {
                EclipseLinkContentAssistVisitor.this.addIdentifier(START_WITH);
            }

            if (!hasClausesDefinedBetween(expression, START_WITH, ORDER_SIBLINGS_BY)) {
                EclipseLinkContentAssistVisitor.this.addIdentifier(CONNECT_BY);
            }

            if (!hasClausesDefinedBetween(expression, CONNECT_BY, AS_OF)) {
                EclipseLinkContentAssistVisitor.this.addIdentifier(ORDER_SIBLINGS_BY);
            }

            if (!hasClausesDefinedBetween(expression, ORDER_SIBLINGS_BY, WHERE)) {
                EclipseLinkContentAssistVisitor.this.addIdentifier(AS_OF);
            }
        }
    }

    /**
     * This subclass adds support for EclipseLink specific support.
     */
    protected class IncompleteCollectionExpressionVisitor extends AbstractContentAssistVisitor.IncompleteCollectionExpressionVisitor {

        @Override
        protected List<String> compositeIdentifiersAfter(String clause) {

            // Add support for hierarchical query and AS OF clauses
            if ((clause == FROM) && getEcliseLinkVersion().isNewerThanOrEqual(EclipseLinkVersion.VERSION_2_5)) {
                List<String> identifiers = super.compositeIdentifiersAfter(clause);
                identifiers.add(START_WITH);
                identifiers.add(CONNECT_BY);
                identifiers.add(ORDER_SIBLINGS_BY);
                identifiers.add(AS_OF);
                return identifiers;
            }

            return super.compositeIdentifiersAfter(clause);
        }
    }

    protected class OrderByClauseStatementHelper extends AbstractContentAssistVisitor.OrderByClauseStatementHelper {

        protected OrderByClauseStatementHelper(AbstractContentAssistVisitor visitor) {
            super(visitor);
        }

        @Override
        public UnionClauseStatementHelper getNextHelper() {
            return getUnionClauseStatementHelper();
        }

        @Override
        public boolean hasSpaceAfterClause(SelectStatement expression) {
            return expression.hasSpaceBeforeUnion();
        }
    }

    protected class SimpleFromClauseStatementHelper extends AbstractContentAssistVisitor.SimpleFromClauseStatementHelper {

        protected SimpleFromClauseStatementHelper(AbstractContentAssistVisitor visitor) {
            super(visitor);
        }

        @Override
        public void addInternalClauseProposals(SimpleSelectStatement expression) {
            super.addInternalClauseProposals(expression);

            EclipseLinkContentAssistVisitor.this.addIdentifier(START_WITH);

            if (!hasClausesDefinedBetween(expression, FROM, CONNECT_BY)) {
                EclipseLinkContentAssistVisitor.this.addIdentifier(CONNECT_BY);
            }

            if (!hasClausesDefinedBetween(expression, FROM, ORDER_SIBLINGS_BY)) {
                EclipseLinkContentAssistVisitor.this.addIdentifier(CONNECT_BY);
            }

            if (!hasClausesDefinedBetween(expression, FROM, AS_OF)) {
                EclipseLinkContentAssistVisitor.this.addIdentifier(AS_OF);
            }
        }
    }

    protected class TableExpressionVisitor extends AbstractEclipseLinkExpressionVisitor {

        /**
         * The {@link Expression} being visited.
         */
        protected Expression expression;

        /**
         * <code>true</code> if the {@link Expression} being visited is a {@link TableExpression}.
         */
        protected boolean valid;

        @Override
        public void visit(TableExpression expression) {
            valid = (this.expression == expression);
        }
    }

    protected class UnionClauseStatementHelper implements StatementHelper<SelectStatement> {

        @Override
        public void addClauseProposals() {
            addIdentifier(EXCEPT);
            addIdentifier(INTERSECT);
            addIdentifier(UNION);
        }

        @Override
        public void addInternalClauseProposals(SelectStatement expression) {
        }

        @Override
        public Expression getClause(SelectStatement expression) {
            return expression.getUnionClauses();
        }

        @Override
        public StatementHelper<? extends SelectStatement> getNextHelper() {
            return null;
        }

        @Override
        public boolean hasClause(SelectStatement expression) {
            return expression.hasUnionClauses();
        }

        @Override
        public boolean hasSpaceAfterClause(SelectStatement expression) {
            return false;
        }

        @Override
        public boolean isClauseComplete(SelectStatement expression) {
            return isComplete(expression.getUnionClauses());
        }

        @Override
        public boolean isRequired() {
            return false;
        }
    }
}
