/*
 * 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
     */
    public 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((Object)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(Integer.valueOf(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(Byte.valueOf(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(Character.valueOf(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(Double.valueOf(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(Float.valueOf(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(Integer.valueOf(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(Long.valueOf(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(Short.valueOf(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(Boolean.valueOf(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()
     * @return
     */
    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()
     * @return
     */
    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(Byte.valueOf(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(Character.valueOf(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(Double.valueOf(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(Float.valueOf(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(Integer.valueOf(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(Long.valueOf(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(Short.valueOf(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(Boolean.valueOf(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.
     *
     * @param selectIfOrderedBy
     */
    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(Byte.valueOf(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(Character.valueOf(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(Double.valueOf(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(Float.valueOf(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(Integer.valueOf(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(Long.valueOf(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(Short.valueOf(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(Boolean.valueOf(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(Byte.valueOf(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(Character.valueOf(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(Double.valueOf(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(Float.valueOf(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(Integer.valueOf(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(Long.valueOf(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(Short.valueOf(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(Boolean.valueOf(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(Byte.valueOf(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(Character.valueOf(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(Double.valueOf(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(Float.valueOf(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(Integer.valueOf(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(Long.valueOf(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(Short.valueOf(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(Boolean.valueOf(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;
    }

}
