/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 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 from Oracle TopLink
//     05/24/2011-2.3 Guy Pelletier
//       - 345962: Join fetch query when using tenant discriminator column fails.
package org.eclipse.persistence.expressions;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.Serializable;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.QueryException;
import org.eclipse.persistence.history.AsOfClause;
import org.eclipse.persistence.internal.expressions.ArgumentListFunctionExpression;
import org.eclipse.persistence.internal.expressions.BaseExpression;
import org.eclipse.persistence.internal.expressions.CollectionExpression;
import org.eclipse.persistence.internal.expressions.ConstantExpression;
import org.eclipse.persistence.internal.expressions.ExpressionIterator;
import org.eclipse.persistence.internal.expressions.ExpressionJavaPrinter;
import org.eclipse.persistence.internal.expressions.ExpressionNormalizer;
import org.eclipse.persistence.internal.expressions.ExpressionSQLPrinter;
import org.eclipse.persistence.internal.expressions.FunctionExpression;
import org.eclipse.persistence.internal.expressions.LiteralExpression;
import org.eclipse.persistence.internal.expressions.MapEntryExpression;
import org.eclipse.persistence.internal.expressions.ParameterExpression;
import org.eclipse.persistence.internal.expressions.SQLSelectStatement;
import org.eclipse.persistence.internal.expressions.SubSelectExpression;
import org.eclipse.persistence.internal.expressions.TableAliasLookup;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.DatabaseTable;
import org.eclipse.persistence.internal.localization.ToStringLocalization;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.queries.DatabaseQuery;
import org.eclipse.persistence.queries.ReadQuery;
import org.eclipse.persistence.queries.ReportQuery;

/**
 * <p>
 * <b>Purpose</b>: Define an object-level representation of a database query where clause.</p>
 * <p>
 * <b>Description</b>: An expression is a tree-like structure that defines the selection
 * criteria for a query against objects in the database.  The expression has the advantage
 * over SQL by being at the object-level, i.e. the object model attributes and relationships
 * can be used to be query on instead of the database field names.
 * Because it is an object, not a string the expression has the advantage that is can be
 * easily manipulated through code to easily build complex selection criterias.</p>
 * <p>
 * <b>Responsibilities</b>:
 * <ul>
 * <li> Store the selection criteria in a tree-like structure.
 * <li> Support public manipulation protocols for all comparison and function operators.
 * <li> Use operator overloading to support all primitive types as well as objects.
 * </ul>
 */
public abstract class Expression implements Serializable, Cloneable {

    /** Required for serialization compatibility. */
    static final long serialVersionUID = -5979150600092006081L;

    /** Temporary values for table aliasing */
    protected transient DatabaseTable lastTable;
    protected transient DatabaseTable currentAlias;
    protected boolean selectIfOrderedBy = true;
    /** PERF: Cache the hashCode. */
    protected int hashCode = 0;

    /** Use the upper() function for case insensitive expression operations (default).
        Seting this flag to false will use the lower() function instead. */
    public static boolean shouldUseUpperCaseForIgnoreCase = true;

    /**
     * Base Expression Constructor.  Not generally used by Developers
     */
    protected Expression() {
        super();
    }

    /**
     * PUBLIC:
     * Function, return an expression that adds to a date based on
     * the specified datePart.  This is equivalent to the Sybase DATEADD function.
     * <p>Example:
     * <blockquote><pre>
     * EclipseLink: employee.get("date").addDate("year", 2)
     * Java: NA
     * SQL: DATEADD(date, 2, year)
     * </pre></blockquote>
     */
    public Expression addDate(String datePart, int numberToAdd) {
        return addDate(datePart, Integer.valueOf(numberToAdd));
    }

    /**
     * PUBLIC:
     * Function, return an expression that adds to a date based on
     * the specified datePart.  This is equivalent to the Sybase DATEADD function.
     * <p>Example:
     * <blockquote><pre>
     * EclipseLink: employee.get("date").addDate("year", 2)
     * Java: NA
     * SQL: DATEADD(date, 2, year)
     * </pre></blockquote>
     */
    public Expression addDate(String datePart, Object numberToAdd) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.AddDate);
        List args = new ArrayList(2);
        args.add(Expression.fromLiteral(datePart, this));
        args.add(numberToAdd);
        return anOperator.expressionForArguments(this, args);
    }

    /**
     * PUBLIC:
     * Function, to add months to a date.
     */
    public Expression addMonths(int months) {
        return addMonths(Integer.valueOf(months));
    }

    /**
     * PUBLIC:
     * Function, to add months to a date.
     */
    public Expression addMonths(Object months) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.AddMonths);
        return anOperator.expressionFor(this, months);
    }

    /**
     * INTERNAL:
     * Find the alias for a given table
     */
    public DatabaseTable aliasForTable(DatabaseTable table) {
        return null;
    }

    /**
     * PUBLIC: Returns an expression equivalent to all of <code>attributeName</code>
     * holding true for <code>criteria</code>.
     * <p>
     * For every expression with an anyOf, its negation has either an allOf or a
     * noneOf.  The following two examples will illustrate as the second is the
     * negation of the first:
     * <p>
     * AnyOf Example: Employees with a non '613' area code phone number.
     * <blockquote><pre>
     * ReadAllQuery query = new ReadAllQuery(Employee.class);
     * ExpressionBuilder employee = new ExpressionBuilder();
     * Expression exp = employee.anyOf("phoneNumbers").get("areaCode").notEqual("613");
     * </pre></blockquote>
     * <p>
     * AllOf Example: Employees with all '613' area code phone numbers.
     * <blockquote><pre>
     * ExpressionBuilder employee = new ExpressionBuilder();
     * ExpressionBuilder phones = new ExpressionBuilder();
     * Expression exp = employee.allOf("phoneNumbers", phones.get("areaCode").equal("613"));
     * SQL:
     * SELECT ... EMPLOYEE t0 WHERE NOT EXISTS (SELECT ... PHONE t1 WHERE
     *                     (t0.EMP_ID = t1.EMP_ID) AND NOT (t1.AREACODE = '613'))
     * </pre></blockquote>
     * <p>
     * allOf is the universal counterpart to the existential anyOf.  To have the
     * condition evaluated for each instance it must be put inside of a subquery,
     * which can be expressed as not exists (any of attributeName some condition).
     * (All x such that y = !Exist x such that !y).
     * <p>Likewise the syntax employee.allOf("phoneNumbers").get("areaCode").equal("613")
     * is not supported for the <pre>equal</pre> must go inside a subQuery.
     * <p>
     * This method saves you from writing the sub query yourself.  The above is
     * equivalent to the following expression:
     * <blockquote><pre>
     * ExpressionBuilder employee = new ExpressionBuilder();
     * ExpressionBuilder phone = new ExpressionBuilder();
     * ReportQuery subQuery = new ReportQuery(Phone.class, phone);
     * subQuery.retreivePrimaryKeys();
     * subQuery.setSelectionCriteria(phone.equal(employee.anyOf("phoneNumbers").and(
     *         phone.get("areaCode").notEqual("613")));
     * Expression exp = employee.notExists(subQuery);
     * </pre></blockquote>
     * <p>
     * Note if employee has no phone numbers allOf ~ noneOf.
     * @param criteria must have its own builder, as it will become the
     * separate selection criteria of a subQuery.
     * @return a notExists subQuery expression
     */
    public Expression allOf(String attributeName, Expression criteria) {
        ReportQuery subQuery = new ReportQuery();
        subQuery.setShouldRetrieveFirstPrimaryKey(true);
        Expression builder = criteria.getBuilder();
        criteria = builder.equal(anyOf(attributeName)).and(criteria.not());
        subQuery.setSelectionCriteria(criteria);
        return notExists(subQuery);
    }

    /**
     * PUBLIC:
     * Return an expression that is the boolean logical combination of both expressions.
     * This is equivalent to the SQL "AND" operator and the Java {@literal "&&"} operator.
     * <p>Example:
     * <blockquote><pre>
     *  EclipseLink: employee.get("firstName").equal("Bob").and(employee.get("lastName").equal("Smith"))
     *  Java: (employee.getFirstName().equals("Bob")) {@literal &&} (employee.getLastName().equals("Smith"))
     *  SQL: F_NAME = 'Bob' AND L_NAME = 'Smith'
     * </pre></blockquote>
     */
    public Expression and(Expression theExpression) {
        // Allow ands with null.
        if (theExpression == null) {
            return this;
        }

        ExpressionBuilder base = getBuilder();
        Expression expressionToUse = theExpression;

        // Ensure the same builder, unless a parralel query is used.
        // For flashback added an extra condition: if left side is a 'NullExpression'
        // then rebuild on it regardless.
        if ((theExpression.getBuilder() != base) && ((base == this) || (theExpression.getBuilder().getQueryClass() == null))) {
            expressionToUse = theExpression.rebuildOn(base);
        }

        if (base == this) {// Allow and to be sent to the builder.
            return expressionToUse;
        }

        ExpressionOperator anOperator = getOperator(ExpressionOperator.And);
        return anOperator.expressionFor(this, expressionToUse);
    }

    /**
     * PUBLIC:
     * Return an expression representing traversal of a 1:many or many:many relationship.
     * This allows you to query whether any of the "many" side of the relationship satisfies the remaining criteria.
     * <p>Example:
     * </p>
     * <table>
     * <caption>This table compares an example EclipseLink anyOf Expression to Java and SQL</caption>
     * <tr>
     * <th id="c1">Format</th>
     * <th id="c2">Equivalent</th>
     * </tr>
     * <tr>
     * <td headers="c1">EclipseLink</td>
     * <td headers="c2">
     * <pre>
     * ReadAllQuery query = new ReadAllQuery(Employee.class);<br>
     * ExpressionBuilder builder = new ExpressionBuilder();<br>
     * Expression exp = builder.get("id").equal("14858");<br>
     * exp = exp.or(builder.anyOf("managedEmployees").get("firstName").equal("Bob"));<br>
     * </pre>
     * </td>
     * </tr>
     * <tr>
     * <td headers="c1">Java</td>
     * <td headers="c2">No direct equivalent</td>
     * </tr>
     * <tr>
     * <td headers="c1">SQL</td>
     * <td headers="c2">SELECT DISTINCT ... WHERE (t2.MGR_ID (+) = t1.ID) AND (t2.F_NAME = 'Bob')</td>
     * </tr>
     * </table>
     */
    public Expression anyOf(String attributeName) {
        return anyOf(attributeName, true);
    }

    /**
     * ADVANCED:
     * Return an expression representing traversal of a 1:many or many:many relationship.
     * This allows you to query whether any of the "many" side of the relationship satisfies the remaining criteria.
     * <p>Example:
     * </p>
     * <table>
     * <caption>This table compares an example EclipseLink anyOf Expression to Java and SQL</caption>
     * <tr>
     * <th id="c3">Format</th>
     * <th id="c4">Equivalent</th>
     * </tr>
     * <tr>
     * <td headers="c3">EclipseLink</td>
     * <td headers="c4">
     * <pre>
     * ReadAllQuery query = new ReadAllQuery(Employee.class);<br>
     * ExpressionBuilder builder = new ExpressionBuilder();<br>
     * Expression exp = builder.get("id").equal("14858");<br>
     * exp = exp.or(builder.anyOf("managedEmployees").get("firstName").equal("Bob"));<br>
     * </pre>
     * </td>
     * </tr>
     * <tr>
     * <td headers="c3">Java</td>
     * <td headers="c4">No direct equivalent</td>
     * </tr>
     * <tr>
     * <td headers="c3">SQL</td>
     * <td headers="c4">SELECT DISTINCT ... WHERE (t2.MGR_ID (+) = t1.ID) AND (t2.F_NAME = 'Bob')</td>
     * </tr>
     * </table>
     * @param shouldJoinBeIndependent indicates whether a new expression should be created.
     */
    public Expression anyOf(String attributeName, boolean shouldJoinBeIndependent) {
        throw new UnsupportedOperationException("anyOf");
    }

    /**
     * ADVANCED:
     * Return an expression representing traversal of a 1:many or many:many relationship.
     * This allows you to query whether any of the "many" side of the relationship satisfies the remaining criteria.
     * This version of the anyOf operation performs an outer join.
     * Outer joins allow the join to performed even if the target of the relationship is empty.
     * NOTE: outer joins are not supported on all database and have differing semantics.
     * <p>Example:
     * </p>
     * <table>
     * <caption>This table compares an example EclipseLink anyOfAllowingNone Expression to Java and SQL</caption>
     * <tr>
     * <th id="c5">Format</th>
     * <th id="c6">Equivalent</th>
     * </tr>
     * <tr>
     * <td headers="c5">EclipseLink</td>
     * <td headers="c6">
     * <pre>
     * ReadAllQuery query = new ReadAllQuery(Employee.class);<br>
     * ExpressionBuilder builder = new ExpressionBuilder();<br>
     * Expression exp = builder.get("id").equal("14858");<br>
     * exp = exp.or(builder.anyOfAllowingNone("managedEmployees").get("firstName").equal("Bob"));<br>
     * </pre>
     * </td>
     * </tr>
     * <tr>
     * <td headers="c5">Java</td>
     * <td headers="c6">No direct equivalent</td>
     * </tr>
     * <tr>
     * <td headers="c5">SQL</td>
     * <td headers="c6">SELECT DISTINCT ... WHERE (t2.MGR_ID (+) = t1.ID) AND (t2.F_NAME = 'Bob')</td>
     * </tr>
     * </table>
     */
    public Expression anyOfAllowingNone(String attributeName) {
        return anyOfAllowingNone(attributeName, true);
    }

    /**
     * ADVANCED:
     * Return an expression representing traversal of a 1:many or many:many relationship.
     * This allows you to query whether any of the "many" side of the relationship satisfies the remaining criteria.
     * This version of the anyOf operation performs an outer join.
     * Outer joins allow the join to performed even if the target of the relationship is empty.
     * NOTE: outer joins are not supported on all database and have differing semantics.
     * <p>Example:
     * </p>
     * <table>
     * <caption>This table compares an example EclipseLink anyOfAllowingNone Expression to Java and SQL</caption>
     * <tr>
     * <th id="c7">Format</th>
     * <th id="c8">Equivalent</th>
     * </tr>
     * <tr>
     * <td headers="c7">EclipseLink</td>
     * <td headers="c8">
     * <pre>
     * ReadAllQuery query = new ReadAllQuery(Employee.class);<br>
     * ExpressionBuilder builder = new ExpressionBuilder();<br>
     * Expression exp = builder.get("id").equal("14858");<br>
     * exp = exp.or(builder.anyOfAllowingNone("managedEmployees").get("firstName").equal("Bob"));<br>
     * </pre>
     * </td>
     * </tr>
     * <tr>
     * <td headers="c7">Java</td>
     * <td headers="c8">No direct equivalent</td>
     * </tr>
     * <tr>
     * <td headers="c7">SQL</td>
     * <td headers="c8">SELECT DISTINCT ... WHERE (t2.MGR_ID (+) = t1.ID) AND (t2.F_NAME = 'Bob')</td>
     * </tr>
     * </table>
     * @param shouldJoinBeIndependent indicates whether a new expression should be created.
     */
    public Expression anyOfAllowingNone(String attributeName, boolean shouldJoinBeIndependent) {
        throw new UnsupportedOperationException("anyOfAllowingNone");
    }

    /**
     * ADVANCED:
     * Assign an alias to the expression in the select clause.
     */
    public Expression as(String alias) {
        ExpressionOperator operator = getOperator(ExpressionOperator.As);
        return operator.expressionFor(this, literal(alias));
    }

    /**
     * ADVANCED:
     * Return an expression that allows you to treat its base as if it were a subclass of the class returned by the base
     * This can only be called on an ExpressionBuilder, the result of expression.get(String), expression.getAllowingNull(String),
     * the result of expression.anyOf("String") or the result of expression.anyOfAllowingNull("String")
     *
     *  downcast uses Expression.type() internally to guarantee the results are of the specified class.
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.get("project").treat(LargeProject.class).get("budget").equal(1000)
     *     Java: ((LargeProject)employee.getProjects().get(0)).getBudget() == 1000
     *     SQL: LPROJ.PROJ_ID (+)= PROJ.PROJ_ID AND L_PROJ.BUDGET = 1000 AND PROJ.TYPE = "L"
     * </pre></blockquote>
     */
    public Expression treat(Class castClass) {
        return this;
    }

    /**
     * PUBLIC:
     * This can only be used within an ordering expression.
     * It will order the result ascending.
     * Example:
     * <blockquote><pre>
     *  readAllQuery.addOrderBy(expBuilder.get("address").get("city").ascending())
     * </pre></blockquote>
     */
    public Expression ascending() {
        return getFunction(ExpressionOperator.Ascending);
    }

    /**
     * PUBLIC:
     * This can only be used within an ordering expression.
     * Null results will be ordered first.
     * Example:
     * <blockquote><pre>
     *  readAllQuery.addOrderBy(expBuilder.get("address").get("city").ascending().nullsFirst())
     * </pre></blockquote>
     */
    public Expression nullsFirst() {
        return getFunction(ExpressionOperator.NullsFirst);
    }

    /**
     * PUBLIC:
     * This can only be used within an ordering expression.
     * Null results will be ordered last.
     * Example:
     * <blockquote><pre>
     *  readAllQuery.addOrderBy(expBuilder.get("address").get("city").ascending().nullsLast())
     * </pre></blockquote>
     */
    public Expression nullsLast() {
        return getFunction(ExpressionOperator.NullsLast);
    }

    /**
     * PUBLIC:
     * Function, returns the single character strings ascii value.
     */
    public Expression asciiValue() {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Ascii);
        return anOperator.expressionFor(this);
    }

    /**
     * Sets all tables represented by this expression to be queried as of a past
     * time.
     * <p>
     * Example:
     * </p>
     * <pre>
     *  EclipseLink: employee.asOf(new AsOfClause(pastTime))
     *  Java: None
     *  SQL (Flashback): SELECT ... FROM EMPLOYEE AS OF TIMESTAMP (pastTime) t0 ...
     *  SQL (Generic): .. WHERE (t1.START {@literal <=} pastTime) AND ((t1.END IS NULL) OR t1.END {@literal >} pastTime)
     * </pre>
     * <p>
     * Set an as of clause at the expression level to still query for current objects
     * while expressing selection criteria like:
     * <ul>
     * <li>query objects as of one time that met some condition at another time.
     * <li>query objects that changed a certain way over a certain interval (querying for change).
     * </ul>
     * <p>
     * Simultaneously querying on two versions of the same object (one past
     * one present) lets you express these advanced selection criteria.
     * <p>
     * Example: Querying on past attributes using parallel expressions.
     * </p>
     * <blockquote><pre>
     *   // Finds all employees who lived in Ottawa as of a past time.
     *   ExpressionBuilder employee = new ExpressionBuilder();
     *   ExpressionBuilder pastEmployee = new ExpressionBuilder(Employee.class);
     *   pastEmployee.asOf(pastTime);
     *   Expression pastAddress = pastEmployee.get("address"); // by default address will also be as of past time.
     *   Expression selectionCriteria = pastAddress.get("city").equal("Ottawa").and(
     *       employee.equal(pastEmployee));
     * </pre></blockquote>
     * <p>
     * The advantage of the parallel expression is that you can still read current
     * objects, the as of clause will affect only the where clause / selection criteria.
     * <p>
     * You may be tempted to rewrite the above as employee.get("address").asOf(pastTime).
     * That is allowed but see below for the finer points involved in this.
     * <p>
     * Example: Querying on object changes using parallel expressions.
     * </p>
     * <blockquote><pre>
     *   // Finds all employees who recently received a raise.  Note that current
     *   // objects are returned, so can be cached normally.
     *   ExpressionBuilder employee = new ExpressionBuilder();
     *   Expression pastEmployee = new ExpressionBuilder(Employee.class);
     *   pastEmployee.asOf(yesterday);
     *   Expression parallelJoin = employee.equal(pastEmployee);
     *   Expression selectionCriteria = parallelJoin.and(
     *       employee.get("salary").greaterThan(pastEmployee.get("salary")));
     * </pre></blockquote>
     * <p>
     * Example: Querying on object changes using custom query keys
     * </p><blockquote><pre>
     *   // First define the custom query key and add it to your descriptor.
     *   ExpressionBuilder builder = new ExpressionBuilder(Employee.class);
     *   Expression joinCriteria = builder.getField("EMPLOYEE.EMP_ID").equal(builder.getParameter("EMPLOYEE.EMP_ID"));
     *   OneToOneQueryKey selfReferential = new OneToOneQueryKey();
     *   selfReferential.setName("this");
     *   selfReferential.setJoinCriteria(joinCriteria);
     *   selfReferential.setReferenceClass(Employee.class);
     *   getSession().getDescriptor(Employee.class).addQueryKey(selfReferential);
     *
     *   // Now build query as before.
     *   Expression employee = new ExpessionBuilder();
     *   Expression pastEmployee = employee.get("this").asOf(yesterday);
     *   Expression selectionCriteria = employee.get("salary").greaterThan(pastEmployee.get("salary"));
     * </pre></blockquote>
     * <p>
     * Note in general that any parallel expression can be rewritten using a custom query key.
     * EclipseLink will even automatically interpret x.get("this") for you so you do
     * not need to define the above query key first.
     * <p>
     * <b>Full Reference:</b>
     * <p>
     * If an object is mapped to multiple tables, then each table will be as of
     * the same time.  Two objects mapped to the same table can not have different
     * as of times.  Conversely only expressions which have associated tables can have an as
     * of clause.
     * <p>
     * If an as of clause is not explicitly set an expression will use the clause
     * of its base expression, and so on recursively until one is found or an
     * ExpressionBuilder is reached.  Some usage scenarios follow:
     * <ul>
     * <li>employee.asOf(pastTime).anyOf("projects"): projects as of past time.
     * <li>expressionBuilder.asOf(pastTime): entire expression as of past time.
     * <li>employee.asOf(pastTime).anyOf("projects").asOf(null): projects as of current time.
     * <li>employee.anyOf("projects").asOf(pastTime): projects only as of past time.
     * </ul>
     * <p>
     * Watch out for x.asOf(oneTime).get("y").asOf(anotherTime).
     * <ul>
     * <li>emp.anyOf("phoneNumbers").asOf(yesterday) = emp.asOf(yesterday).anyOf("phoneNumbers") but:
     * <li>emp.get("address").asOf(yesterday) != emp.asOf(yesterday).get("address").
     * </ul>
     * Whether the join is also as of yesterday depends on which table the foreign
     * key field resides on.  In an anyOf the foreign key is always on the right, but
     * in a get (1-1) it could be on either side.  For this
     * reason employee.get("address").asOf(yesterday) is undefined as it can mean
     * either 'my address as of yesterday', or 'my address, as of yesterday.'
     * @param pastTime A read only data object used to represent a past time.
     * @return <code>this</code>
     * @since OracleAS EclipseLink 10<i>g</i> (10.0.3)
     * @see org.eclipse.persistence.history.AsOfClause
     * @see #hasAsOfClause
     * @see org.eclipse.persistence.sessions.Session#acquireHistoricalSession(org.eclipse.persistence.history.AsOfClause)
     * @see org.eclipse.persistence.queries.ObjectLevelReadQuery#setAsOfClause(org.eclipse.persistence.history.AsOfClause)
     */
    public Expression asOf(AsOfClause pastTime) {
        throw new UnsupportedOperationException("anyOfAllowingNone");
    }

    /**
     * INTERNAL:
     * Alias a particular table within this node
     */
    protected void assignAlias(String name, DatabaseTable tableOrExpression) {
        // By default, do nothing.
    }

    /**
     * INTERNAL:
     * Assign aliases to any tables which I own. Start with t(initialValue),
     * and return the new value of  the counter , i.e. if initialValue is one
     * and I have tables ADDRESS and EMPLOYEE I will assign them t1 and t2 respectively, and return 3.
     */
    public int assignTableAliasesStartingAt(int initialValue) {
        if (hasBeenAliased()) {
            return initialValue;
        }
        int counter = initialValue;
        List<DatabaseTable> ownedTables = getOwnedTables();
        if (ownedTables != null) {
            for (DatabaseTable table : ownedTables) {
                assignAlias("t" + counter, table);
                counter++;
            }
        }
        return counter;
    }

    /**
     * PUBLIC:
     * Function, This represents the aggregate function Average. Can be used only within Report Queries.
     */
    public Expression average() {
        return getFunction(ExpressionOperator.Average);
    }

    /**
     * PUBLIC:
     * Function, between two bytes
     */
    public Expression between(byte leftValue, byte rightValue) {
        return between(Byte.valueOf(leftValue), Byte.valueOf(rightValue));
    }

    /**
     * PUBLIC:
     * Function, between two chars
     */
    public Expression between(char leftChar, char rightChar) {
        return between(Character.valueOf(leftChar), Character.valueOf(rightChar));
    }

    /**
     * PUBLIC:
     * Function, between two doubles
     */
    public Expression between(double leftValue, double rightValue) {
        return between(Double.valueOf(leftValue), Double.valueOf(rightValue));
    }

    /**
     * PUBLIC:
     * Function, between two floats
     */
    public Expression between(float leftValue, float rightValue) {
        return between(Float.valueOf(leftValue), Float.valueOf(rightValue));
    }

    /**
     * PUBLIC:
     * Function, between two ints
     */
    public Expression between(int leftValue, int rightValue) {
        return between(Integer.valueOf(leftValue), Integer.valueOf(rightValue));
    }

    /**
     * PUBLIC:
     * Function, between two longs
     */
    public Expression between(long leftValue, long rightValue) {
        return between(Long.valueOf(leftValue), Long.valueOf(rightValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receiver's value is between two other values.
     * This means the receiver's value is greater than or equal to the leftValue argument and less than or equal to the
     * rightValue argument.
     * <p>
     * This is equivalent to the SQL "BETWEEN AND" operator and Java {@literal ">=", "<=;"} operators.
     * <p>Example:
     * <pre>
     *     EclipseLink: employee.get("age").between(19,50)
     *     Java: (employee.getAge() {@literal >=} 19) {@literal &&} (employee.getAge() {@literal <=} 50)
     *     SQL: AGE BETWEEN 19 AND 50
     * </pre>
     */
    public Expression between(Object leftValue, Object rightValue) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Between);
        List args = new ArrayList(2);
        args.add(leftValue);
        args.add(rightValue);
        return anOperator.expressionForArguments(this, args);
    }

    public Expression between(Expression leftExpression, Expression rightExpression) {
        return between(leftExpression, (Object)rightExpression);

    }

    /**
     * PUBLIC:
     * Function, between two shorts
     */
    public Expression between(short leftValue, short rightValue) {
        return between(Short.valueOf(leftValue), Short.valueOf(rightValue));
    }

    /**
     * PUBLIC:
     * Function Convert values returned by the query to values
     * given in the caseItems Map.  The equivalent of
     * the Oracle CASE function
     * <p>Example:
     * <blockquote><pre>
     * Map caseTable = new HashMap();
     * caseTable.put("Robert", "Bob");
     * caseTable.put("Susan", "Sue");
     *
     * EclipseLink: employee.get("name").caseStatement(caseTable, "No-Nickname")
     * Java: NA
     * SQL: CASE name WHEN "Robert" THEN "Bob"
     *     WHEN "Susan" THEN "Sue"
     *  ELSE "No-Nickname"
     * </pre></blockquote>
     * @param caseItems java.util.Map
     * A Map containing the items to be processed.
     * Keys represent the items to match coming from the query.
     * Values represent what a key will be changed to.
     * @param defaultItem java.lang.String  the default value that will be used if none of the keys in the
     * hashtable match
     */
    public Expression caseStatement(Map caseItems, Object defaultItem) {
        FunctionExpression expression = caseStatement();
        expression.addChild(this);
        Iterator iterator = caseItems.keySet().iterator();
        while (iterator.hasNext()) {
            Object key = iterator.next();
            expression.addChild(Expression.from(key, this));
            expression.addChild(Expression.from(caseItems.get(key), this));
        }
        expression.addChild(Expression.from(defaultItem, this));
        return expression;
    }

    /**
     * INTERNAL:
     * Creates an ArgumentListFunctionExpression that is capable of creating a case statement of the form:
     * <blockquote><pre>
     * SQL: CASE name WHEN "Robert" THEN "Bob"
     *     WHEN "Susan" THEN "Sue"
     *  ELSE "No-Nickname"
     * </pre></blockquote>
     *
     * This expression must be manipulated to successfully build a case statement by adding appropriate
     * children to it.
     *
     * A child must be added for the "case expression" (name above), a pair of children must be added for
     * each "when then" expression and a child must be added for the else.
     *
     * @see ArgumentListFunctionExpression
     */
    public ArgumentListFunctionExpression caseStatement() {

        ListExpressionOperator caseOperator = (ListExpressionOperator)getOperator(ExpressionOperator.Case);
        ListExpressionOperator clonedCaseOperator = new ListExpressionOperator();
        caseOperator.copyTo(clonedCaseOperator);

        ArgumentListFunctionExpression expression = new ArgumentListFunctionExpression();
        expression.setBaseExpression(this);

        expression.setOperator(clonedCaseOperator);
        return expression;
    }

    /**
     * PUBLIC:
     * Function Convert values returned by the query to values
     * given in the caseConditions Map.  The equivalent of
     * the SQL CASE function
     * <p>Example:
     * <blockquote><pre>
     * Map caseTable = new HashMap();
     * caseTable.put(employee.get("name").equals("Robert"), "Bob");
     * caseTable.put(employee.get("name").equals("Susan"), "Sue");
     *
     * EclipseLink: expressionBuilder.caseConditionStatement(caseTable, "No-Nickname")
     * Java: NA
     * SQL: CASE WHEN name = "Robert" THEN "Bob"
     *     WHEN name = "Susan" THEN "Sue"
     *  ELSE "No-Nickname"
     * </pre></blockquote>
     * @param caseConditions java.util.Map
     * A Map containing the items to be processed.
     * Keys represent the items to match coming from the query.
     * Values represent what a key will be changed to.
     * @param defaultItem java.lang.Object  the default value that will be used if none of the keys in the
     * Map match
     */
    public Expression caseConditionStatement(Map<Expression, Object> caseConditions, Object defaultItem) {
        FunctionExpression expression = caseConditionStatement();
        Iterator<Expression> iterator = caseConditions.keySet().iterator();
        if (iterator.hasNext()){
            Expression key = iterator.next();
            expression.addChild(key);
            expression.setBaseExpression(key);//base needs to be the same as the first child for reportQuery items.
            expression.addChild(Expression.from(caseConditions.get(key), this));

            while (iterator.hasNext()) {
                key = iterator.next();
                expression.addChild(key);
                expression.addChild(Expression.from(caseConditions.get(key), this));
            }
        }
        expression.addChild(Expression.from(defaultItem, this));
        return expression;
    }

    /**
     * INTERNAL:
     * Creates an ArgumentListFunctionExpression that is capable of creating a case statement of the form:
     * <blockquote><pre>
     * SQL: CASE WHEN name = "Robert" THEN "Bob"
     *     WHEN name = "Susan" THEN "Sue"
     *  ELSE "No-Nickname"
     * </pre></blockquote>
     *
     * This expression must be manipulated to successfully build a case statement by adding appropriate
     * children to it.
     *
     * A pair of children must be added for  each "when then" expression and a child must be added for the else.
     *
     * @see ArgumentListFunctionExpression
     */
    public ArgumentListFunctionExpression caseConditionStatement() {
        ListExpressionOperator caseOperator = (ListExpressionOperator)getOperator(ExpressionOperator.CaseCondition);
        ListExpressionOperator clonedCaseOperator = new ListExpressionOperator();
        caseOperator.copyTo(clonedCaseOperator);

        ArgumentListFunctionExpression expression = new ArgumentListFunctionExpression();
        expression.setBaseExpression(this);

        expression.setOperator(clonedCaseOperator);
        return expression;
    }

    /**
     * PUBLIC:
     * Function Test if arguments are equal, returning null if they are and the value of the
     * first expression otherwise.
     * <p>Example:
     * <blockquote><pre>
     * EclipseLink: builder.get("name").nullIf( "Bobby")
     * Java: NA
     * SQL: NULLIF(name, "Bobby")
     * </pre></blockquote>
     * @param object java.lang.Object the value/expression that will be compared to the base expression
     */
    public Expression nullIf(Object object) {
            ExpressionOperator anOperator = getOperator(ExpressionOperator.NullIf);
            List args = new ArrayList(1);
            args.add(Expression.from(object, this));
            return anOperator.expressionForArguments(this, args);
    }

    /**
     * PUBLIC:
     * Function Return null if all arguments are null and the first non-null argument otherwise
     * The equivalent of the COALESCE SQL function
     * <p>Example:
     * <blockquote><pre>
     * List list = new ArrayList(3);
     * list.add(builder.get("firstName"));
     * list.add(builder.get("lastName"));
     * list.add(builder.get("nickname"));
     *
     * EclipseLink: expressionBuilder.coalesce(caseTable)
     * Java: NA
     * SQL: COALESCE(firstname, lastname, nickname)
     * </pre></blockquote>
     * @param expressions java.util.Collection
     * A Collection containing the items to check if null
     */
    public ArgumentListFunctionExpression coalesce(Collection expressions) {
        ArgumentListFunctionExpression expression = coalesce();
        Iterator iterator = expressions.iterator();
        if (iterator.hasNext()){
            Expression base = Expression.from(iterator.next(), this);
            expression.addChild(base);
            expression.setBaseExpression(base);//base needs to be the same as the first child for reportQuery items.
            while (iterator.hasNext()) {
                expression.addChild(Expression.from(iterator.next(), this));
            }
        }
        return expression;
    }

    public ArgumentListFunctionExpression coalesce() {
        ListExpressionOperator coalesceOperator = (ListExpressionOperator)getOperator(ExpressionOperator.Coalesce);
        ListExpressionOperator clonedCoalesceOperator = new ListExpressionOperator();
        coalesceOperator.copyTo(clonedCoalesceOperator);

        ArgumentListFunctionExpression expression = new ArgumentListFunctionExpression();
        expression.setBaseExpression(this);

        expression.setOperator(clonedCoalesceOperator);
        return expression;
    }

    /**
     * INTERNAL:
     * Clone the expression maintaining clone identity in the inter-connected expression graph.
     */
    @Override
    public Object clone() {
        // 2612538 - the default size of Map (32) is appropriate
        Map alreadyDone = new IdentityHashMap();
        return copiedVersionFrom(alreadyDone);
    }

    /**
     * INTERNAL:
     * This expression is built on a different base than the one we want. Rebuild it and
     * return the root of the new tree.
     * This method will rebuildOn the receiver even it is a parallel select or a
     * sub select: it will not replace every base with newBase.
     * Also it will rebuild using anyOf as appropriate not get.
     * @see org.eclipse.persistence.mappings.ForeignReferenceMapping#batchedValueFromRow
     * @see #rebuildOn(Expression)
     */
    public Expression cloneUsing(Expression newBase) {
        // 2637484 INVALID QUERY KEY EXCEPTION THROWN USING BATCH READS AND PARALLEL EXPRESSIONS
        // 2612567 CR4298- NULLPOINTEREXCEPTION WHEN USING SUBQUERY AND BATCH READING IN 4.6
        // 2612140 CR2973- BATCHATTRIBUTE QUERIES WILL FAIL WHEN THE INITIAL QUERY HAS A SUBQUERY
        // 2720149 INVALID SQL WHEN USING BATCH READS AND MULTIPLE ANYOFS
        // 2612538 - the default size of Map (32) is appropriate
        Map alreadyDone = new IdentityHashMap();

        // cloneUsing is identical to cloning save that the primary builder
        // will be replaced not with its clone but with newBase.
        // ExpressionBuilder.registerIn() will check for this newBase with
        // alreadyDone.get(alreadyDone);
        // copiedVersionFrom() must be called on the primary builder before
        // other builders.
        alreadyDone.put(alreadyDone, newBase);
        return copiedVersionFrom(alreadyDone);
    }

    /**
     * PUBLIC:
     * Function, returns the concatenation of the two string values.
     */
    public Expression concat(Object left) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Concat);
        return anOperator.expressionFor(this, left);
    }

    /**
     * PUBLIC:
     * Return an expression that performs a key word search.
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: project.get("description").containsAllKeyWords("EclipseLink rdbms java")
     * </pre></blockquote>
     */
    public Expression containsAllKeyWords(String spaceSeparatedKeyWords) {
        StringTokenizer tokenizer = new StringTokenizer(spaceSeparatedKeyWords);
        Expression expression = null;
        while (tokenizer.hasMoreTokens()) {
            String token = tokenizer.nextToken();
            if (expression == null) {
                expression = containsSubstringIgnoringCase(token);
            } else {
                expression = expression.and(containsSubstringIgnoringCase(token));
            }
        }

        if (expression == null) {
            return like("%");
        } else {
            return expression;
        }
    }

    /**
     * PUBLIC:
     * Return an expression that performs a key word search.
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: project.get("description").containsAllKeyWords("EclipseLink rdbms java")
     * </pre></blockquote>
     */
    public Expression containsAnyKeyWords(String spaceSeparatedKeyWords) {
        StringTokenizer tokenizer = new StringTokenizer(spaceSeparatedKeyWords);
        Expression expression = null;
        while (tokenizer.hasMoreTokens()) {
            String token = tokenizer.nextToken();
            if (expression == null) {
                expression = containsSubstringIgnoringCase(token);
            } else {
                expression = expression.or(containsSubstringIgnoringCase(token));
            }
        }

        if (expression == null) {
            return like("%");
        } else {
            return expression;
        }
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value contains the substring.
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.get("firstName").containsSubstring("Bob")
     *     Java: employee.getFirstName().indexOf("Bob") != -1
     *     SQL: F_NAME LIKE '%BOB%'
     * </pre></blockquote>
     */
    public Expression containsSubstring(String theValue) {
        return like("%" + theValue + "%");
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value contains the substring.
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.get("firstName").containsSubstring("Bob")
     *     Java: employee.getFirstName().indexOf("Bob") != -1
     *     SQL: F_NAME LIKE '%BOB%'
     * </pre></blockquote>
     */
    public Expression containsSubstring(Expression expression) {
        return like((value("%").concat(expression)).concat("%"));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value contains the substring, ignoring case.
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.get("firstName").containsSubstringIgnoringCase("Bob")
     *     Java: employee.getFirstName().toUpperCase().indexOf("BOB") != -1
     *     SQL: UPPER(F_NAME) LIKE '%BOB%'
     * </pre></blockquote>
     */
    public Expression containsSubstringIgnoringCase(String theValue) {
        if (shouldUseUpperCaseForIgnoreCase) {
            return toUpperCase().containsSubstring(theValue.toUpperCase());
        } else {
            return toLowerCase().containsSubstring(theValue.toLowerCase());
        }
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value contains the substring, ignoring case.
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.get("firstName").containsSubstringIgnoringCase("Bob")
     *     Java: employee.getFirstName().toUpperCase().indexOf("BOB") != -1
     *     SQL: UPPER(F_NAME) LIKE '%BOB%'
     * </pre></blockquote>
     */
    public Expression containsSubstringIgnoringCase(Expression expression) {
        if (shouldUseUpperCaseForIgnoreCase) {
            return toUpperCase().containsSubstring(expression.toUpperCase());
        } else {
            return toLowerCase().containsSubstring(expression.toLowerCase());
        }
    }

    /*
     * Modify this individual expression node to use outer joins wherever there are
     * equality operations between two field nodes.
     */
    protected void convertNodeToUseOuterJoin() {
    }

    /**
     * INTERNAL:
     * Modify this expression to use outer joins wherever there are
     * equality operations between two field nodes.
     */
    public Expression convertToUseOuterJoin() {
        ExpressionIterator iterator = new ExpressionIterator() {
            @Override
            public void iterate(Expression each) {
                each.convertNodeToUseOuterJoin();
            }
        };
        iterator.iterateOn(this);
        return this;
    }

    /**
     * INTERNAL:
     */
    public Expression copiedVersionFrom(Map alreadyDone) {
        if (alreadyDone == null) {
            // For sub-selects no cloning is done.
            return this;
        }
        Expression existing = (Expression)alreadyDone.get(this);
        if (existing == null) {
            return registerIn(alreadyDone);
        } else {
            return existing;
        }
    }

    /**
     * PUBLIC:
     * This represents the aggregate function Average. Can be used only within Report Queries.
     */
    public Expression count() {
        return getFunction(ExpressionOperator.Count);
    }

    /**
     * INTERNAL:
     */
    public Expression create(Expression base, Object singleArgument, ExpressionOperator anOperator) {
        // This is a replacement for real class methods in Java. Instead of returning a new instance we create it, then
        // mutate it using this method.
        return this;
    }

    /**
     * INTERNAL:
     */
    public Expression createWithBaseLast(Expression base, Object singleArgument, ExpressionOperator anOperator) {
        // This is a replacement for real class methods in Java. Instead of returning a new instance we create it, then
        // mutate it using this method.
        return this;
    }

    /**
     * INTERNAL:
     */
    public Expression create(Expression base, List arguments, ExpressionOperator anOperator) {
        // This is a replacement for real class methods in Java. Instead of returning a new instance we create it, then
        // mutate it using this method.
        return this;
    }

    /**
     * PUBLIC:
     * This gives access to the current timestamp on the database through expression.
     * Please note, this method is added for consistency and returns the same
     * result as currentDate.
     */
    public Expression currentTimeStamp() {
        return currentDate();
    }

    /**
     * PUBLIC:
     * This gives access to the current date on the database through expression.
     */
    public Expression currentDate() {
        return getFunction(ExpressionOperator.Today);
    }

   /**
    * PUBLIC:
    * This gives access to the current date only on the database through expression.
    * Note the difference between currentDate() and this method. This method does
    * not return the time portion of current date where as currentDate() does.
    */
   public Expression currentDateDate() {
       return getFunction(ExpressionOperator.CurrentDate);
   }

   /**
    * PUBLIC:
    * This gives access to the current time only on the database through expression.
    * Note the difference between currentDate() and this method. This method does
    * not return the date portion where as currentDate() does.
    */
   public Expression currentTime() {
       return getFunction(ExpressionOperator.CurrentTime);
   }

    /**
     * PUBLIC:
     * Function, Return the difference between the queried part of a date(i.e. years, days etc.)
     * and same part of the given date. The equivalent of the Sybase function DateDiff
     * <p>Example:
     * <blockquote><pre>
     * EclipseLink: employee.get("date").dateDifference("year", new Date(System.currentTimeMillis()))
     * Java: NA
     * SQL: DATEADD(date, 2, GETDATE)
     * </pre></blockquote>
     */
    public Expression dateDifference(String datePart, java.util.Date date) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.DateDifference);
        FunctionExpression expression = new FunctionExpression();
        expression.setBaseExpression(this);
        expression.addChild(Expression.fromLiteral(datePart, this));
        expression.addChild(Expression.from(date, this));
        expression.addChild(this);
        expression.setOperator(anOperator);
        return expression;
    }

    /**
     * PUBLIC:
     * Function, Return the difference between the queried part of a date(i.e. years, days etc.)
     * and same part of the given date. The equivalent of the Sybase function DateDiff
     * <p>Example:
     * <blockquote><pre>
     * EclipseLink: employee.get("date").dateDifference("year", new Date(System.currentTimeMillis()))
     * Java: NA
     * SQL: DATEADD(date, 2, GETDATE)
     * </pre></blockquote>
     */
    public Expression dateDifference(String datePart, Expression comparisonExpression) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.DateDifference);
        FunctionExpression expression = new FunctionExpression();
        expression.setBaseExpression(this);
        expression.addChild(Expression.fromLiteral(datePart, this));
        expression.addChild(comparisonExpression);
        expression.addChild(this);
        expression.setOperator(anOperator);
        return expression;
    }

    /**
     * PUBLIC:
     * return a string that represents the given part of a date. The equivalent
     * of the Sybase DATENAME function
     * <p>Example:
     * <blockquote><pre>
     * EclipseLink: employee.get("date").dateName("year")
     * Java: new String(date.getYear())
     * SQL: DATENAME(date, year)
     * </pre></blockquote>
     */
    public Expression dateName(String datePart) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.DateName);
        FunctionExpression expression = new FunctionExpression();
        expression.setBaseExpression(this);
        expression.addChild(Expression.fromLiteral(datePart, this));
        expression.addChild(this);
        expression.setOperator(anOperator);
        return expression;
    }

    /**
     * PUBLIC:
     * Function return an integer which represents the requested
     * part of the date.  Equivalent of the Sybase function DATEPART
     * <p>Example:
     * <blockquote><pre>
     * EclipseLink: employee.get("date").datePart("year")
     * Java: date.getYear()
     * SQL: DATEPART(date, year)
     * </pre></blockquote>
     */
    public Expression datePart(String datePart) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.DatePart);
        FunctionExpression expression = new FunctionExpression();
        expression.setBaseExpression(this);
        expression.addChild(Expression.fromLiteral(datePart, this));
        expression.addChild(this);
        expression.setOperator(anOperator);
        return expression;
    }

    /**
     * PUBLIC:
     * Function, returns the date converted to the string value in the default database format.
     */
    public Expression dateToString() {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.DateToString);
        return anOperator.expressionFor(this);
    }

    /**
     * PUBLIC:
     * Function Convert values returned by the query to values given in the decodeableItems Map.
     * The equivalent of the Oracle DECODE function.
     * Note: This will only work on databases that support Decode with the syntax below.
     * <p>Example:
     * <blockquote><pre>
     * Map decodeTable = new HashMap();
     * decodeTable.put("Robert", "Bob");
     * decodeTable.put("Susan", "Sue");
     *
     * EclipseLink: employee.get("name").Decode(decodeTable, "No-Nickname")
     * Java: NA
     * SQL: DECODE(name, "Robert", "Bob", "Susan", "Sue", "No-Nickname")
     * </pre></blockquote>
     * @param decodeableItems java.util.Map
     *   a Map containing the items to be decoded.  Keys represent
     * the items to match coming from the query.  Values represent what
     * a key will be changed to.
     * @param defaultItem
     *  the default value that will be used if none of the keys in the
     * Map match
     **/
    public Expression decode(Map decodeableItems, String defaultItem) {

        /**
         * decode works differently than most of the functionality in the expression framework.
         * It takes a variable number of arguments and as a result, the printed strings for
         * a decode call have to be built when the number of arguments are known.
         * As a result, we do not look up decode in the ExpressionOperator.  Instead we build
         * the whole operator here.  The side effect of this is that decode will not thrown
         * an invalid operator exception for any platform.  (Even the ones that do not support
         * decode)
         */
        ExpressionOperator anOperator = new ExpressionOperator();
        anOperator.setSelector(ExpressionOperator.Decode);
        anOperator.setName("DECODE");
        anOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        anOperator.setType(ExpressionOperator.FunctionOperator);
        anOperator.bePrefix();

        List<String> v = new ArrayList<>(decodeableItems.size() + 1);
        v.add("DECODE(");
        for (int i = 0; i < ((decodeableItems.size() * 2) + 1); i++) {
            v.add(", ");
        }
        v.add(")");
        anOperator.printsAs(v);

        FunctionExpression expression = new FunctionExpression();
        expression.setBaseExpression(this);
        expression.addChild(this);
        Iterator iterator = decodeableItems.keySet().iterator();
        while (iterator.hasNext()) {
            Object key = iterator.next();
            expression.addChild(Expression.from(key, this));
            expression.addChild(Expression.from(decodeableItems.get(key), this));
        }
        expression.addChild(Expression.from(defaultItem, this));
        expression.setOperator(anOperator);
        return expression;
    }

    /**
     * PUBLIC:
     * This can only be used within an ordering expression.
     * It will order the result descending.
     * <p>Example:
     * <blockquote><pre>
     * readAllQuery.addOrderBy(expBuilder.get("address").get("city").descending())
     * </pre></blockquote>
     */
    public Expression descending() {
        return getFunction(ExpressionOperator.Descending);
    }

    /**
     * INTERNAL:
     * Used in debug printing of this node.
     */
    public String descriptionOfNodeType() {
        return "Expression";
    }

    /**
     * PUBLIC:
     * Function return a value which indicates how much difference there is
     * between two expressions.  Equivalent of the Sybase DIFFERENCE function
     * <p>Example:
     * <blockquote><pre>
     * EclipseLink: employee.get("name").difference("Frank")
     * SQL: DIFFERENCE(name, 'Frank')
     * </pre></blockquote>
     */
    public Expression difference(String expression) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Difference);
        return anOperator.expressionFor(this, expression);
    }

    /**
     * PUBLIC:
     * Function, This represents the distinct option inside an aggregate function. Can be used only within Report Queries.
     */
    public Expression distinct() {
        return getFunction(ExpressionOperator.Distinct);
    }

    /**
     * INTERNAL:
     * Check if the object conforms to the expression in memory.
     * This is used for in-memory querying.
     * By default throw an exception as all valid root expressions must override.
     * If the expression in not able to determine if the object conform throw a not supported exception.
     */
    public boolean doesConform(Object object, AbstractSession session, AbstractRecord translationRow, int valueHolderPolicy) throws QueryException {
        return doesConform(object, session, translationRow, valueHolderPolicy, false);
    }

    /**
     * INTERNAL:
     * New parameter added to doesConform for feature 2612601
     * @param objectIsUnregistered true if object possibly not a clone, but is being
     * conformed against the unit of work cache; if object is not in the UOW cache
     * but some of its attributes are, use the registered versions of
     * object's attributes for the purposes of this method.
     */
    public boolean doesConform(Object object, AbstractSession session, AbstractRecord translationRow, int valueHolderPolicy, boolean objectIsUnregistered) throws QueryException {
        throw QueryException.cannotConformExpression();
    }

    /**
     * INTERNAL:
     * Return if the expression is equal to the other.
     * This is used to allow dynamic expression's SQL to be cached.
     * Two expressions should be considered equal if they have the same "parameterized" SQL.
     * This must be over written by each subclass.
     */
    @Override
    public boolean equals(Object expression) {
        return (this == expression) || ((expression != null) && getClass().equals(expression.getClass()) && (hashCode() == expression.hashCode()));
    }

    /**
     * INTERNAL:
     * Return a consistent hash-code for the expression.
     * This is used to allow dynamic expression's SQL to be cached.
     * Two expressions should have the same hashCode if they have the same "parameterized" SQL.
     * This should be over written by each subclass to provide a consistent value.
     */
    @Override
    public int hashCode() {
        if (this.hashCode == 0) {
            this.hashCode = computeHashCode();
        }
        return this.hashCode;
    }

    /**
     * INTERNAL:
     * Compute a consistent hash-code for the expression.
     * This is used to allow dynamic expression's SQL to be cached.
     * Two expressions should have the same hashCode if they have the same "parameterized" SQL.
     * This should be over written by each subclass to provide a consistent value.
     */
    public int computeHashCode() {
        return 32;
    }

    public Expression equal(byte theValue) {
        return equal(Byte.valueOf(theValue));
    }

    public Expression equal(char theChar) {
        return equal(Character.valueOf(theChar));
    }

    public Expression equal(double theValue) {
        return equal(Double.valueOf(theValue));
    }

    public Expression equal(float theValue) {
        return equal(Float.valueOf(theValue));
    }

    public Expression equal(int theValue) {
        return equal(Integer.valueOf(theValue));
    }

    public Expression equal(long theValue) {
        return equal(Long.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receiver's value is equal to the other value.
     * This is equivalent to the SQL "=" operator and Java "equals" method.
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.get("firstName").equal("Bob")
     *     Java: employee.getFirstName().equals("Bob")
     *     SQL: F_NAME = 'Bob'
     * </pre></blockquote>
     */
    public Expression equal(Object theValue) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Equal);
        return anOperator.expressionFor(this, theValue);
    }

    /**
     * Returns an expression that compares if the receiver's value is equal to the other value.
     * This is equivalent to the SQL "=" operator and Java "equals" method.
     * <p>Since OracleAS EclipseLink 10<i>g</i> (9.0.4) if <code>this</code> is an <code>ExpressionBuilder</code> and <code>theValue</code>
     * is not used elsewhere, both will be translated to the same table.  This can
     * generate SQL with one less join for most exists subqueries.
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.get("manager").equal(employee)
     *     Java: employee.getManager().equals(employee)
     *     SQL (optimized): EMP_ID = MANAGER_ID
     *     SQL (unoptimized): t0.MANAGER_ID = t1.EMP_ID AND t0.EMP_ID = t1.EMP_ID
     * </pre></blockquote>
     * @see #equal(Object)
     */
    public Expression equal(Expression theValue) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Equal);
        return anOperator.expressionFor(this, theValue);

    }

    public Expression equal(short theValue) {
        return equal(Short.valueOf(theValue));
    }

    public Expression equal(boolean theBoolean) {
        return equal(Boolean.valueOf(theBoolean));
    }

    /**
     * INTERNAL:
     * Return an expression representing an outer join comparison
     */

    // cr3546
    public Expression equalOuterJoin(Object theValue) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.EqualOuterJoin);
        return anOperator.expressionFor(this, theValue);
    }

    /**
     * INTERNAL:
     * Return an expression representing an outer join comparison
     */
    public Expression equalOuterJoin(Expression theValue) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.EqualOuterJoin);
        return anOperator.expressionFor(this, theValue);

    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receiver's value is equal to the other value, ignoring case.
     * This is equivalent to the Java "equalsIgnoreCase" method.
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.get("firstName").equalsIgnoreCase("Bob")
     *     Java: employee.getFirstName().equalsIgnoreCase("Bob")
     *     SQL: UPPER(F_NAME) = 'BOB'
     * </pre></blockquote>
     */
    public Expression equalsIgnoreCase(String theValue) {
        if (shouldUseUpperCaseForIgnoreCase) {
            return toUpperCase().equal(theValue.toUpperCase());
        } else {
            return toLowerCase().equal(theValue.toLowerCase());
        }
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receiver's value is equal to the other value, ignoring case.
     * This is equivalent to the Java "equalsIgnoreCase" method.
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.get("firstName").equalsIgnoreCase("Bob")
     *     Java: employee.getFirstName().equalsIgnoreCase("Bob")
     *     SQL: UPPER(F_NAME) = 'BOB'
     * </pre></blockquote>
     */
    public Expression equalsIgnoreCase(Expression theValue) {
        if (shouldUseUpperCaseForIgnoreCase) {
            return toUpperCase().equal(theValue.toUpperCase());
        } else {
            return toLowerCase().equal(theValue.toLowerCase());
        }
    }

    /**
     * PUBLIC:
     * Return a sub query expression.
     * A sub query using a report query to define a subselect within another queries expression or select's where clause.
     * The sub query (the report query) will use its own expression builder be can reference expressions from the base expression builder.
     * <p>Example:
     * <blockquote><pre>
     * ExpressionBuilder builder = new ExpressionBuilder();
     * ReportQuery subQuery = new ReportQuery(Employee.class, new ExpressionBuilder());
     * subQuery.setSelectionCriteria(subQuery.getExpressionBuilder().get("name").equal(builder.get("name")));
     * builder.exists(subQuery);
     * </pre></blockquote>
     */
    public Expression exists(ReportQuery subQuery) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Exists);
        return anOperator.expressionFor(subQuery(subQuery));
    }

    /**
     * INTERNAL:
     * Extract the primary key from the expression into the row.
     * Ensure that the query is querying the exact primary key.
     * Return false if not on the primary key.
     */
    public boolean extractPrimaryKeyValues(boolean requireExactMatch, ClassDescriptor descriptor, AbstractRecord primaryKeyRow, AbstractRecord translationRow) {
        return extractValues(true, requireExactMatch, descriptor, primaryKeyRow, translationRow);
    }

    /**
     * INTERNAL:
     * Extract the primary key from the expression into the row.
     * Ensure that the query is querying the exact primary key.
     * Return false if not on the primary key.
     */
    public boolean extractValues(boolean primaryKeyOnly, boolean requireExactMatch, ClassDescriptor descriptor, AbstractRecord primaryKeyRow, AbstractRecord translationRow) {
        return false;
    }

    /**
     * INTERNAL:
     * Return if the expression is not a valid primary key expression and add all primary key fields to the set.
     */
    public boolean extractFields(boolean requireExactMatch, boolean primaryKey, ClassDescriptor descriptor, List<DatabaseField> searchFields, Set<DatabaseField> foundFields) {
        return false;
    }

    /**
     * INTERNAL:
     * Create an expression node.
     */
    public static Expression from(Object value, Expression base) {
        //CR#... null value used to return null, must build a null constant expression.
        if (value instanceof Expression) {
            Expression exp = (Expression)value;
            if (exp.isValueExpression() || base.isExpressionBuilder()) {
                exp.setLocalBase(base);
            } else {
                // We don't know which side of the relationship cares about the other one, so notify both
                // However for 3107049 value.equal(value) would cause infinite loop if did that.
                base.setLocalBase(exp);
            }
            return exp;
        }
        if (value instanceof ReportQuery) {
            Expression exp = base.subQuery((ReportQuery)value);
            exp.setLocalBase(base);// We don't know which side of the relationship cares about the other one, so notify both
            base.setLocalBase(exp);
            return exp;
        }
        return fromConstant(value, base);

    }

    /**
     * INTERNAL:
     * Create an expression node.
     */
    public static Expression fromConstant(Object value, Expression base) {
        return new ConstantExpression(value, base);
    }

    /**
     * INTERNAL:
     * Create an expression node.
     */
    public static Expression fromLiteral(String value, Expression base) {
        return new LiteralExpression(value, base);
    }

    /**
     * PUBLIC:
     * Return an expression that wraps the attribute or query key name.
     * This method is used to construct user-defined queries containing joins.
     * <p>Example:
     * <blockquote><pre>
     *  builder.get("address").get("city").equal("Ottawa");
     * </pre></blockquote>
     */
    public Expression get(String attributeName) {
        return get(attributeName, true);
    }

    /**
     * PUBLIC:
     * Return an expression that wraps the attribute or query key name.
     * This method is used to construct user-defined queries containing joins.
     * <p>Example:
     * <blockquote><pre>
     *  builder.get("address", false).get("city").equal("Ottawa");
     * </pre></blockquote>
     * @param forceInnerJoin - allows the get to not force an inner-join (if getAllowingNull was used elsewhere).
     */
    public Expression get(String attributeName, boolean forceInnerJoin) {
        throw new UnsupportedOperationException("get");
    }

    /**
     * ADVANCED:
     * Return an expression that wraps the attribute or query key name.
     * This is only applicable to 1:1 relationships, and allows the target of
     * the relationship to be null if there is no corresponding relationship in the database.
     * Implemented via an outer join in the database.
     * <p>Example:
     * <blockquote><pre>
     *  builder.getAllowingNull("address").get("city").equal("Ottawa");
     * </pre></blockquote>
     */
    public Expression getAllowingNull(String attributeName) {
        throw new UnsupportedOperationException("getAllowingNull");
    }

    /**
     * Answers the past time the expression is explicitly as of.
     * @return An immutable object representation of the past time.
     * <code>null</code> if no clause set, <code>AsOfClause.NO_CLAUSE</code> if
     * clause explicitly set to <code>null</code>.
     * @see #asOf(org.eclipse.persistence.history.AsOfClause)
     * @see #hasAsOfClause()
     */
    public AsOfClause getAsOfClause() {
        return null;
    }

    /**
     * INTERNAL:
     * For Flashback: If this expression is not already as of some timestamp
     * gets the clause from the base expression.  Allows a clause to be set
     * only on the builder and then propogated during normalize.
     */
    public AsOfClause getAsOfClauseRecursively() {
        return null;
    }

    /**
     * INTERNAL:
     * Return the expression builder which is the ultimate base of this expression, or
     * null if there isn't one (shouldn't happen if we start from a root)
     */
    public abstract ExpressionBuilder getBuilder();

    /**
     * INTERNAL:
     * If there are any fields associated with this expression, return them
     */
    public DatabaseField getClonedField() {
        return null;
    }

    /**
     * ADVANCED:
     * Return an expression representing a field in a data-level query.
     * This is used internally in EclipseLink, or to construct queries involving
     * fields and/or tables that are not mapped.
     * <p> Example:
     * <blockquote><pre>
     *  builder.getField("ADDR_ID").greaterThan(100);
     *  builder.getTable("PROJ_EMP").getField("TYPE").equal("S");
     * </pre></blockquote>
     */
    public Expression getField(String fieldName) {
        throw QueryException.illegalUseOfGetField(fieldName);
    }

    /**
     * ADVANCED: Return an expression representing a field in a data-level query.
     * This is used internally in EclipseLink, or to construct queries involving
     * fields and/or tables that are not mapped.
     * <p> Example:
     * <blockquote><pre>
     *  builder.getField(aField).greaterThan(100);
     * </pre></blockquote>
     */
    public Expression getField(DatabaseField field) {
        throw QueryException.illegalUseOfGetField(field);
    }

    /**
     * INTERNAL:
     */
    public List<DatabaseField> getFields() {
        return new ArrayList<>(1);
    }

    /**
     * INTERNAL:
     */
    public List<DatabaseField> getSelectionFields() {
        return getSelectionFields(null);
    }
    public List<DatabaseField> getSelectionFields(ReadQuery query) {
        return getFields();
    }

    /**
     * INTERNAL:
     * Transform the object-level value into a database-level value
     */
    public Object getFieldValue(Object objectValue, AbstractSession session) {
        // Enums default to their ordinal
        if (objectValue instanceof Enum){
            return ((Enum)objectValue).ordinal();
        }
        return objectValue;

    }

    /**
     * ADVANCED:
     * Defines a join between the two objects based on the specified ON clause.
     * This can be used to define a join condition on two unrelated objects,
     * or to qualify a relationship join with additional criteria.
     * <p> Example:
     * <blockquote><pre>
     *  Expression address = employee.getAllowingNull("address");
     *  employee.join(address, address.get("city").equal("Ottawa"));
     *  query.addNonFetchJoin(address);
     * </pre></blockquote>
     */
    public Expression join(Expression target, Expression onClause) {
        throw new UnsupportedOperationException("join");
    }

    /**
     * ADVANCED:
     * Defines an outer join between the two objects based on the specified ON clause.
     * This can be used to define a join condition on two unrelated objects,
     * or to qualify a relationship join with additional criteria.
     * <p> Example:
     * <blockquote><pre>
     *  Expression address = employee.getAllowingNull("address");
     *  employee.leftJoin(address, address.get("city").equal("Ottawa"));
     *  query.addNonFetchJoin(address);
     * </pre></blockquote>
     */
    public Expression leftJoin(Expression target, Expression onClause) {
        throw new UnsupportedOperationException("leftJoin");
    }

    /**
     * ADVANCED:
     * This can be used for accessing user defined functions.
     * The operator must be defined in ExpressionOperator to be able to reference it.
     * @see ExpressionOperator
     * <p> Example:
     * <blockquote><pre>
     *  builder.get("name").getFunction(MyFunctions.FOO_BAR).greaterThan(100);
     * </pre></blockquote>
     */
    public Expression getFunction(int selector) {
        ExpressionOperator anOperator = getOperator(selector);
        return anOperator.expressionFor(this);
    }

    /**
     * ADVANCED:
     * This can be used for accessing user defined functions that have arguments.
     * The operator must be defined in ExpressionOperator to be able to reference it.
     * @see ExpressionOperator
     * <p> Example:
     * <blockquote><pre>
     *    List arguments = new ArrayList();
     *    arguments.add("blee");
     *  builder.get("name").getFunction(MyFunctions.FOO_BAR, arguments).greaterThan(100);
     * </pre></blockquote>
     */
    public Expression getFunction(int selector, List arguments) {
        ExpressionOperator anOperator = getOperator(selector);
        return anOperator.expressionForArguments(this, arguments);
    }

    /**
     * ADVANCED:
     * This can be used for accessing user defined operators that have arguments.
     * The operator must be defined in ExpressionOperator to be able to reference it.
     * @see ExpressionOperator
     * <p> Example:
     * <blockquote><pre>
     *  List arguments = new ArrayList();
     *  arguments.add("blee");
     *  builder.get("name").operator("FOO_BAR", arguments).greaterThan(100);
     * </pre></blockquote>
     */
    public Expression operator(String name, List arguments) {
        Integer selector = ExpressionOperator.getPlatformOperatorSelectors().get(name);
        if (selector == null) {
            return getFunctionWithArguments(name, arguments);
        }
        return getFunction(selector, arguments);
    }

    /**
     * ADVANCED:
     * Return a user defined function accepting the argument.
     * The function is assumed to be a normal prefix function and will print like, UPPER(base).
     * <p> Example:
     * <blockquote><pre>
     *  builder.get("firstName").getFunction("UPPER");
     * </pre></blockquote>
     */
    public Expression getFunction(String functionName) {
        ExpressionOperator anOperator = ExpressionOperator.simpleFunction(0, functionName);
        return anOperator.expressionFor(this);
    }

    /**
     * ADVANCED:
     * Return a user defined function accepting the argument.
     * The function is assumed to be a normal prefix function and will print like, CONCAT(base, argument).
     */
    public Expression getFunction(String functionName, Object argument) {
        ExpressionOperator anOperator = ExpressionOperator.simpleTwoArgumentFunction(0, functionName);
        return anOperator.expressionFor(this, argument);
    }

    /**
     * ADVANCED:
     * Return a user defined function accepting all of the arguments.
     * The function is assumed to be a normal prefix function like, CONCAT(base, value1, value2, value3, ...).
     */
    public Expression getFunctionWithArguments(String functionName, List arguments) {
        ExpressionOperator anOperator = new ExpressionOperator();
        anOperator.setType(ExpressionOperator.FunctionOperator);
        List<String> v = new ArrayList<>(arguments.size());
        v.add(functionName + "(");
        for (int index = 0; index < arguments.size(); index++) {
            v.add(", ");
        }
        v.add(")");
        anOperator.printsAs(v);
        anOperator.bePrefix();
        anOperator.setNodeClass(ClassConstants.FunctionExpression_Class);

        return anOperator.expressionForArguments(this, arguments);
    }

    /**
     * ADVANCED:
     * Parse the SQL for parameter and return a custom function expression
     * using a custom operator that will print itself as the SQL.
     * Arguments are passed using '?', and must match the number of arguments.
     */
    public Expression sql(String sql, List arguments) {
        ExpressionOperator anOperator = new ExpressionOperator();
        anOperator.setType(ExpressionOperator.FunctionOperator);
        List<String> v = new ArrayList<>(arguments.size());
        int start = 0;
        int index = sql.indexOf('?');
        while (index != -1) {
            v.add(sql.substring(start, index));
            start = index + 1;
            index = sql.indexOf('?', start);
        }
        if (start <= sql.length()) {
            v.add(sql.substring(start, sql.length()));
        }
        anOperator.printsAs(v);
        anOperator.bePrefix();
        anOperator.setNodeClass(ClassConstants.FunctionExpression_Class);

        return anOperator.expressionForArguments(this, arguments);
    }

    /**
     * PUBLIC:
     * Return an expression that wraps the inheritance type field in an expression.
     * <p>Example:
     * <blockquote><pre>
     *  builder.getClassForInheritance().equal(SmallProject.class);
     *  builder.anyOf("projects").getClassForInheritance().equal(builder.getParameter("projectClass"));
     * </pre></blockquote>
     */
    public Expression type() {
        //Only valid on an ObjectExpression
        return null;
    }

    /**
     * INTERNAL:
     */
    public String getName() {
        return "";
    }

    /**
     * INTERNAL:
     * Most expression have operators, so this is just a convenience method.
     */
    public ExpressionOperator getOperator() {
        return null;
    }

    /**
     * INTERNAL:
     * Create a new expression tree with the named operator. Part of the implementation of user-level "get"
     */
    public ExpressionOperator getOperator(int selector) {
        ExpressionOperator result = ExpressionOperator.getOperator(selector);
        if (result != null) {
            return result;
        }

        // Make a temporary operator which we expect the platform
        // to supply later.
        result = new ExpressionOperator();
        result.setSelector(selector);
        result.setNodeClass(ClassConstants.FunctionExpression_Class);
        return result;
    }

    /**
     * INTERNAL:
     * Return the tables that this node owns for purposes of table aliasing.
     */
    public List<DatabaseTable> getOwnedTables() {
        return null;
    }

    /**
     * INTERNAL:
     * Return an expression representing a parameter with the given name and type
     */
    public Expression getParameter(String parameterName, Object type) {
        return new ParameterExpression(parameterName, getBuilder(), type);

    }

    /**
     * ADVANCED:
     * Return an expression representing a parameter with the given name.
     */
    public Expression getParameter(String parameterName) {
        return new ParameterExpression(parameterName, getBuilder(), null);

    }

    /**
     * ADVANCED:
     * Return an expression representing a parameter with the given name.
     */
    public Expression getParameter(DatabaseField field) {
        return new ParameterExpression(field, getBuilder());

    }

    /**
     * ADVANCED:
     * Return an expression representing a property with the given name.
     */
    public Expression getProperty(DatabaseField field) {
        ParameterExpression paramExpression = new ParameterExpression(field, this);
        paramExpression.setIsProperty(true);
        return paramExpression;
    }

    /**
     * INTERNAL:
     */
    public AbstractSession getSession() {
        return getBuilder().getSession();
    }

    /**
     * ADVANCED: Return an expression representing a table in a data-level query.
     * This is used internally in EclipseLink, or to construct queries involving
     * fields and/or tables that are not mapped.
     * <p> Example:
     * <blockquote><pre>
     *  builder.getTable("PROJ_EMP").getField("TYPE").equal("S");
     * </pre></blockquote>
     */
    public Expression getTable(String tableName) {
        DatabaseTable table = new DatabaseTable(tableName);
        return getTable(table);
    }

    /**
     * ADVANCED: Return an expression representing a table in a data-level query.
     * This is used internally in EclipseLink, or to construct queries involving
     * fields and/or tables that are not mapped.
     * <p> Example:
     * <blockquote><pre>
     *  builder.getTable(linkTable).getField("TYPE").equal("S");
     * </pre></blockquote>
     */
    public Expression getTable(DatabaseTable table) {
        throw QueryException.illegalUseOfGetTable(table);
    }

    /**
     * ADVANCED: Return an expression representing a sub-select in the from clause.
     * <p> Example:
     * <blockquote><pre>
     *  builder.getAlias(builder.subQuery(reportQuery)).get("type").equal("S");
     * </pre></blockquote>
     */
    public Expression getAlias(Expression subSelect) {
        throw QueryException.illegalUseOfGetTable(subSelect);
    }

    /**
     * INTERNAL:
     * Return the aliases used. By default, return null, since we don't have tables.
     */
    public TableAliasLookup getTableAliases() {
        return null;

    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is equal to the other value.
     * This is equivalent to the SQL "=" operator and Java "equals" method.
     */
    public Expression greaterThan(byte theValue) {
        return greaterThan(Byte.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is equal to the other value.
     * This is equivalent to the SQL "=" operator and Java "equals" method.
     */
    public Expression greaterThan(char theChar) {
        return greaterThan(Character.valueOf(theChar));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is equal to the other value.
     * This is equivalent to the SQL "=" operator and Java "equals" method.
     */
    public Expression greaterThan(double theValue) {
        return greaterThan(Double.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is equal to the other value.
     * This is equivalent to the SQL "=" operator and Java "equals" method.
     */
    public Expression greaterThan(float theValue) {
        return greaterThan(Float.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is equal to the other value.
     * This is equivalent to the SQL "=" operator and Java "equals" method.
     */
    public Expression greaterThan(int theValue) {
        return greaterThan(Integer.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is equal to the other value.
     * This is equivalent to the SQL "=" operator and Java "equals" method.
     */
    public Expression greaterThan(long theValue) {
        return greaterThan(Long.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receiver's value is greater than the other value.
     * This is equivalent to the SQL {@literal ">"} operator.
     */
    public Expression greaterThan(Object theValue) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.GreaterThan);
        return anOperator.expressionFor(this, theValue);
    }

    public Expression greaterThan(Expression theValue) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.GreaterThan);
        return anOperator.expressionFor(this, theValue);

    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is equal to the other value.
     * This is equivalent to the SQL "=" operator and Java "equals" method.
     */
    public Expression greaterThan(short theValue) {
        return greaterThan(Short.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is equal to the other value.
     * This is equivalent to the SQL "=" operator and Java "equals" method.
     */
    public Expression greaterThan(boolean theBoolean) {
        return greaterThan(Boolean.valueOf(theBoolean));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is greater and equal to the other value.
     * This is equivalent to the SQL {@literal ">="} operator.
     */
    public Expression greaterThanEqual(byte theValue) {
        return greaterThanEqual(Byte.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is greater and equal to the other value.
     * This is equivalent to the SQL {@literal ">="} operator.
     */
    public Expression greaterThanEqual(char theChar) {
        return greaterThanEqual(Character.valueOf(theChar));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is greater and equal to the other value.
     * This is equivalent to the SQL {@literal ">="} operator.
     */
    public Expression greaterThanEqual(double theValue) {
        return greaterThanEqual(Double.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is greater and equal to the other value.
     * This is equivalent to the SQL {@literal ">="} operator.
     */
    public Expression greaterThanEqual(float theValue) {
        return greaterThanEqual(Float.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is greater and equal to the other value.
     * This is equivalent to the SQL {@literal ">="} operator.
     */
    public Expression greaterThanEqual(int theValue) {
        return greaterThanEqual(Integer.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is greater and equal to the other value.
     * This is equivalent to the SQL {@literal ">="} operator.
     */
    public Expression greaterThanEqual(long theValue) {
        return greaterThanEqual(Long.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is greater and equal to the other value.
     * This is equivalent to the SQL {@literal ">="} operator.
     */
    public Expression greaterThanEqual(Object theValue) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.GreaterThanEqual);
        return anOperator.expressionFor(this, theValue);

    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is greater and equal to the other value.
     * This is equivalent to the SQL {@literal ">="} operator.
     */
    public Expression greaterThanEqual(Expression theValue) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.GreaterThanEqual);
        return anOperator.expressionFor(this, theValue);

    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is greater and equal to the other value.
     * This is equivalent to the SQL {@literal ">="} operator.
     */
    public Expression greaterThanEqual(short theValue) {
        return greaterThanEqual(Short.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is greater and equal to the other value.
     * This is equivalent to the SQL {@literal ">="} operator.
     */
    public Expression greaterThanEqual(boolean theBoolean) {
        return greaterThanEqual(Boolean.valueOf(theBoolean));
    }

    /**
     * ADVANCED:
     * Answers true if <code>this</code> is to be queried as of a past time.
     * @return false from <code>asOf(null); hasAsOfClause()</code>.
     * @see #getAsOfClause
     */
    public boolean hasAsOfClause() {
        return false;
    }

    /**
     * INTERNAL:
     * Answers if the database tables associated with this expression have been
     * aliased.  This insures the same tables are not aliased twice.
     */
    public boolean hasBeenAliased() {
        return false;
    }

    /**
     * PUBLIC:
     * Function, returns binary array value for the hex string.
     */
    public Expression hexToRaw() {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.HexToRaw);
        return anOperator.expressionFor(this);
    }

    /**
     * PUBLIC:
     * Function  return a specific value if item returned from the
     * query is null.  Equivalent of the oracle NVL function
     * <p>Example:
     * <blockquote><pre>
     * EclipseLink: employee.get("name").ifNull("no-name")
     * Java: NA
     * SQL: NVL(name, 'no-name')
     * </pre></blockquote>
     */
    public Expression ifNull(Object nullValue) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Nvl);
        return anOperator.expressionFor(this, nullValue);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression in(byte[] theBytes) {
        List values = new ArrayList(theBytes.length);

        for (int index = 0; index < theBytes.length; index++) {
            values.add(theBytes[index]);
        }

        return in(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression in(char[] theChars) {
        List values = new ArrayList(theChars.length);

        for (int index = 0; index < theChars.length; index++) {
            values.add(theChars[index]);
        }

        return in(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression in(double[] theDoubles) {
        List values = new ArrayList(theDoubles.length);

        for (int index = 0; index < theDoubles.length; index++) {
            values.add(theDoubles[index]);
        }

        return in(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression in(float[] theFloats) {
        List values = new ArrayList(theFloats.length);

        for (int index = 0; index < theFloats.length; index++) {
            values.add(theFloats[index]);
        }

        return in(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression in(int[] theInts) {
        List values = new ArrayList(theInts.length);

        for (int index = 0; index < theInts.length; index++) {
            values.add(theInts[index]);
        }

        return in(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression in(long[] theLongs) {
        List values = new ArrayList(theLongs.length);

        for (int index = 0; index < theLongs.length; index++) {
            values.add(theLongs[index]);
        }

        return in(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression in(Object[] theObjects) {
        List values = new ArrayList(theObjects.length);

        for (int index = 0; index < theObjects.length; index++) {
            values.add(theObjects[index]);
        }

        return in(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression in(short[] theShorts) {
        List values = new ArrayList(theShorts.length);

        for (int index = 0; index < theShorts.length; index++) {
            values.add(theShorts[index]);
        }

        return in(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression in(boolean[] theBooleans) {
        List values = new ArrayList(theBooleans.length);

        for (int index = 0; index < theBooleans.length; index++) {
            values.add(theBooleans[index]);
        }

        return in(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.get("age").in(ages)
     *     Java: ages.contains(employee.getAge())
     *     SQL: AGE IN (55, 18, 30)
     * </pre></blockquote>
     */
    public Expression in(Collection theObjects) {
        return in(new CollectionExpression(theObjects, this));
    }

    public Expression in(Expression arguments) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.In);
        return anOperator.expressionFor(this, arguments);
    }

    public Expression in(ReportQuery subQuery) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.InSubQuery);
        return anOperator.expressionFor(this, subQuery);
    }

    /*
     * PUBLIC:
     * Index method could be applied to QueryKeyExpression corresponding to CollectionMapping
     * that has non-null listOrderField (the field holding the index values).
     * <p>Example:
     * <blockquote><pre>
     *    ReportQuery query = new ReportQuery();
     *    query.setReferenceClass(Employee.class);
     *    ExpressionBuilder builder = query.getExpressionBuilder();
     *    Expression firstNameJohn = builder.get("firstName").equal("John");
     *    Expression anyOfProjects = builder.anyOf("projects");
     *    Expression exp = firstNameJohn.and(anyOfProjects.index().between(2, 4));
     *    query.setSelectionCriteria(exp);
     *    query.addAttribute("projects", anyOfProjects);
     *
     *    SELECT DISTINCT t0.PROJ_ID, t0.PROJ_TYPE, t0.DESCRIP, t0.PROJ_NAME, t0.LEADER_ID, t0.VERSION, t1.PROJ_ID, t1.BUDGET, t1.MILESTONE
     *    FROM OL_PROJ_EMP t4, OL_SALARY t3, OL_EMPLOYEE t2, OL_LPROJECT t1, OL_PROJECT t0
     *    WHERE ((((t2.F_NAME = 'John') AND (t4.PROJ_ORDER BETWEEN 2 AND 4)) AND (t3.OWNER_EMP_ID = t2.EMP_ID)) AND
     *    (((t4.EMP_ID = t2.EMP_ID) AND (t0.PROJ_ID = t4.PROJ_ID)) AND (t1.PROJ_ID (+) = t0.PROJ_ID)))
     * </pre></blockquote>
     */
    public Expression index() {
        throw QueryException.indexRequiresQueryKeyExpression(this);
    }

    /**
     * PUBLIC:
     * Function, returns the integer index of the substring within the source string.
     */
    public Expression indexOf(Object substring) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Instring);
        return anOperator.expressionFor(this, substring);
    }

    /**
     * INTERNAL:
     */
    public boolean isClassTypeExpression(){
        return false;
    }

    /**
     * INTERNAL:
     */
    public boolean isCompoundExpression() {
        return false;
    }

    /**
     * INTERNAL:
     */
    public boolean isConstantExpression() {
        return false;
    }

    /**
     * INTERNAL:
     */
    public boolean isDataExpression() {
        return false;
    }

    /**
     * PUBLIC: A logical expression for the collection <code>attributeName</code>
     * being empty.
     * Equivalent to <code>size(attributeName).equal(0)</code>
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.isEmpty("phoneNumbers")
     *     Java: employee.getPhoneNumbers().size() == 0
     *     SQL: SELECT ... FROM EMP t0 WHERE (
     *      (SELECT COUNT(*) FROM PHONE t1 WHERE (t0.EMP_ID = t1.EMP_ID)) = 0)
     * </pre></blockquote>
     * This is a case where a fast operation in java does not translate to an
     * equally fast operation in SQL, requiring a correlated subselect.
     * @see #size(java.lang.String)
     */
    public Expression isEmpty(String attributeName) {
        return size(attributeName).equal(0);
    }

    /**
     * INTERNAL:
     */
    public boolean isExpressionBuilder() {
        return false;
    }

    /**
     * INTERNAL:
     */
    public boolean isFieldExpression() {
        return false;
    }

    /**
     * INTERNAL:
     */
    public boolean isFunctionExpression() {
        return false;
    }

    /**
     * INTERNAL:
     */
    public boolean isLiteralExpression() {
        return false;
    }

    /**
     * INTERNAL:
     */
    public boolean isLogicalExpression() {
        return false;
    }

    /**
     * PUBLIC:
     * Compare to null.
     */
    public Expression isNull() {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.IsNull);
        return anOperator.expressionFor(this);
    }

    /**
     * INTERNAL:
     */
    public boolean isObjectExpression() {
        return false;
    }

    /**
     * INTERNAL:
     */
    public boolean isParameterExpression() {
        return false;
    }

    /**
     * INTERNAL:
     */
    public boolean isQueryKeyExpression() {
        return false;
    }

    /**
     * INTERNAL:
     */
    public boolean isRelationExpression() {
        return false;
    }

    /**
     * INTERNAL:
     */
    public boolean isSubSelectExpression() {
        return false;
    }

    /**
     * INTERNAL:
     */
    public boolean isTableExpression() {
        return false;
    }

    /**
     * INTERNAL:
     */
    public boolean isTreatExpression() {
        return false;
    }

    /**
     * INTERNAL:
     */
    public boolean isMapEntryExpression(){
        return false;
    }

    /**
     * INTERNAL:
     * Subclasses implement (isParameterExpression() || isConstantExpression())
     */
    public boolean isValueExpression() {
        return false;
    }

    /**
     * INTERNAL:
     * For iterating using an inner class
     */
    public void iterateOn(ExpressionIterator iterator) {
        iterator.iterate(this);
    }

    /**
     * PUBLIC:
     * Function, returns the date with the last date in the months of this source date.
     */
    public Expression lastDay() {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.LastDay);
        return anOperator.expressionFor(this);
    }

    /**
     * PUBLIC:
     * Function, returns the string padded with the substring to the size.
     */
    public Expression leftPad(int size, Object substring) {
        return leftPad(Integer.valueOf(size), substring);
    }

    /**
     * PUBLIC:
     * Function, returns the string padded with the substring to the size.
     */
    public Expression leftPad(Object size, Object substring) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.LeftPad);
        List args = new ArrayList(2);
        args.add(size);
        args.add(substring);
        return anOperator.expressionForArguments(this, args);
    }

    /**
     * PUBLIC:
     * Function, returns the string left trimmed for white space.
     */
    public Expression leftTrim() {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.LeftTrim);
        return anOperator.expressionFor(this);
    }

    /**
     * PUBLIC:
     * Function, returns the string with the substring trimed from the left.
     */
    public Expression leftTrim(Object substring) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.LeftTrim2);
        return anOperator.expressionFor(this, substring);
    }

    /**
     * PUBLIC:
     * Function, returns the size of the string.
     */
    public Expression length() {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Length);
        return anOperator.expressionFor(this);
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is less than the other value.
     * This is equivalent to the SQL {@literal "<"} operator.
     */
    public Expression lessThan(byte theValue) {
        return lessThan(Byte.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is less than the other value.
     * This is equivalent to the SQL {@literal "<"} operator.
     */
    public Expression lessThan(char theChar) {
        return lessThan(Character.valueOf(theChar));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is less than the other value.
     * This is equivalent to the SQL {@literal "<"} operator.
     */
    public Expression lessThan(double theValue) {
        return lessThan(Double.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is less than the other value.
     * This is equivalent to the SQL {@literal "<"} operator.
     */
    public Expression lessThan(float theValue) {
        return lessThan(Float.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is less than the other value.
     * This is equivalent to the SQL {@literal "<"} operator.
     */
    public Expression lessThan(int theValue) {
        return lessThan(Integer.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is less than the other value.
     * This is equivalent to the SQL {@literal "<"} operator.
     */
    public Expression lessThan(long theValue) {
        return lessThan(Long.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is less than the other value.
     * This is equivalent to the SQL {@literal "<"} operator.
     */
    public Expression lessThan(Object theValue) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.LessThan);
        return anOperator.expressionFor(this, theValue);
    }

    public Expression lessThan(Expression theValue) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.LessThan);
        return anOperator.expressionFor(this, theValue);

    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is less than the other value.
     * This is equivalent to the SQL {@literal "<"} operator.
     */
    public Expression lessThan(short theValue) {
        return lessThan(Short.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is less than the other value.
     * This is equivalent to the SQL {@literal "<"} operator.
     */
    public Expression lessThan(boolean theBoolean) {
        return lessThan(Boolean.valueOf(theBoolean));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is less than and equal to the other value.
     * This is equivalent to the SQL {@literal "<="} operator.
     */
    public Expression lessThanEqual(byte theValue) {
        return lessThanEqual(Byte.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is less than and equal to the other value.
     * This is equivalent to the SQL {@literal "<="} operator.
     */
    public Expression lessThanEqual(char theChar) {
        return lessThanEqual(Character.valueOf(theChar));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is less than and equal to the other value.
     * This is equivalent to the SQL {@literal "<="} operator.
     */
    public Expression lessThanEqual(double theValue) {
        return lessThanEqual(Double.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is less than and equal to the other value.
     * This is equivalent to the SQL {@literal "<="} operator.
     */
    public Expression lessThanEqual(float theValue) {
        return lessThanEqual(Float.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is less than and equal to the other value.
     * This is equivalent to the SQL {@literal "<="} operator.
     */
    public Expression lessThanEqual(int theValue) {
        return lessThanEqual(Integer.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is less than and equal to the other value.
     * This is equivalent to the SQL {@literal "<="} operator.
     */
    public Expression lessThanEqual(long theValue) {
        return lessThanEqual(Long.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is less than and equal to the other value.
     * This is equivalent to the SQL {@literal "<="} operator.
     */
    public Expression lessThanEqual(Object theValue) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.LessThanEqual);
        return anOperator.expressionFor(this, theValue);
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is less than and equal to the other value.
     * This is equivalent to the SQL {@literal "<="} operator.
     */
    public Expression lessThanEqual(Expression theValue) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.LessThanEqual);
        return anOperator.expressionFor(this, theValue);

    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is less than and equal to the other value.
     * This is equivalent to the SQL {@literal "<="} operator.
     */
    public Expression lessThanEqual(short theValue) {
        return lessThanEqual(Short.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is less than and equal to the other value.
     * This is equivalent to the SQL {@literal "<="} operator.
     */
    public Expression lessThanEqual(boolean theBoolean) {
        return lessThanEqual(Boolean.valueOf(theBoolean));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is like other value.
     * This is equivalent to the SQL "LIKE" operator that except wildcards.
     * The character "%" means any sequence of characters and the character "_" mean any character.
     * i.e. "B%" == "Bob", "B_B" == "BOB"
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.get("firstName").like("B%")
     *     Java: NA
     *     SQL: F_NAME LIKE 'B%'
     * </pre></blockquote>
     */
    public Expression like(String value) {
        return like(new ConstantExpression(value, this));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is like other value.
     * This is equivalent to the SQL "LIKE ESCAPE" operator that except wildcards.
     * The character "%" means any sequence of characters and the character "_" mean any character.
     * i.e. "B%" == "Bob", "B_B" == "BOB"
     * The escape sequence specifies a set of characters the may be used to indicate that
     * an one of the wildcard characters should be interpreted literally.
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.get("firstName").like("B\_SMITH", "\")
     *     Java: NA
     *     SQL: F_NAME LIKE 'B\_SMITH ESCAPE '\''
     * </pre></blockquote>
     */
    public Expression like(String value, String escapeSequence) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.LikeEscape);
        List args = new ArrayList(2);
        args.add(value);
        args.add(escapeSequence);
        return anOperator.expressionForArguments(this, args);
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is like other value.
     * This is equivalent to the SQL "LIKE" operator that except wildcards.
     * The character "%" means any sequence of characters and the character "_" mean any character.
     * i.e. "B%" == "Bob", "B_B" == "BOB"
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.get("firstName").like("B%")
     *     Java: NA
     *     SQL: F_NAME LIKE 'B%'
     * </pre></blockquote>
     */
    public Expression like(Expression argument) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Like);
        return anOperator.expressionFor(this, argument);
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value matches the regular expression.
     * This uses the databases support for regular expression.
     * Regular expressions are similar to LIKE except support a much larger scope of comparisons.
     * i.e. "^B.*" == "Bob", "^B.B$" == "BOB"
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.get("firstName").regexp("^B.*")
     *     Java: Pattern.compile("^B.*").matcher(employee.getFirstName()).matches()
     *     SQL: F_NAME REGEXP '^B.*'
     * </pre></blockquote>
     */
    public Expression regexp(String regexp) {
        return regexp(new ConstantExpression(regexp, this));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value matches the regular expression.
     * This uses the databases support for regular expression.
     * Regular expressions are similar to LIKE except support a much larger scope of comparisons.
     * i.e. "^B.*" == "Bob", "^B.B$" == "BOB"
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.get("firstName").regexp("^B.*")
     *     Java: Pattern.compile("^B.*").matcher(employee.getFirstName()).matches()
     *     SQL: F_NAME REGEXP '^B.*'
     * </pre></blockquote>
     */
    public Expression regexp(Expression regexp) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Regexp);
        return anOperator.expressionFor(this, regexp);
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is like other value.
     * This is equivalent to the SQL "LIKE ESCAPE" operator that except wildcards.
     * The character "%" means any sequence of characters and the character "_" mean any character.
     * i.e. "B%" == "Bob", "B_B" == "BOB"
     * The escape sequence specifies a set of characters the may be used to indicate that
     * an one of the wildcard characters should be interpreted literally.
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.get("firstName").like("B\_SMITH", "\")
     *     Java: NA
     *     SQL: F_NAME LIKE 'B\_SMITH ESCAPE '\''
     * </pre></blockquote>
     */
    public Expression like(Expression value, Expression escapeSequence) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.LikeEscape);
        List args = new ArrayList(2);
        args.add(value);
        args.add(escapeSequence);
        return anOperator.expressionForArguments(this, args);
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is like the other value, ignoring case.
     * This is a case in-sensitive like.
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.get("firstName").likeIgnoreCase("%Bob%")
     *     Java: none
     *     SQL: UPPER(F_NAME) LIKE 'BOB'
     * </pre></blockquote>
     */
    public Expression likeIgnoreCase(String theValue) {
        if (shouldUseUpperCaseForIgnoreCase) {
            return toUpperCase().like(theValue.toUpperCase());
        } else {
            return toLowerCase().like(theValue.toLowerCase());
        }
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is like the other value, ignoring case.
     * This is a case in-sensitive like.
     */
    public Expression likeIgnoreCase(Expression theValue) {
        if (shouldUseUpperCaseForIgnoreCase) {
            return toUpperCase().like(theValue.toUpperCase());
        } else {
            return toLowerCase().like(theValue.toLowerCase());
        }
    }

    /**
     * PUBLIC:
     * Function, returns the position of <code>str</code> in <code>this</code>
     * <p>Example:
     * <blockquote><pre>
     * EclipseLink: employee.get("firstName").locate("ob")
     * Java: employee.getFirstName().indexOf("ob") + 1
     * SQL: LOCATE('ob', t0.F_NAME)
     * </pre></blockquote>
     * <p>
     * Note that while in String.locate(str) -1 is returned if not found, and the
     * index starting at 0 if found, in SQL it is 0 if not found, and the index
     * starting at 1 if found.
     */
    public Expression locate(Object str) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Locate);
        List args = new ArrayList(1);
        args.add(str);
        return anOperator.expressionForArguments(this, args);
    }

    /**
     * PUBLIC:
     * Function, returns the position of <code>str</code> in <code>this</code>,
     * starting the search at <code>fromIndex</code>.
     * <p>Example:
     * <blockquote><pre>
     * EclipseLink: employee.get("firstName").locate("ob", 1)
     * Java: employee.getFirstName().indexOf("ob", 1) + 1
     * SQL: LOCATE('ob', t0.F_NAME, 1)
     * </pre></blockquote>
     * <p>
     * Note that while in String.locate(str) -1 is returned if not found, and the
     * index starting at 0 if found, in SQL it is 0 if not found, and the index
     * starting at 1 if found.
     */
    public Expression locate(String str, int fromIndex) {
        return locate(str, Integer.valueOf(fromIndex));
    }

    /**
     * PUBLIC:
     * Function, returns the position of <code>str</code> in <code>this</code>,
     * starting the search at <code>fromIndex</code>.
     * <p>Example:
     * <blockquote><pre>
     * EclipseLink: employee.get("firstName").locate("ob", 1)
     * Java: employee.getFirstName().indexOf("ob", 1) + 1
     * SQL: LOCATE('ob', t0.F_NAME, 1)
     * </pre></blockquote>
     * <p>
     * Note that while in String.locate(str) -1 is returned if not found, and the
     * index starting at 0 if found, in SQL it is 0 if not found, and the index
     * starting at 1 if found.
     */
    public Expression locate(Object str, Object fromIndex) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Locate2);
        List args = new ArrayList(2);
        args.add(str);
        args.add(fromIndex);
        return anOperator.expressionForArguments(this, args);
    }

    /**
     * PUBLIC:
     * This represents the aggregate function Maximum. Can be used only within Report Queries.
     */
    public Expression maximum() {
        return getFunction(ExpressionOperator.Maximum);
    }

    /**
     * PUBLIC:
     * This represents the aggregate function Minimum. Can be used only within Report Queries.
     */
    public Expression minimum() {
        return getFunction(ExpressionOperator.Minimum);
    }

    /**
     * PUBLIC:
     * Function, returns the decimal number of months between the two dates.
     */
    public Expression monthsBetween(Object otherDate) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.MonthsBetween);
        return anOperator.expressionFor(this, otherDate);
    }

    /**
     * PUBLIC:
     * Return a Map.Entry containing the key and the value from a mapping that maps to a java.util.Map
     * This expression can only be used as a return value in a ReportQuery and cannot be used as part of
     * the WHERE clause in any query
     *
     * EclipseLink: eb.get("mapAttribute").mapEntry()
     */
    public Expression mapEntry(){
        MapEntryExpression expression = new MapEntryExpression(this);
        expression.returnMapEntry();
        return expression;
    }

    /**
     * PUBLIC:
     * Return the key from a mapping that maps to a java.util.Map
     * This expression can be used either in as a return value in a ReportQuery or in the WHERE clause in a query
     *
     * EclipseLink: eb.get("mapAttribute").mapKey()
     */
    public Expression mapKey(){
        return new MapEntryExpression(this);
    }

    /**
     * PUBLIC:
     * funcation return a date converted to a new timezone. Equivalent of the Oracle NEW_TIME function
     * <p>Example:
     * <blockquote><pre>
     * EclipseLink: employee.get("date").newTime("EST", "PST")
     * Java: NA
     * SQL: NEW_TIME(date, 'EST', 'PST')
     * </pre></blockquote>
     */
    public Expression newTime(String timeZoneFrom, String timeZoneTo) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.NewTime);
        List args = new ArrayList(2);
        args.add(timeZoneFrom);
        args.add(timeZoneTo);
        return anOperator.expressionForArguments(this, args);
    }

    /**
     * PUBLIC:
     * Function, returns the date with the next day from the source date as the day name given.
     */
    public Expression nextDay(Object dayName) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.NextDay);
        return anOperator.expressionFor(this, dayName);
    }

    /**
     * PUBLIC: Returns an expression equivalent to none of <code>attributeName</code>
     * holding true for <code>criteria</code>.
     * <p>
     * For every expression with an anyOf, its negation has either an allOf or a
     * noneOf.  The following two examples will illustrate as the second is the
     * negation of the first:
     * <p>
     * AnyOf Example: Employees with a '613' area code phone number.
     * <blockquote><pre>
     * ReadAllQuery query = new ReadAllQuery(Employee.class);
     * ExpressionBuilder employee = new ExpressionBuilder();
     * Expression exp = employee.anyOf("phoneNumbers").get("areaCode").equal("613");
     * </pre></blockquote>
     * <p>
     * NoneOf Example: Employees with no '613' area code phone numbers.
     * <blockquote><pre>
     * ExpressionBuilder employee = new ExpressionBuilder();
     * ExpressionBuilder phones = new ExpressionBuilder();
     * Expression exp = employee.noneOf("phoneNumbers", phones.get("areaCode").equal("613"));
     * SQL:
     * SELECT ... EMPLOYEE t0 WHERE NOT EXISTS (SELECT ... PHONE t1 WHERE
     *                         (t0.EMP_ID = t1.EMP_ID) AND (t1.AREACODE = '613'))
     * </pre></blockquote>
     * <p>
     * noneOf is the universal counterpart to the existential anyOf.  To have the
     * condition evaluated for each instance it must be put inside of a subquery,
     * which can be expressed as not exists (any of attributeName some condition).
     * (All x such that !y = !Exist x such that y).
     * <p>Likewise the syntax employee.noneOf("phoneNumbers").get("areaCode").equal("613")
     * is not supported for the <code>equal</code> must go inside a subQuery.
     * <p>
     * This method saves you from writing the sub query yourself.  The above is
     * equivalent to the following expression:
     * <blockquote><pre>
     * ExpressionBuilder employee = new ExpressionBuilder();
     * ExpressionBuilder phone = new ExpressionBuilder();
     * ReportQuery subQuery = new ReportQuery(Phone.class, phone);
     * subQuery.retreivePrimaryKeys();
     * subQuery.setSelectionCriteria(phone.equal(employee.anyOf("phoneNumbers").and(
     *         phone.get("areaCode").equal("613")));
     * Expression exp = employee.notExists(subQuery);
     * </pre></blockquote>
     * @param criteria must have its own builder, as it will become the
     * separate selection criteria of a subQuery.
     * @return a notExists subQuery expression
     */
    public Expression noneOf(String attributeName, Expression criteria) {
        ReportQuery subQuery = new ReportQuery();
        subQuery.setShouldRetrieveFirstPrimaryKey(true);
        Expression builder = criteria.getBuilder();
        criteria = builder.equal(anyOf(attributeName)).and(criteria);
        subQuery.setSelectionCriteria(criteria);
        return notExists(subQuery);
    }

    /**
     * INTERNAL:
     * Normalize into a structure that is printable.
     * Also compute printing information such as outer joins.
     */
    public Expression normalize(ExpressionNormalizer normalizer) {
        //This class has no validation but we should still make the method call for consistency
        //bug # 2956674
        //validation is moved into normalize to ensure that expressions are valid before we attempt to work with them
        validateNode();
        return this;
    }

    /**
     * PUBLIC:
     * Return an expression that is the boolean logical negation of the expression.
     * This is equivalent to the SQL "NOT" operator and the Java "!" operator.
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.get("age").equal(24).not()
     *     Java: (! (employee.getAge() == 24))
     *     SQL: NOT (AGE = 24)
     * </pre></blockquote>
     */
    public Expression not() {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Not);
        return anOperator.expressionFor(this);
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is not between two other values.
     * Equivalent to between negated.
     * @see #between(Object, Object)
     */
    public Expression notBetween(byte leftValue, byte rightValue) {
        return notBetween(Byte.valueOf(leftValue), Byte.valueOf(rightValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is not between two other values.
     * Equivalent to between negated.
     * @see #between(Object, Object)
     */
    public Expression notBetween(char leftChar, char rightChar) {
        return notBetween(Character.valueOf(leftChar), Character.valueOf(rightChar));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is not between two other values.
     * Equivalent to between negated.
     * @see #between(Object, Object)
     */
    public Expression notBetween(double leftValue, double rightValue) {
        return notBetween(Double.valueOf(leftValue), Double.valueOf(rightValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is not between two other values.
     * Equivalent to between negated.
     * @see #between(Object, Object)
     */
    public Expression notBetween(float leftValue, float rightValue) {
        return notBetween(Float.valueOf(leftValue), Float.valueOf(rightValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is not between two other values.
     * Equivalent to between negated.
     * @see #between(Object, Object)
     */
    public Expression notBetween(int leftValue, int rightValue) {
        return notBetween(Integer.valueOf(leftValue), Integer.valueOf(rightValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is not between two other values.
     * Equivalent to between negated.
     * @see #between(Object, Object)
     */
    public Expression notBetween(long leftValue, long rightValue) {
        return notBetween(Long.valueOf(leftValue), Long.valueOf(rightValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is not between two other values.
     * Equivalent to between negated.
     * @see #between(Object, Object)
     */
    public Expression notBetween(Object leftValue, Object rightValue) {
        return between(leftValue, rightValue).not();
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is not between two other values.
     * Equivalent to between negated.
     * @see #between(Object, Object)
     */
    public Expression notBetween(Expression leftExpression, Expression rightExpression) {
        return between(leftExpression, rightExpression).not();
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is not between two other values.
     * Equivalent to between negated.
     * @see #between(Object, Object)
     */
    public Expression notBetween(short leftValue, short rightValue) {
        return notBetween(Short.valueOf(leftValue), Short.valueOf(rightValue));
    }

    /**
     * PUBLIC: A logical expression for the collection <code>attributeName</code>
     * not being empty.
     * Equivalent to <code>size(attributeName).greaterThan(0)</code>
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.notEmpty("phoneNumbers")
     *     Java: employee.getPhoneNumbers().size() {@literal >} 0
     *     SQL: SELECT ... FROM EMP t0 WHERE (
     *      (SELECT COUNT(*) FROM PHONE t1 WHERE (t0.EMP_ID = t1.EMP_ID)) {@literal >} 0)
     * </pre></blockquote>
     * This is a case where a fast operation in java does not translate to an
     * equally fast operation in SQL, requiring a correlated subselect.
     * @see #size(java.lang.String)
     */
    public Expression notEmpty(String attributeName) {
        return size(attributeName).greaterThan(0);
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is not equal to the other value.
     * This is equivalent to the SQL {@literal "<>"} operator
     *
     * @see #equal(Object)
     */
    public Expression notEqual(byte theValue) {
        return notEqual(Byte.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is not equal to the other value.
     * This is equivalent to the SQL {@literal "<>"} operator
     *
     * @see #equal(Object)
     */
    public Expression notEqual(char theChar) {
        return notEqual(Character.valueOf(theChar));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is not equal to the other value.
     * This is equivalent to the SQL {@literal "<>"} operator
     *
     * @see #equal(Object)
     */
    public Expression notEqual(double theValue) {
        return notEqual(Double.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is not equal to the other value.
     * This is equivalent to the SQL {@literal "<>"} operator
     *
     * @see #equal(Object)
     */
    public Expression notEqual(float theValue) {
        return notEqual(Float.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is not equal to the other value.
     * This is equivalent to the SQL {@literal "<>"} operator
     *
     * @see #equal(Object)
     */
    public Expression notEqual(int theValue) {
        return notEqual(Integer.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is not equal to the other value.
     * This is equivalent to the SQL {@literal "<>"} operator
     *
     * @see #equal(Object)
     */
    public Expression notEqual(long theValue) {
        return notEqual(Long.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is not equal to the other value.
     * This is equivalent to the SQL {@literal "<>"} operator
     *
     * @see #equal(Object)
     */
    public Expression notEqual(Object theValue) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.NotEqual);
        return anOperator.expressionFor(this, theValue);
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is not equal to the other value.
     * This is equivalent to the SQL {@literal "<>"} operator
     *
     * @see #equal(Object)
     */
    public Expression notEqual(Expression theValue) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.NotEqual);
        return anOperator.expressionFor(this, theValue);
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is not equal to the other value.
     * This is equivalent to the SQL {@literal "<>"} operator
     *
     * @see #equal(Object)
     */
    public Expression notEqual(short theValue) {
        return notEqual(Short.valueOf(theValue));
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is not equal to the other value.
     * This is equivalent to the SQL {@literal "<>"} operator
     *
     * @see #equal(Object)
     */
    public Expression notEqual(boolean theBoolean) {
        return notEqual(Boolean.valueOf(theBoolean));
    }

    /**
     * PUBLIC:
     * Return a sub query expression.
     * A sub query using a report query to define a subselect within another queries expression or select's where clause.
     * The sub query (the report query) will use its own expression builder be can reference expressions from the base expression builder.
     * <p>Example:
     * <blockquote><pre>
     * ExpressionBuilder builder = new ExpressionBuilder();
     * ReportQuery subQuery = new ReportQuery(Employee.class, new ExpressionBuilder());
     * subQuery.setSelectionCriteria(subQuery.getExpressionBuilder().get("name").equal(builder.get("name")));
     * builder.notExists(subQuery);
     * </pre></blockquote>
     */
    public Expression notExists(ReportQuery subQuery) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.NotExists);
        return anOperator.expressionFor(subQuery(subQuery));
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression notIn(byte[] theBytes) {
        List values = new ArrayList(theBytes.length);

        for (int index = 0; index < theBytes.length; index++) {
            values.add(theBytes[index]);
        }

        return notIn(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression notIn(char[] theChars) {
        List values = new ArrayList(theChars.length);

        for (int index = 0; index < theChars.length; index++) {
            values.add(theChars[index]);
        }

        return notIn(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression notIn(double[] theDoubles) {
        List values = new ArrayList(theDoubles.length);

        for (int index = 0; index < theDoubles.length; index++) {
            values.add(theDoubles[index]);
        }

        return notIn(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression notIn(float[] theFloats) {
        List values = new ArrayList(theFloats.length);

        for (int index = 0; index < theFloats.length; index++) {
            values.add(theFloats[index]);
        }

        return notIn(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression notIn(int[] theInts) {
        List values = new ArrayList(theInts.length);

        for (int index = 0; index < theInts.length; index++) {
            values.add(theInts[index]);
        }

        return notIn(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression notIn(long[] theLongs) {
        List values = new ArrayList(theLongs.length);

        for (int index = 0; index < theLongs.length; index++) {
            values.add(theLongs[index]);
        }

        return notIn(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression notIn(Object[] theObjects) {
        List values = new ArrayList(theObjects.length);

        for (int index = 0; index < theObjects.length; index++) {
            values.add(theObjects[index]);
        }

        return notIn(values);
    }

    public Expression notIn(ReportQuery subQuery) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.NotInSubQuery);
        return anOperator.expressionFor(this, subQuery);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression notIn(short[] theShorts) {
        List values = new ArrayList(theShorts.length);

        for (int index = 0; index < theShorts.length; index++) {
            values.add(theShorts[index]);
        }

        return notIn(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression notIn(boolean[] theBooleans) {
        List values = new ArrayList(theBooleans.length);

        for (int index = 0; index < theBooleans.length; index++) {
            values.add(theBooleans[index]);
        }

        return notIn(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * The collection can be a collection of constants or expressions.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.get("age").in(ages)
     *     Java: ages.contains(employee.getAge())
     *     SQL: AGE IN (55, 18, 30)
     * </pre></blockquote>
     */
    public Expression notIn(Collection theObjects) {
        return notIn(new CollectionExpression(theObjects, this));
    }

    public Expression notIn(Expression arguments) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.NotIn);
        return anOperator.expressionFor(this, arguments);
    }

    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is not like the other value.
     * Equivalent to like negated.
     * @see #like(String)
     */
    public Expression notLike(String aString) {
        return notLike(new ConstantExpression(aString, this));
    }


    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is not like the other value.
     * Equivalent to like negated.
     * @see #like(String)
     */
    public Expression notLike(Expression arguments) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.NotLike);
        return anOperator.expressionFor(this, arguments);
    }
    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is not like the other value.
     * Equivalent to like negated.
     * @param value string to compare
     * @param escapeSequence the escape character to use
     * @see #like(String)
     */
    public Expression notLike(String value, String escapeSequence) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.NotLikeEscape);
        List args = new ArrayList(2);
        args.add(value);
        args.add(escapeSequence);
        return anOperator.expressionForArguments(this, args);
    }
    /**
     * PUBLIC:
     * Return an expression that compares if the receivers value is not like the other value.
     * Equivalent to like negated.
     * @param value string to compare
     * @param escapeSequence the escape character to use
     * @see #like(String)
     */
    public Expression notLike(Expression value, Expression escapeSequence) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.NotLikeEscape);
        List args = new ArrayList(2);
        args.add(value);
        args.add(escapeSequence);
        return anOperator.expressionForArguments(this, args);
    }

    /**
     * PUBLIC:
     * Return an expression representing a comparison to null
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.get("age").notNull()
     *     Java: employee.getAge() != null
     *     SQL: AGE IS NOT NULL
     * </pre></blockquote>
     */
    public Expression notNull() {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.NotNull);
        return anOperator.expressionFor(this);
    }

    /**
     * PUBLIC:
     * Return an expression that is the boolean logical combination of both expressions.
     * This is equivalent to the SQL "OR" operator and the Java "||" operator.
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.get("firstName").equal("Bob").OR(employee.get("lastName").equal("Smith"))
     *     Java: (employee.getFirstName().equals("Bob")) || (employee.getLastName().equals("Smith"))
     *     SQL: F_NAME = 'Bob' OR L_NAME = 'Smith'
     * </pre></blockquote>
     */
    public Expression or(Expression theExpression) {
        // Allow ands with null.
        if (theExpression == null) {
            return this;
        }

        ExpressionBuilder base = getBuilder();
        Expression expressionToUse = theExpression;

        // Ensure the same builder, unless a parralel query is used.
        if ((theExpression.getBuilder() != base) && (theExpression.getBuilder().getQueryClass() == null)) {
            expressionToUse = theExpression.rebuildOn(base);
        }

        if (base == this) {// Allow and to be sent to the builder.
            return expressionToUse;
        }

        ExpressionOperator anOperator = getOperator(ExpressionOperator.Or);
        return anOperator.expressionFor(this, expressionToUse);
    }

    /**
     * INTERNAL:
     */
    public Expression performOperator(ExpressionOperator anOperator, List args) {
        return anOperator.expressionForArguments(this, args);
    }

    protected void postCopyIn(Map alreadyDone) {
    }

    /**
     * ADVANCED:
     * Inserts the SQL as is directly into the expression.
     * The sql will be printed immediately after (postfixed to) the sql for
     * <b>this</b>.
     * Warning: Allowing an unverified SQL string to be passed into this
     * method makes your application vulnerable to SQL injection attacks.
     */
    public Expression postfixSQL(String sqlString) {
        ExpressionOperator anOperator = new ExpressionOperator();
        anOperator.setType(ExpressionOperator.FunctionOperator);
        List<String> v = new ArrayList<>(1);
        v.add(sqlString);
        anOperator.printsAs(v);
        anOperator.bePostfix();
        anOperator.setNodeClass(ClassConstants.FunctionExpression_Class);

        return anOperator.expressionFor(this);
    }

    /**
     * ADVANCED:
     * Insert the SQL as is directly into the expression.
     * The sql will be printed immediately before (prefixed to) the sql for
     * <b>this</b>.
      * Warning: Allowing an unverified SQL string to be passed into this
     * method makes your application vulnerable to SQL injection attacks.
     */
    public Expression prefixSQL(String sqlString) {
        ExpressionOperator anOperator = new ExpressionOperator();
        anOperator.setType(ExpressionOperator.FunctionOperator);
        List<String> v = new ArrayList<>(1);
        v.add(sqlString);
        anOperator.printsAs(v);
        anOperator.bePrefix();
        anOperator.setNodeClass(ClassConstants.FunctionExpression_Class);

        return anOperator.expressionFor(this);
    }

    /**
     * INTERNAL:
     * Print SQL
     */
    public abstract void printSQL(ExpressionSQLPrinter printer);

    /**
     * INTERNAL:
     * Print java for project class generation
     */
    public void printJava(ExpressionJavaPrinter printer) {
        //do nothing
    }

    /**
     * INTERNAL:
     * This expression is built on a different base than the one we want. Rebuild it and
     * return the root of the new tree
     * If receiver is a complex expression, use cloneUsing(newBase) instead.
     * @see #cloneUsing(Expression newBase)
     */
    public abstract Expression rebuildOn(Expression newBase);

    /**
     * INTERNAL:
     * Search the tree for any expressions (like SubSelectExpressions) that have been
     * built using a builder that is not attached to the query.  This happens in case of an Exists
     * call using a new ExpressionBuilder().  This builder needs to be replaced with one from the query.
     */
    public abstract void resetPlaceHolderBuilder(ExpressionBuilder queryBuilder);

    /**
     * ADVANCED:
     * For Object-relational support.
     */
    public Expression ref() {
        return getFunction(ExpressionOperator.Ref);
    }

    protected Expression registerIn(Map alreadyDone) {
        Expression copy = shallowClone();
        alreadyDone.put(this, copy);
        copy.postCopyIn(alreadyDone);
        return copy;

    }

    /**
     * PUBLIC:
     * Function, returns the string with occurances of the first substring replaced with the second substring.
     */
    public Expression replace(Object stringToReplace, Object stringToReplaceWith) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Replace);
        List args = new ArrayList(2);
        args.add(stringToReplace);
        args.add(stringToReplaceWith);
        return anOperator.expressionForArguments(this, args);
    }

    /**
     * PUBLIC:
     * return the result of this query repeated a given number of times.
     * Equivalent of the Sybase REPLICATE function
     * <p>Example:
     * <blockquote><pre>
     * EclipseLink: employee.get("name").replicate(2)
     * Java: NA
     * SQL: REPLICATE(name, 2)
     * </pre></blockquote>
     */
    public Expression replicate(int constant) {
        return replicate(Integer.valueOf(constant));
    }

    /**
     * PUBLIC:
     * return the result of this query repeated a given number of times.
     * Equivalent of the Sybase REPLICATE function
     * <p>Example:
     * <blockquote><pre>
     * EclipseLink: employee.get("name").replicate(2)
     * Java: NA
     * SQL: REPLICATE(name, 2)
     * </pre></blockquote>
     */
    public Expression replicate(Object theValue) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Replicate);
        return anOperator.expressionFor(this, theValue);
    }

    /**
     * Reset cached information here so that we can be sure we're accurate.
     */
    protected void resetCache() {
    }

    /**
     * PUBLIC:
     * Function return the reverse of the query result. Equivalent of the
     * Sybase REVERSE function
     * <p>Example:
     * <blockquote><pre>
     * EclipseLink: employee.get("name").reverse()
     * Java: NA
     * SQL: REVERSE(name)
     * </pre></blockquote>
     */
    public Expression reverse() {
        return getFunction(ExpressionOperator.Reverse);
    }

    /**
     * PUBLIC:
     * Function return a given number of characters starting at the
     * right of a string. Equivalent to the Sybase RIGHT function
     * <p>Example:
     * <blockquote><pre>
     * EclipseLink: employee.get("name").right(2)
     * Java: NA
     * SQL: RIGHT(name, 2)
     * </pre></blockquote>
     */
    public Expression right(int characters) {
        return right(Integer.valueOf(characters));
    }

    /**
     * PUBLIC:
     * Function return a given number of characters starting at the
     * right of a string. Equivalent to the Sybase RIGHT function
     * <p>Example:
     * <blockquote><pre>
     * EclipseLink: employee.get("name").right(2)
     * Java: NA
     * SQL: RIGHT(name, 2)
     * </pre></blockquote>
     */
    public Expression right(Object characters) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Right);
        return anOperator.expressionFor(this, characters);
    }

    /**
     * PUBLIC:
     * Function, returns the string padded with the substring to the size.
     */
    public Expression rightPad(int size, Object substring) {
        return rightPad(Integer.valueOf(size), substring);
    }

    /**
     * PUBLIC:
     * Function, returns the string padded with the substring to the size.
     */
    public Expression rightPad(Object size, Object substring) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.RightPad);
        List args = new ArrayList(2);
        args.add(size);
        args.add(substring);
        return anOperator.expressionForArguments(this, args);
    }

    /**
     * PUBLIC:
     * Function, returns the string right trimmed for white space.
     */
    public Expression rightTrim() {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.RightTrim);
        return anOperator.expressionFor(this);
    }

    /**
     * PUBLIC:
     * Function, returns the string with the substring trimed from the right.
     */
    public Expression rightTrim(Object substring) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.RightTrim2);
        return anOperator.expressionFor(this, substring);
    }

    /**
     * PUBLIC:
     * Function, returns the date rounded to the year, month or day.
     */
    public Expression roundDate(Object yearOrMonthOrDayRoundToken) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.RoundDate);
        return anOperator.expressionFor(this, yearOrMonthOrDayRoundToken);
    }

    /**
     * PUBLIC:
     * Return whether this expression should be included in the SELECT clause if it is used
     * in an ORDER BY clause
     */
    public boolean selectIfOrderedBy() {
        return selectIfOrderedBy;
    }

    /**
     * INTERNAL:
     * Set the local base expression, ie the one on the other side of the operator
     * Most types will ignore this, since they don't need it.
     */
    public void setLocalBase(Expression exp) {
    }

    /**
     * PUBLIC:
     * Set whether this expression should be included in the SELECT clause of a query
     * that uses it in the ORDER BY clause.
     *
     */
    public void setSelectIfOrderedBy(boolean selectIfOrderedBy) {
        this.selectIfOrderedBy = selectIfOrderedBy;
    }

    /**
     * INTERNAL:
     */
    public Expression shallowClone() {
        Expression result = null;
        try {
            result = (Expression)super.clone();
        } catch (CloneNotSupportedException exception) {
            throw new InternalError(exception.toString());
        }
        return result;
    }

    /**
     * PUBLIC: A logical expression for the size of collection <code>attributeName</code>.
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.size("phoneNumbers")
     *     Java: employee.getPhoneNumbers().size()
     *     SQL: SELECT ... FROM EMP t0 WHERE  ...
     *      (SELECT COUNT(*) FROM PHONE t1 WHERE (t0.EMP_ID = t1.EMP_ID))
     * </pre></blockquote>
     * This is a case where a fast operation in java does not translate to an
     * equally fast operation in SQL, requiring a correlated subselect.
     */
    public Expression size(String attributeName) {
        return SubSelectExpression.createSubSelectExpressionForCount(this, this, attributeName, null);
    }

    /**
     * PUBLIC: A logical expression for the size of collection expression.
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.size(Class returnType)
     *     Java: employee.getPhoneNumbers().size()
     *     SQL: SELECT ... FROM EMP t0 WHERE  ...
     *      (SELECT COUNT(*) FROM PHONE t1 WHERE (t0.EMP_ID = t1.EMP_ID))
     * </pre></blockquote>
     * This is a case where a fast operation in java does not translate to an
     * equally fast operation in SQL, requiring a correlated subselect.
     */
    public Expression size(Class returnType) {
        if (((BaseExpression)this).getBaseExpression() == null){
            return SubSelectExpression.createSubSelectExpressionForCount(this, this, null, returnType);
        }
        return SubSelectExpression.createSubSelectExpressionForCount(((BaseExpression)this).getBaseExpression(), this, null, returnType);
    }

    /**
     * PUBLIC:
     * This represents the aggregate function StandardDeviation. Can be used only within Report Queries.
     */
    public Expression standardDeviation() {
        return getFunction(ExpressionOperator.StandardDeviation);
    }

    /**
     * PUBLIC:
     * Return a sub query expression.
     * A sub query using a report query to define a subselect within another queries expression or select's where clause.
     * The sub query (the report query) will use its own expression builder be can reference expressions from the base expression builder.
     * <p>Example:
     * <blockquote><pre>
     * ExpressionBuilder builder = new ExpressionBuilder();
     * ReportQuery subQuery = new ReportQuery(Employee.class, new ExpressionBuilder());
     * subQuery.addMaximum("salary");
     * builder.get("salary").equal(builder.subQuery(subQuery));
     * </pre></blockquote>
     */
    public Expression subQuery(ReportQuery subQuery) {
        return new SubSelectExpression(subQuery, this);
    }

    /**
     * PUBLIC:
     * Function, returns the substring from the source string.
     * EclipseLink: employee.get("firstName").substring(1, 2)
     * Java: NA
     * SQL: SUBSTR(FIRST_NAME, 1, 2)
     */
    public Expression substring(int startPosition, int size) {
        return substring(Integer.valueOf(startPosition), Integer.valueOf(size));
    }

    /**
     * PUBLIC:
     * Function, returns the substring from the source string.
     * EclipseLink: employee.get("firstName").substring(1, 2)
     * Java: NA
     * SQL: SUBSTR(FIRST_NAME, 1, 2)
     */
    public Expression substring(Object startPosition, Object size) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Substring);
        List args = new ArrayList(2);
        args.add(startPosition);
        args.add(size);
        return anOperator.expressionForArguments(this, args);
    }

    /**
     * PUBLIC:
     * Function, returns the substring from the source string.
     * EclipseLink: employee.get("firstName").substring(1)
     * Java: NA
     * SQL: SUBSTR(FIRST_NAME, 1)
     */
    public Expression substring(int startPosition) {
        return substring(Integer.valueOf(startPosition));
    }

    /**
     * PUBLIC:
     * Function, returns the substring from the source string.
     * EclipseLink: employee.get("firstName").substring(1)
     * Java: NA
     * SQL: SUBSTR(FIRST_NAME, 1)
     */
    public Expression substring(Object startPosition) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.SubstringSingleArg);
        List args = new ArrayList(1);
        args.add(startPosition);
        return anOperator.expressionForArguments(this, args);
    }

    /**
     * PUBLIC:
     * This represents the aggregate function Sum. Can be used only within Report Queries.
     */
    public Expression sum() {
        return getFunction(ExpressionOperator.Sum);
    }

    /**
     * PUBLIC:
     * Function, returns the single character string with the ascii or character set value.
     */
    public Expression toCharacter() {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Chr);
        return anOperator.expressionFor(this);
    }

    /**
     * PUBLIC:
     * Function, returns date from the string using the default format.
     */
    public Expression toDate() {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.ToDate);
        return anOperator.expressionFor(this);
    }

    /**
     * PUBLIC:
     * Return an expression that represents the receiver value converted to a character string.
     * This is equivalent to the SQL "TO_CHAR" operator and Java "toString" method.
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.get("salary").toChar().equal("100000")
     *     Java: employee.getSalary().toString().equals("100000")
     *     SQL: TO_CHAR(SALARY) = '100000'
     * </pre></blockquote>
     */
    public Expression toChar() {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.ToChar);
        return anOperator.expressionFor(this);
    }

    /**
     * PUBLIC:
     * Return an expression that represents the receiver value converted to a character string,
     * with the database formating options (i.e. 'year', 'yyyy', 'day', etc.).
     * This is equivalent to the SQL "TO_CHAR" operator and Java Date API.
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.get("startDate").toChar("day").equal("monday")
     *     Java: employee.getStartDate().getDay().equals("monday")
     *     SQL: TO_CHAR(START_DATE, 'day') = 'monday'
     * </pre></blockquote>
     */
    public Expression toChar(String format) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.ToCharWithFormat);
        return anOperator.expressionFor(this, format);
    }

    /**
     * PUBLIC:
     * Return an expression that represents the receiver value converted to lower case.
     * This is equivalent to the SQL "LOWER" operator and Java "toLowerCase" method.
     * This is only allowed for String attribute values.
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.get("firstName").toLowerCase().equal("bob")
     *     Java: employee.getFirstName().toLowerCase().equals("bob")
     *     SQL: LOWER(F_NAME) = 'bob'
     * </pre></blockquote>
     */
    public Expression toLowerCase() {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.ToLowerCase);
        return anOperator.expressionFor(this);
    }

    /**
     * PUBLIC:
     * Function, returns the number converted from the string.
     */
    public Expression toNumber() {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.ToNumber);
        return anOperator.expressionFor(this);
    }

    /**
     * PUBLIC:
     * Print a debug form of the expression tree.
     */
    @Override
    public String toString() {
        try {
            StringWriter innerWriter = new StringWriter();
            BufferedWriter outerWriter = new BufferedWriter(innerWriter);
            toString(outerWriter, 0);
            outerWriter.flush();
            return innerWriter.toString();
        } catch (IOException e) {
            return ToStringLocalization.buildMessage("error_printing_expression", null);
        }
    }

    /**
     * INTERNAL:
     * Print a debug form of the expression tree.
     */
    public void toString(BufferedWriter writer, int indent) throws IOException {
        writer.newLine();
        for (int i = 0; i < indent; i++) {
            writer.write("   ");
        }
        writer.write(descriptionOfNodeType());
        writer.write(" ");
        writeDescriptionOn(writer);
        writeSubexpressionsTo(writer, indent + 1);
    }

    /**
     * PUBLIC:
     * Return an expression that represents the receiver value converted to upper case.
     * This is equivalent to the SQL "UPPER" operator and Java "toUpperCase" method.
     * This is only allowed for String attribute values.
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.get("firstName").toUpperCase().equal("BOB")
     *     Java: employee.getFirstName().toUpperCase().equals("BOB")
     *     SQL: UPPER(F_NAME) = 'BOB'
     * </pre></blockquote>
     */
    public Expression toUpperCase() {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.ToUpperCase);
        return anOperator.expressionFor(this);
    }

    /**
     * PUBLIC:
     * Function, returns the string with the first letter of each word capitalized.
     */
    public Expression toUppercaseCasedWords() {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Initcap);
        return anOperator.expressionFor(this);
    }

    /**
     * PUBLIC:
     * Function, returns the string with each char from the from string converted to the char in the to string.
     */
    public Expression translate(Object fromString, Object toString) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Translate);
        List args = new ArrayList(2);
        args.add(fromString);
        args.add(toString);
        return anOperator.expressionForArguments(this, args);
    }

    /**
     * PUBLIC:
     * Function, returns the string trimmed for white space.
     */
    public Expression trim() {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Trim);
        return anOperator.expressionFor(this);
    }

    /**
     * PUBLIC:
     * Function, returns the string right and left trimmed for the substring.
     */
    public Expression trim(Object substring) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Trim2);
        return anOperator.expressionFor(this, substring);
    }

    /**
     * PUBLIC:
     * XMLType Function, extracts a secton of XML from a larget XML document
     * @param xpath XPath expression representing the node to be returned
     */
    public Expression extractXml(String xpath) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.ExtractXml);
        return anOperator.expressionFor(this, xpath);
    }

    /**
     * PUBLIC:
     * Extract the date part from the date/time value.
     * EXTRACT is part of the SQL standard, so should be supported by most databases.
     * @param part is the date part to extract, "YEAR", "MONTH", "DAY", "HOUR", "MINUTE", "SECOND", "TIMEZONE_HOUR", "TIMEZONE_MINUTE".
     */
    public Expression extract(String part) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Extract);
        return anOperator.expressionFor(this, literal(part));
    }

    /**
     * PUBLIC:
     * Cast the value to the database type.
     * CAST is part of the SQL standard, so should be supported by most databases.
     * @param type is the database type name, this is database specific but should include, "CHAR", "VARCHAR", "NUMERIC", "INTEGER", "DATE", "TIME", "TIMESTAMP",
     * the type may include a size and scale.
     */
    public Expression cast(String type) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Cast);
        return anOperator.expressionFor(this, literal(type));
    }

    /**
     * PUBLIC:
     * XMLType Function, extracts a value from an XMLType field
     * @param xpath XPath expression
     */
    public Expression extractValue(String xpath) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.ExtractValue);
        return anOperator.expressionFor(this, xpath);
    }

    /**
     * PUBLIC:
     * XMLType Function, gets the number of nodes returned by the given xpath expression
     * returns 0 if there are none
     * @param xpath Xpath expression
     */
    public Expression existsNode(String xpath) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.ExistsNode);
        return anOperator.expressionFor(this, xpath);
    }

    /**
     * PUBLIC:
     * XMLType Function - evaluates to 0 if the xml is a well formed document and 1 if the document
     * is a fragment
     */
    public Expression isFragment() {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.IsFragment);
        return anOperator.expressionFor(this);
    }

    /**
     * PUBLIC:
     * XMLType Function - gets a string value from an XMLType
     */
    public Expression getStringVal() {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.GetStringVal);
        return anOperator.expressionFor(this);
    }

    /**
     * PUBLIC:
     * XMLType Function - gets a number value from an XMLType
     */
    public Expression getNumberVal() {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.GetNumberVal);
        return anOperator.expressionFor(this);
    }

    /**
     * PUBLIC:
     * return the date truncated to the indicated datePart. Equivalent
     * to the Sybase TRUNC function for dates
     * <p>Example:
     * <blockquote><pre>
     * EclipseLink: employee.get("date").truncDate(year)
     * Java: NA
     * SQL: TRUNC(date, year)
     * </pre></blockquote>
     */
    public Expression truncateDate(String datePart) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.TruncateDate);
        return anOperator.expressionFor(this, datePart);

    }

    /**
     * INTERNAL:
     * We are given an expression that comes from a different context than the one in which this was built,
     * e.g. it is the selection criteria of a mapping, or the criteria on which multiple tables are joined in a descriptor.
     * We need to transform it so it refers to the objects we are dealing with, and AND it into the rest of our expression.
     *
     * We want to replace the original base expression with (newBase), and any parameters will be given values based
     * on the context which (this) provides.
     *
     * For example, suppose that the main expression is
     *      emp.address.streetName = 'something'
     * and we are trying to twist the selection criteria for the mapping 'address' in Employee. Because that mapping
     * selects addresses, we will use the 'address' node as the base. Values for any parameters will come from the 'emp' node,
     * which was the base of the original expression. Note that the values need not be constants, they can be fields.
     *
     * We do this by taking the tree we're trying to merge and traverse it more or less re-executing it
     * it with the appropriate initial receiver and context.
     * Return the root of the new expression tree. This will probably need to be AND'ed with the root of the old tree.
     */
    public Expression twist(Expression expression, Expression newBase) {
        if (expression == null) {
            return null;
        }
        return expression.twistedForBaseAndContext(newBase, this, null);

    }

    /**
     * INTERNAL:
     * Rebuild myself against the base, with the values of parameters supplied by the context
     * expression. This is used for transforming a standalone expression (e.g. the join criteria of a mapping)
     * into part of some larger expression. You normally would not call this directly, instead calling twist
     * See the comment there for more details"
     */
    public Expression twistedForBaseAndContext(Expression newBase, Expression context, Expression oldBase) {
        // Will be overridden by subclasses
        return this;
    }

    /**
     * INTERNAL:
     * Do any required validation for this node. Throw an exception for any incorrect constructs.
     */
    public void validateNode() {
    }

    /**
     * PUBLIC:
     * Function, this represents the value function, used in nestedtable
     */
    public Expression value() {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Value);
        return anOperator.expressionFor(this);
    }

    /**
     * PUBLIC:
     * Return an expression on the constant.
     * <p>Example:
     * <blockquote><pre>
     * reportQuery.addItem("a constant", builder.value("a constant"));
     * </pre></blockquote>
     */
    public Expression value(byte constant) {
        return value(Byte.valueOf(constant));
    }

    /**
     * PUBLIC:
     * Return an expression on the constant.
     * <p>Example:
     * <blockquote><pre>
     * reportQuery.addItem("a constant", builder.value("a constant"));
     * </pre></blockquote>
     */
    public Expression value(char constant) {
        return value(Character.valueOf(constant));
    }

    /**
     * PUBLIC:
     * Return an expression on the constant.
     * <p>Example:
     * <blockquote><pre>
     * reportQuery.addItem("a constant", builder.value("a constant"));
     * </pre></blockquote>
     */
    public Expression value(double constant) {
        return value(Double.valueOf(constant));
    }

    /**
     * PUBLIC:
     * Return an expression on the constant.
     * <p>Example:
     * <blockquote><pre>
     * reportQuery.addItem("a constant", builder.value("a constant"));
     * </pre></blockquote>
     */
    public Expression value(float constant) {
        return value(Float.valueOf(constant));
    }

    /**
     * PUBLIC:
     * Return an expression on the constant.
     * <p>Example:
     * <blockquote><pre>
     * reportQuery.addItem("a constant", builder.value("a constant"));
     * </pre></blockquote>
     */
    public Expression value(int constant) {
        return value(Integer.valueOf(constant));
    }

    /**
     * PUBLIC:
     * Return an expression on the constant.
     * <p>Example:
     * <blockquote><pre>
     * reportQuery.addItem("a constant", builder.value("a constant"));
     * </pre></blockquote>
     */
    public Expression value(long constant) {
        return value(Long.valueOf(constant));
    }

    /**
     * PUBLIC:
     * Return an expression on the constant.
     * <p>Example:
     * <blockquote><pre>
     * reportQuery.addItem("a constant", builder.value("a constant"));
     * </pre></blockquote>
     */
    public Expression value(Object constant) {
        return new ConstantExpression(constant, this);
    }

    /**
     * PUBLIC:
     * Return an expression on the constant.
     * <p>Example:
     * <blockquote><pre>
     * reportQuery.addItem("a constant", builder.value("a constant"));
     * </pre></blockquote>
     */
    public Expression value(short constant) {
        return value(Short.valueOf(constant));
    }

    /**
     * PUBLIC:
     * Return an expression on the constant.
     * <p>Example:
     * <blockquote><pre>
     * reportQuery.addItem("a constant", builder.value("a constant"));
     * </pre></blockquote>
     */
    public Expression value(boolean constant) {
        return value(Boolean.valueOf(constant));
    }

    /**
     * ADVANCED:
     * Return an expression on the literal.
     * A literal is a specific SQL syntax string that will be printed as is without quotes in the SQL.
     * It can be useful for printing database key words or global variables.
     * <p>Example:
     * <blockquote><pre>
     * reportQuery.addItem("currentTime", builder.literal("SYSDATE"));
     * </pre></blockquote>
     */
    public Expression literal(String literal) {
        return new LiteralExpression(literal, this);
    }

    /**
     * ADVANCED:
     * Return an expression for the alias.
     * This allows an alias used in the select clause to be used in other clauses.
     */
    public Expression alias(String alias) {
        return literal(alias);
    }

    /**
     * INTERNAL:
     * Return the value for in memory comparison.
     * This is only valid for valueable expressions.
     * New parameter added for feature 2612601
     * @param isObjectUnregistered true if object possibly not a clone, but is being
     * conformed against the unit of work cache.
     */
    public Object valueFromObject(Object object, AbstractSession session, AbstractRecord translationRow, int valueHolderPolicy, boolean isObjectUnregistered) {
        throw QueryException.cannotConformExpression();
    }

    /**
     * INTERNAL:
     * Return the value for in memory comparison.
     * This is only valid for valueable expressions.
     */
    public Object valueFromObject(Object object, AbstractSession session, AbstractRecord translationRow, int valueHolderPolicy) {
        return valueFromObject(object, session, translationRow, valueHolderPolicy, false);
    }

    /**
     * PUBLIC:
     * Function, this represents the aggregate function Variance. Can be used only within Report Queries.
     */
    public Expression variance() {
        return getFunction(ExpressionOperator.Variance);
    }

    /**
     * INTERNAL:
     * Used to print a debug form of the expression tree.
     */
    public void writeDescriptionOn(BufferedWriter writer) throws IOException {
        writer.write("some expression");
    }

    /**
     * INTERNAL:
     * Append the field name to the writer. Should be overridden for special operators such as functions.
     */
    protected void writeField(ExpressionSQLPrinter printer, DatabaseField field, SQLSelectStatement statement) {
        //print ", " before each selected field except the first one
        if (printer.isFirstElementPrinted()) {
            printer.printString(", ");
        } else {
            printer.setIsFirstElementPrinted(true);
        }

        if (statement.requiresAliases()) {
            if (field.getTable() != lastTable) {
                lastTable = field.getTable();
                currentAlias = aliasForTable(lastTable);
            }
            printer.printString(currentAlias.getQualifiedNameDelimited(printer.getPlatform()));
            printer.printString(".");
        }
        printer.printString(field.getNameDelimited(printer.getPlatform()));

        //bug6070214: unique field aliases need to be generated when required.
        if (statement.getUseUniqueFieldAliases()){
            printer.printString(" AS " + statement.generatedAlias(field.getNameDelimited(printer.getPlatform())));
        }
    }

    /**
     * INTERNAL:
     * Append the field's alias to the writer.
     * This is used for pessimistic locking.
     */
    protected void writeAlias(ExpressionSQLPrinter printer, DatabaseField field, SQLSelectStatement statement) {
        //print ", " before each selected field except the first one
        if (printer.isFirstElementPrinted()) {
            printer.printString(", ");
        } else {
            printer.setIsFirstElementPrinted(true);
        }

        if (statement.requiresAliases()) {
            if (field.getTable() != this.lastTable) {
                this.lastTable = field.getTable();
                this.currentAlias = aliasForTable(this.lastTable);
            }
            printer.printString(this.currentAlias.getQualifiedNameDelimited(printer.getPlatform()));
        } else {
            printer.printString(field.getTable().getQualifiedNameDelimited(printer.getPlatform()));
        }
    }

    /**
     * INTERNAL:
     * called from SQLSelectStatement.writeFieldsFromExpression(...)
     */
    public void writeFields(ExpressionSQLPrinter printer, List<DatabaseField> newFields, SQLSelectStatement statement) {
        for (DatabaseField field : getSelectionFields(statement.getQuery())) {
            newFields.add(field);
            writeField(printer, field, statement);
        }
    }

    /**
     * INTERNAL:
     * Used in SQL printing.
     */
    public void writeSubexpressionsTo(BufferedWriter writer, int indent) throws IOException {
        // In general, there are no sub-expressions
    }

    /**
     *
     * PUBLIC:
     * Return an expression that is used with a comparison expression.
     * The ANY keyword denotes that the search condition is TRUE if the comparison is TRUE
     * for at least one of the values that is returned. If the subquery returns no value,
     * the search condition is FALSE
     */
    public Expression any(byte[] theBytes) {
        List values = new ArrayList(theBytes.length);

        for (int index = 0; index < theBytes.length; index++) {
            values.add(theBytes[index]);
        }

        return any(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression any(char[] theChars) {
        List values = new ArrayList(theChars.length);

        for (int index = 0; index < theChars.length; index++) {
            values.add(theChars[index]);
        }

        return any(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression any(double[] theDoubles) {
        List values = new ArrayList(theDoubles.length);

        for (int index = 0; index < theDoubles.length; index++) {
            values.add(theDoubles[index]);
        }

        return any(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression any(float[] theFloats) {
        List values = new ArrayList(theFloats.length);

        for (int index = 0; index < theFloats.length; index++) {
            values.add(theFloats[index]);
        }

        return any(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression any(int[] theInts) {
        List values = new ArrayList(theInts.length);

        for (int index = 0; index < theInts.length; index++) {
            values.add(theInts[index]);
        }

        return any(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression any(long[] theLongs) {
        List values = new ArrayList(theLongs.length);

        for (int index = 0; index < theLongs.length; index++) {
            values.add(theLongs[index]);
        }

        return any(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression any(Object[] theObjects) {
        List values = new ArrayList(theObjects.length);

        for (int index = 0; index < theObjects.length; index++) {
            values.add(theObjects[index]);
        }

        return any(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression any(short[] theShorts) {
        List values = new ArrayList(theShorts.length);

        for (int index = 0; index < theShorts.length; index++) {
            values.add(theShorts[index]);
        }

        return any(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression any(boolean[] theBooleans) {
        List values = new ArrayList(theBooleans.length);

        for (int index = 0; index < theBooleans.length; index++) {
            values.add(theBooleans[index]);
        }

        return any(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.get("age").in(ages)
     *     Java: ages.contains(employee.getAge())
     *     SQL: AGE IN (55, 18, 30)
     * </pre></blockquote>
     */
    public Expression any(List theObjects) {
        return any(new ConstantExpression(theObjects, this));
    }

    public Expression any(Expression arguments) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Any);
        return anOperator.expressionFor(this, arguments);
    }

    /**
     * PUBLIC:
     * Return a union expression with the subquery.
     */
    public Expression union(Expression arguments) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Union);
        return anOperator.expressionFor(this, arguments);
    }

    /**
     * PUBLIC:
     * Return a intersect expression with the subquery.
     */
    public Expression intersect(ReportQuery query) {
        return intersect(subQuery(query));
    }

    /**
     * PUBLIC:
     * Return a intersect all expression with the subquery.
     */
    public Expression intersectAll(ReportQuery query) {
        return intersectAll(subQuery(query));
    }

    /**
     * PUBLIC:
     * Return a intersect expression with the subquery.
     */
    public Expression intersect(Expression arguments) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Intersect);
        return anOperator.expressionFor(this, arguments);
    }

    /**
     * PUBLIC:
     * Return a except expression with the subquery.
     */
    public Expression except(ReportQuery query) {
        return except(subQuery(query));
    }

    /**
     * PUBLIC:
     * Return a except all expression with the subquery.
     */
    public Expression exceptAll(ReportQuery query) {
        return exceptAll(subQuery(query));
    }

    /**
     * PUBLIC:
     * Return a except expression with the subquery.
     */
    public Expression except(Expression arguments) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Except);
        return anOperator.expressionFor(this, arguments);
    }

    /**
     * PUBLIC:
     * Return a union expression with the subquery.
     */
    public Expression union(ReportQuery query) {
        return union(subQuery(query));
    }

    /**
     * PUBLIC:
     * Return a union all expression with the subquery.
     */
    public Expression unionAll(ReportQuery query) {
        return unionAll(subQuery(query));
    }

    /**
     * PUBLIC:
     * Return a union all expression with the subquery.
     */
    public Expression unionAll(Expression arguments) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.UnionAll);
        return anOperator.expressionFor(this, arguments);
    }

    /**
     * PUBLIC:
     * Return a intersect all expression with the subquery.
     */
    public Expression intersectAll(Expression arguments) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.IntersectAll);
        return anOperator.expressionFor(this, arguments);
    }

    /**
     * PUBLIC:
     * Return a except all expression with the subquery.
     */
    public Expression exceptAll(Expression arguments) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.ExceptAll);
        return anOperator.expressionFor(this, arguments);
    }

    public Expression any(ReportQuery subQuery) {
        return any(subQuery(subQuery));
    }

    /**
     * PUBLIC:
     * Return an expression that is used with a comparison expression.
     * The SOME keyword denotes that the search condition is TRUE if the comparison is TRUE
     * for at least one of the values that is returned. If the subquery returns no value,
     * the search condition is FALSE
     */
    public Expression some(byte[] theBytes) {
        List values = new ArrayList(theBytes.length);

        for (int index = 0; index < theBytes.length; index++) {
            values.add(theBytes[index]);
        }

        return some(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression some(char[] theChars) {
        List values = new ArrayList(theChars.length);

        for (int index = 0; index < theChars.length; index++) {
            values.add(theChars[index]);
        }

        return some(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression some(double[] theDoubles) {
        List values = new ArrayList(theDoubles.length);

        for (int index = 0; index < theDoubles.length; index++) {
            values.add(theDoubles[index]);
        }

        return some(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression some(float[] theFloats) {
        List values = new ArrayList(theFloats.length);

        for (int index = 0; index < theFloats.length; index++) {
            values.add(theFloats[index]);
        }

        return some(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression some(int[] theInts) {
        List values = new ArrayList(theInts.length);

        for (int index = 0; index < theInts.length; index++) {
            values.add(theInts[index]);
        }

        return some(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression some(long[] theLongs) {
        List values = new ArrayList(theLongs.length);

        for (int index = 0; index < theLongs.length; index++) {
            values.add(theLongs[index]);
        }

        return some(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression some(Object[] theObjects) {
        List values = new ArrayList(theObjects.length);

        for (int index = 0; index < theObjects.length; index++) {
            values.add(theObjects[index]);
        }

        return some(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression some(short[] theShorts) {
        List values = new ArrayList(theShorts.length);

        for (int index = 0; index < theShorts.length; index++) {
            values.add(theShorts[index]);
        }

        return some(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression some(boolean[] theBooleans) {
        List values = new ArrayList(theBooleans.length);

        for (int index = 0; index < theBooleans.length; index++) {
            values.add(theBooleans[index]);
        }

        return some(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.get("age").in(ages)
     *     Java: ages.contains(employee.getAge())
     *     SQL: AGE IN (55, 18, 30)
     * </pre></blockquote>
     */
    public Expression some(List theObjects) {
        return some(new ConstantExpression(theObjects, this));
    }

    public Expression some(Expression arguments) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.Some);
        return anOperator.expressionFor(this, arguments);
    }

    public Expression some(ReportQuery subQuery) {
        return some(subQuery(subQuery));
    }

    /**
     *
     * PUBLIC:
     * Return an expression that is used with a comparison expression.
     * The SOME keyword denotes that the search condition is TRUE if the comparison is TRUE
     * for at least one of the values that is returned. If the subquery returns no value,
     * the search condition is FALSE
     */
    public Expression all(byte[] theBytes) {
        List values = new ArrayList(theBytes.length);

        for (int index = 0; index < theBytes.length; index++) {
            values.add(theBytes[index]);
        }

        return all(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression all(char[] theChars) {
        List values = new ArrayList(theChars.length);

        for (int index = 0; index < theChars.length; index++) {
            values.add(theChars[index]);
        }

        return all(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression all(double[] theDoubles) {
        List values = new ArrayList(theDoubles.length);

        for (int index = 0; index < theDoubles.length; index++) {
            values.add(theDoubles[index]);
        }

        return all(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression all(float[] theFloats) {
        List values = new ArrayList(theFloats.length);

        for (int index = 0; index < theFloats.length; index++) {
            values.add(theFloats[index]);
        }

        return all(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression all(int[] theInts) {
        List values = new ArrayList(theInts.length);

        for (int index = 0; index < theInts.length; index++) {
            values.add(theInts[index]);
        }

        return all(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression all(long[] theLongs) {
        List values = new ArrayList(theLongs.length);

        for (int index = 0; index < theLongs.length; index++) {
            values.add(theLongs[index]);
        }

        return all(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression all(Object[] theObjects) {
        List values = new ArrayList(theObjects.length);

        for (int index = 0; index < theObjects.length; index++) {
            values.add(theObjects[index]);
        }

        return all(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression all(short[] theShorts) {
        List values = new ArrayList(theShorts.length);

        for (int index = 0; index < theShorts.length; index++) {
            values.add(theShorts[index]);
        }

        return all(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     */
    public Expression all(boolean[] theBooleans) {
        List values = new ArrayList(theBooleans.length);

        for (int index = 0; index < theBooleans.length; index++) {
            values.add(theBooleans[index]);
        }

        return all(values);
    }

    /**
     * PUBLIC:
     * Return an expression that checks if the receivers value is contained in the collection.
     * This is equivalent to the SQL "IN" operator and Java "contains" operator.
     * <p>Example:
     * <blockquote><pre>
     *     EclipseLink: employee.get("age").in(ages)
     *     Java: ages.contains(employee.getAge())
     *     SQL: AGE IN (55, 18, 30)
     * </pre></blockquote>
     */
    public Expression all(List theObjects) {
        return all(new ConstantExpression(theObjects, this));
    }

    public Expression all(Expression arguments) {
        ExpressionOperator anOperator = getOperator(ExpressionOperator.All);
        return anOperator.expressionFor(this, arguments);
    }

    public Expression all(ReportQuery subQuery) {
        return all(subQuery(subQuery));
    }

    /**
     * INTERNAL:
     * Lookup the descriptor for this item by traversing its expression recursively.
     */
    public ClassDescriptor getLeafDescriptor(DatabaseQuery query, ClassDescriptor rootDescriptor, AbstractSession session) {
        return null;
    }

    /**
     * INTERNAL:
     * Lookup the mapping for this item by traversing its expression recursively.
     * If an aggregate of foreign mapping is found it is traversed.
     */
    public DatabaseMapping getLeafMapping(DatabaseQuery query, ClassDescriptor rootDescriptor, AbstractSession session) {
        return null;
    }

}
