You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2015/05/23 12:44:41 UTC

[2/2] cayenne git commit: unit test reorg by expression type , some cleanup and fixing warnings

unit test reorg by expression type , some cleanup and fixing warnings


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/069b8fbb
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/069b8fbb
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/069b8fbb

Branch: refs/heads/master
Commit: 069b8fbb277e4cf2a3c11324e26fec32d02fc3ee
Parents: debfa94
Author: aadamchik <aa...@apache.org>
Authored: Sat May 23 13:18:10 2015 +0300
Committer: aadamchik <aa...@apache.org>
Committed: Sat May 23 13:43:53 2015 +0300

----------------------------------------------------------------------
 .../org/apache/cayenne/exp/parser/ASTAdd.java   | 150 ++--
 .../org/apache/cayenne/exp/parser/ASTAnd.java   | 167 ++--
 .../apache/cayenne/exp/parser/ASTBetween.java   | 120 +--
 .../cayenne/exp/parser/ASTBitwiseAnd.java       |  88 +-
 .../cayenne/exp/parser/ASTBitwiseLeftShift.java | 153 ++--
 .../apache/cayenne/exp/parser/ASTDivide.java    | 149 ++--
 .../org/apache/cayenne/exp/parser/ASTNot.java   | 102 +--
 .../exp/parser/ASTNotLikeIgnoreCase.java        | 106 +--
 .../apache/cayenne/exp/parser/ASTObjPath.java   | 147 +--
 .../org/apache/cayenne/exp/parser/ASTOr.java    | 135 +--
 .../org/apache/cayenne/exp/parser/ASTPath.java  | 145 +--
 .../exp/parser/AggregateConditionNode.java      | 140 ++-
 .../apache/cayenne/exp/parser/SimpleNode.java   | 887 ++++++++++---------
 .../cayenne/exp/parser/ASTBetweenTest.java      |  71 ++
 .../apache/cayenne/exp/parser/ASTDbPathIT.java  |  72 ++
 .../cayenne/exp/parser/ASTDbPathTest.java       |   2 -
 .../apache/cayenne/exp/parser/ASTEqualIT.java   | 112 +++
 .../apache/cayenne/exp/parser/ASTEqualTest.java |  84 ++
 .../cayenne/exp/parser/ASTGreaterTest.java      |  86 ++
 .../apache/cayenne/exp/parser/ASTLessTest.java  |  86 ++
 .../exp/parser/ASTLikeIgnoreCaseTest.java       |  24 +
 .../apache/cayenne/exp/parser/ASTLikeTest.java  |  86 ++
 .../apache/cayenne/exp/parser/ASTNotTest.java   |  46 +
 .../apache/cayenne/exp/parser/ASTObjPathIT.java |  49 +
 .../cayenne/exp/parser/ASTObjPathTest.java      |  54 +-
 .../parser/ExpressionEvaluateInMemoryIT.java    | 181 ----
 .../parser/ExpressionEvaluateInMemoryTest.java  | 316 -------
 27 files changed, 2011 insertions(+), 1747 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/069b8fbb/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTAdd.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTAdd.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTAdd.java
index 5c196c8..de484ef 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTAdd.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTAdd.java
@@ -28,80 +28,82 @@ import org.apache.cayenne.util.ConversionUtil;
 
 /**
  * "Add" Expression.
- * 
  */
 public class ASTAdd extends SimpleNode {
-    ASTAdd(int id) {
-        super(id);
-    }
-
-    public ASTAdd() {
-        super(ExpressionParserTreeConstants.JJTADD);
-    }
-
-    public ASTAdd(Object[] nodes) {
-        super(ExpressionParserTreeConstants.JJTADD);
-        int len = nodes.length;
-        for (int i = 0; i < len; i++) {
-            jjtAddChild(wrapChild(nodes[i]), i);
-        }
-        
-        connectChildren();
-    }
-
-    public ASTAdd(Collection nodes) {
-        super(ExpressionParserTreeConstants.JJTADD);
-        int len = nodes.size();
-        Iterator it = nodes.iterator();
-        for (int i = 0; i < len; i++) {
-            jjtAddChild(wrapChild(it.next()), i);
-        }
-        
-        connectChildren();
-    }
-
-    @Override
-    protected Object evaluateNode(Object o) throws Exception {
-        int len = jjtGetNumChildren();
-        if (len == 0) {
-            return null;
-        }
-
-        BigDecimal result = null;
-        for (int i = 0; i < len; i++) {
-            BigDecimal value = ConversionUtil.toBigDecimal(evaluateChild(i, o));
-
-            if (value == null) {
-                return null;
-            }
-
-            result = (i == 0) ? value : result.add(value);
-        }
-
-        return result;
-    }
-
-    /**
-     * Creates a copy of this expression node, without copying children.
-     */
-    @Override
-    public Expression shallowCopy() {
-        return new ASTAdd(id);
-    }
-
-    @Override
-    protected String getExpressionOperator(int index) {
-        return "+";
-    }
-
-    @Override
-    public int getType() {
-        return Expression.ADD;
-    }
-
-    @Override
-    public void jjtClose() {
-        super.jjtClose();
-        flattenTree();
-    }
+
+	private static final long serialVersionUID = -8622963819149351988L;
+
+	ASTAdd(int id) {
+		super(id);
+	}
+
+	public ASTAdd() {
+		super(ExpressionParserTreeConstants.JJTADD);
+	}
+
+	public ASTAdd(Object[] nodes) {
+		super(ExpressionParserTreeConstants.JJTADD);
+		int len = nodes.length;
+		for (int i = 0; i < len; i++) {
+			jjtAddChild(wrapChild(nodes[i]), i);
+		}
+
+		connectChildren();
+	}
+
+	public ASTAdd(Collection<?> nodes) {
+		super(ExpressionParserTreeConstants.JJTADD);
+		int len = nodes.size();
+		Iterator<?> it = nodes.iterator();
+		for (int i = 0; i < len; i++) {
+			jjtAddChild(wrapChild(it.next()), i);
+		}
+
+		connectChildren();
+	}
+
+	@Override
+	protected Object evaluateNode(Object o) throws Exception {
+		int len = jjtGetNumChildren();
+		if (len == 0) {
+			return null;
+		}
+
+		BigDecimal result = null;
+		for (int i = 0; i < len; i++) {
+			BigDecimal value = ConversionUtil.toBigDecimal(evaluateChild(i, o));
+
+			if (value == null) {
+				return null;
+			}
+
+			result = (i == 0) ? value : result.add(value);
+		}
+
+		return result;
+	}
+
+	/**
+	 * Creates a copy of this expression node, without copying children.
+	 */
+	@Override
+	public Expression shallowCopy() {
+		return new ASTAdd(id);
+	}
+
+	@Override
+	protected String getExpressionOperator(int index) {
+		return "+";
+	}
+
+	@Override
+	public int getType() {
+		return Expression.ADD;
+	}
+
+	@Override
+	public void jjtClose() {
+		super.jjtClose();
+		flattenTree();
+	}
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/069b8fbb/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTAnd.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTAnd.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTAnd.java
index 4732ba7..33fdcb1 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTAnd.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTAnd.java
@@ -32,86 +32,89 @@ import org.apache.cayenne.util.ConversionUtil;
  * @since 1.1
  */
 public class ASTAnd extends AggregateConditionNode implements ValueInjector {
-    /**
-     * Constructor used by expression parser. Do not invoke directly.
-     */
-    ASTAnd(int id) {
-        super(id);
-    }
-
-    public ASTAnd() {
-        super(ExpressionParserTreeConstants.JJTAND);
-    }
-
-    public ASTAnd(Object[] nodes) {
-        super(ExpressionParserTreeConstants.JJTAND);
-        int len = nodes.length;
-        for (int i = 0; i < len; i++) {
-            jjtAddChild((Node) nodes[i], i);
-        }
-        
-        connectChildren();
-    }
-
-    public ASTAnd(Collection<? extends Node> nodes) {
-        super(ExpressionParserTreeConstants.JJTAND);
-        int len = nodes.size();
-        Iterator<? extends Node> it = nodes.iterator();
-        for (int i = 0; i < len; i++) {
-            jjtAddChild(it.next(), i);
-        }
-        
-        connectChildren();
-    }
-
-    @Override
-    protected Object evaluateNode(Object o) throws Exception {
-        int len = jjtGetNumChildren();
-        if (len == 0) {
-            return Boolean.FALSE;
-        }
-
-        for (int i = 0; i < len; i++) {
-            if (!ConversionUtil.toBoolean(evaluateChild(i, o))) {
-                return Boolean.FALSE;
-            }
-        }
-
-        return Boolean.TRUE;
-    }
-
-    /**
-     * Creates a copy of this expression node, without copying children.
-     */
-    @Override
-    public Expression shallowCopy() {
-        return new ASTAnd(id);
-    }
-
-    @Override
-    public int getType() {
-        return Expression.AND;
-    }
-
-    @Override
-    public void jjtClose() {
-        super.jjtClose();
-        flattenTree();
-    }
-
-    @Override
-    protected String getExpressionOperator(int index) {
-        return "and";
-    }
-
-    public void injectValue(Object o) {
-        //iterate through all operands, inject all possible
-        int len = jjtGetNumChildren();
-        for (int i = 0; i < len; i++) {
-            Node node = jjtGetChild(i);
-            if (node instanceof ValueInjector) {
-                ((ValueInjector) node).injectValue(o);
-            }
-        }
-    }
+
+	private static final long serialVersionUID = -5936206826390819160L;
+
+	/**
+	 * Constructor used by expression parser. Do not invoke directly.
+	 */
+	ASTAnd(int id) {
+		super(id);
+	}
+
+	public ASTAnd() {
+		super(ExpressionParserTreeConstants.JJTAND);
+	}
+
+	public ASTAnd(Object[] nodes) {
+		super(ExpressionParserTreeConstants.JJTAND);
+		int len = nodes.length;
+		for (int i = 0; i < len; i++) {
+			jjtAddChild((Node) nodes[i], i);
+		}
+
+		connectChildren();
+	}
+
+	public ASTAnd(Collection<? extends Node> nodes) {
+		super(ExpressionParserTreeConstants.JJTAND);
+		int len = nodes.size();
+		Iterator<? extends Node> it = nodes.iterator();
+		for (int i = 0; i < len; i++) {
+			jjtAddChild(it.next(), i);
+		}
+
+		connectChildren();
+	}
+
+	@Override
+	protected Object evaluateNode(Object o) throws Exception {
+		int len = jjtGetNumChildren();
+		if (len == 0) {
+			return Boolean.FALSE;
+		}
+
+		for (int i = 0; i < len; i++) {
+			if (!ConversionUtil.toBoolean(evaluateChild(i, o))) {
+				return Boolean.FALSE;
+			}
+		}
+
+		return Boolean.TRUE;
+	}
+
+	/**
+	 * Creates a copy of this expression node, without copying children.
+	 */
+	@Override
+	public Expression shallowCopy() {
+		return new ASTAnd(id);
+	}
+
+	@Override
+	public int getType() {
+		return Expression.AND;
+	}
+
+	@Override
+	public void jjtClose() {
+		super.jjtClose();
+		flattenTree();
+	}
+
+	@Override
+	protected String getExpressionOperator(int index) {
+		return "and";
+	}
+
+	public void injectValue(Object o) {
+		// iterate through all operands, inject all possible
+		int len = jjtGetNumChildren();
+		for (int i = 0; i < len; i++) {
+			Node node = jjtGetChild(i);
+			if (node instanceof ValueInjector) {
+				((ValueInjector) node).injectValue(o);
+			}
+		}
+	}
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/069b8fbb/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBetween.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBetween.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBetween.java
index 9725d20..539991c 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBetween.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBetween.java
@@ -28,63 +28,65 @@ import org.apache.cayenne.exp.Expression;
  */
 public class ASTBetween extends ConditionNode {
 
-    ASTBetween(int id) {
-        super(id);
-    }
-
-    public ASTBetween() {
-        super(ExpressionParserTreeConstants.JJTBETWEEN);
-    }
-
-    public ASTBetween(ASTPath path, Object value1, Object value2) {
-        super(ExpressionParserTreeConstants.JJTBETWEEN);
-        jjtAddChild(path, 0);
-        jjtAddChild(new ASTScalar(value1), 1);
-        jjtAddChild(new ASTScalar(value2), 2);
-
-        connectChildren();
-    }
-
-    @Override
-    protected Object evaluateNode(Object o) throws Exception {
-        int len = jjtGetNumChildren();
-        if (len != 3) {
-            return Boolean.FALSE;
-        }
-
-        Object o1 = evaluateChild(0, o);
-        Object o2 = evaluateChild(1, o);
-        Object o3 = evaluateChild(2, o);
-        Evaluator e = Evaluator.evaluator(o1);
-
-        Integer c1 = e.compare(o1, o2);
-        if (c1 == null) {
-            return Boolean.FALSE;
-        }
-
-        Integer c2 = e.compare(o1, o3);
-        if (c2 == null) {
-            return Boolean.FALSE;
-        }
-
-        return c1 >= 0 && c2 <= 0 ? Boolean.TRUE : Boolean.FALSE;
-    }
-
-    /**
-     * Creates a copy of this expression node, without copying children.
-     */
-    @Override
-    public Expression shallowCopy() {
-        return new ASTBetween(id);
-    }
-
-    @Override
-    protected String getExpressionOperator(int index) {
-        return (index == 2) ? "and" : "between";
-    }
-
-    @Override
-    public int getType() {
-        return Expression.BETWEEN;
-    }
+	private static final long serialVersionUID = -8739783546459651759L;
+
+	ASTBetween(int id) {
+		super(id);
+	}
+
+	public ASTBetween() {
+		super(ExpressionParserTreeConstants.JJTBETWEEN);
+	}
+
+	public ASTBetween(ASTPath path, Object value1, Object value2) {
+		super(ExpressionParserTreeConstants.JJTBETWEEN);
+		jjtAddChild(path, 0);
+		jjtAddChild(new ASTScalar(value1), 1);
+		jjtAddChild(new ASTScalar(value2), 2);
+
+		connectChildren();
+	}
+
+	@Override
+	protected Object evaluateNode(Object o) throws Exception {
+		int len = jjtGetNumChildren();
+		if (len != 3) {
+			return Boolean.FALSE;
+		}
+
+		Object o1 = evaluateChild(0, o);
+		Object o2 = evaluateChild(1, o);
+		Object o3 = evaluateChild(2, o);
+		Evaluator e = Evaluator.evaluator(o1);
+
+		Integer c1 = e.compare(o1, o2);
+		if (c1 == null) {
+			return Boolean.FALSE;
+		}
+
+		Integer c2 = e.compare(o1, o3);
+		if (c2 == null) {
+			return Boolean.FALSE;
+		}
+
+		return c1 >= 0 && c2 <= 0 ? Boolean.TRUE : Boolean.FALSE;
+	}
+
+	/**
+	 * Creates a copy of this expression node, without copying children.
+	 */
+	@Override
+	public Expression shallowCopy() {
+		return new ASTBetween(id);
+	}
+
+	@Override
+	protected String getExpressionOperator(int index) {
+		return (index == 2) ? "and" : "between";
+	}
+
+	@Override
+	public int getType() {
+		return Expression.BETWEEN;
+	}
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/069b8fbb/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseAnd.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseAnd.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseAnd.java
index 16c3d5d..9fe8a2f 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseAnd.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseAnd.java
@@ -30,81 +30,81 @@ import org.apache.cayenne.util.ConversionUtil;
  * @since 3.1
  */
 public class ASTBitwiseAnd extends SimpleNode {
-	private static final long serialVersionUID = 1L;
+
+	private static final long serialVersionUID = -1482206814209874743L;
 
 	ASTBitwiseAnd(int id) {
 		super(id);
 	}
-	
+
 	public ASTBitwiseAnd() {
 		super(ExpressionParserTreeConstants.JJTBITWISEAND);
 	}
-	
+
 	public ASTBitwiseAnd(Object[] nodes) {
-        super(ExpressionParserTreeConstants.JJTBITWISEAND);
-        int len = nodes.length;
-        for (int i = 0; i < len; i++) {
-            jjtAddChild(wrapChild(nodes[i]), i);
-        }
-        
-        connectChildren();
+		super(ExpressionParserTreeConstants.JJTBITWISEAND);
+		int len = nodes.length;
+		for (int i = 0; i < len; i++) {
+			jjtAddChild(wrapChild(nodes[i]), i);
+		}
+
+		connectChildren();
+	}
+
+	public ASTBitwiseAnd(Collection<Object> nodes) {
+		super(ExpressionParserTreeConstants.JJTBITWISEAND);
+		int len = nodes.size();
+		Iterator<Object> it = nodes.iterator();
+		for (int i = 0; i < len; i++) {
+			jjtAddChild(wrapChild(it.next()), i);
+		}
 	}
-	
-    public ASTBitwiseAnd(Collection<Object> nodes) {
-        super(ExpressionParserTreeConstants.JJTBITWISEAND);
-        int len = nodes.size();
-        Iterator<Object> it = nodes.iterator();
-        for (int i = 0; i < len; i++) {
-            jjtAddChild(wrapChild(it.next()), i);
-        }
-    }
-	
+
 	@Override
 	protected Object evaluateNode(Object o) throws Exception {
-        int len = jjtGetNumChildren();
-        if (len == 0) {
-            return null;
-        }
+		int len = jjtGetNumChildren();
+		if (len == 0) {
+			return null;
+		}
 
-        Long result = null;
-        for (int i = 0; i < len; i++) {
-            Long value = ConversionUtil.toLong(evaluateChild(i, o), Long.MIN_VALUE);
+		Long result = null;
+		for (int i = 0; i < len; i++) {
+			Long value = ConversionUtil.toLong(evaluateChild(i, o), Long.MIN_VALUE);
 
-            if (value == Long.MIN_VALUE) {
-                return null;
-            }
+			if (value == Long.MIN_VALUE) {
+				return null;
+			}
 
-            result = (i == 0) ? value : result & value;
-        }
+			result = (i == 0) ? value : result & value;
+		}
 
-        return result;
+		return result;
 	}
 
 	@Override
 	protected String getExpressionOperator(int index) {
 		return "&";
 	}
-	
+
 	@Override
 	public int getType() {
 		return Expression.BITWISE_AND;
 	}
-	
+
 	@Override
 	protected String getEJBQLExpressionOperator(int index) {
-		throw new UnsupportedOperationException(
-				"EJBQL 'bitwise not' is not supported");
+		throw new UnsupportedOperationException("EJBQL 'bitwise not' is not supported");
 	}
-	
+
 	@Override
 	public Expression shallowCopy() {
 		return new ASTBitwiseAnd(id);
 	}
-	
-    @Override
-    public void jjtClose() {
-        super.jjtClose();
-        flattenTree();
-    }
+
+	@Override
+	public void jjtClose() {
+		super.jjtClose();
+		flattenTree();
+	}
 
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/069b8fbb/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseLeftShift.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseLeftShift.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseLeftShift.java
index 890e678..d7c8606 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseLeftShift.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseLeftShift.java
@@ -30,82 +30,81 @@ import org.apache.cayenne.util.ConversionUtil;
  * @since 4.0
  */
 public class ASTBitwiseLeftShift extends SimpleNode {
-    private static final long serialVersionUID = 1L;
-
-    ASTBitwiseLeftShift(int id) {
-        super(id);
-    }
-
-    public ASTBitwiseLeftShift() {
-        super(ExpressionParserTreeConstants.JJTBITWISELEFTSHIFT);
-    }
-
-    public ASTBitwiseLeftShift(Object[] nodes) {
-        super(ExpressionParserTreeConstants.JJTBITWISELEFTSHIFT);
-        int len = nodes.length;
-        for (int i = 0; i < len; i++) {
-            jjtAddChild(wrapChild(nodes[i]), i);
-        }
-
-        connectChildren();
-    }
-
-    public ASTBitwiseLeftShift(Collection<Object> nodes) {
-        super(ExpressionParserTreeConstants.JJTBITWISELEFTSHIFT);
-        int len = nodes.size();
-        Iterator<Object> it = nodes.iterator();
-        for (int i = 0; i < len; i++) {
-            jjtAddChild(wrapChild(it.next()), i);
-        }
-    }
-
-    @Override
-    protected Object evaluateNode(Object o) throws Exception {
-        int len = jjtGetNumChildren();
-        if (len == 0) {
-            return null;
-        }
-
-        Long result = null;
-        for (int i = 0; i < len; i++) {
-            Long value = ConversionUtil.toLong(evaluateChild(i, o),
-                    Long.MIN_VALUE);
-
-            if (value == Long.MIN_VALUE) {
-                return null;
-            }
-
-            result = (i == 0) ? value : result << value;
-        }
-
-        return result;
-    }
-
-    @Override
-    protected String getExpressionOperator(int index) {
-        return "<<";
-    }
-
-    @Override
-    public int getType() {
-        return Expression.BITWISE_LEFT_SHIFT;
-    }
-
-    @Override
-    protected String getEJBQLExpressionOperator(int index) {
-        throw new UnsupportedOperationException(
-                "EJBQL 'bitwise not' is not supported");
-    }
-
-    @Override
-    public Expression shallowCopy() {
-        return new ASTBitwiseLeftShift(id);
-    }
-
-    @Override
-    public void jjtClose() {
-        super.jjtClose();
-        flattenTree();
-    }
+
+	private static final long serialVersionUID = -954784931828996446L;
+
+	ASTBitwiseLeftShift(int id) {
+		super(id);
+	}
+
+	public ASTBitwiseLeftShift() {
+		super(ExpressionParserTreeConstants.JJTBITWISELEFTSHIFT);
+	}
+
+	public ASTBitwiseLeftShift(Object[] nodes) {
+		super(ExpressionParserTreeConstants.JJTBITWISELEFTSHIFT);
+		int len = nodes.length;
+		for (int i = 0; i < len; i++) {
+			jjtAddChild(wrapChild(nodes[i]), i);
+		}
+
+		connectChildren();
+	}
+
+	public ASTBitwiseLeftShift(Collection<Object> nodes) {
+		super(ExpressionParserTreeConstants.JJTBITWISELEFTSHIFT);
+		int len = nodes.size();
+		Iterator<Object> it = nodes.iterator();
+		for (int i = 0; i < len; i++) {
+			jjtAddChild(wrapChild(it.next()), i);
+		}
+	}
+
+	@Override
+	protected Object evaluateNode(Object o) throws Exception {
+		int len = jjtGetNumChildren();
+		if (len == 0) {
+			return null;
+		}
+
+		Long result = null;
+		for (int i = 0; i < len; i++) {
+			Long value = ConversionUtil.toLong(evaluateChild(i, o), Long.MIN_VALUE);
+
+			if (value == Long.MIN_VALUE) {
+				return null;
+			}
+
+			result = (i == 0) ? value : result << value;
+		}
+
+		return result;
+	}
+
+	@Override
+	protected String getExpressionOperator(int index) {
+		return "<<";
+	}
+
+	@Override
+	public int getType() {
+		return Expression.BITWISE_LEFT_SHIFT;
+	}
+
+	@Override
+	protected String getEJBQLExpressionOperator(int index) {
+		throw new UnsupportedOperationException("EJBQL 'bitwise not' is not supported");
+	}
+
+	@Override
+	public Expression shallowCopy() {
+		return new ASTBitwiseLeftShift(id);
+	}
+
+	@Override
+	public void jjtClose() {
+		super.jjtClose();
+		flattenTree();
+	}
 
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/069b8fbb/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDivide.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDivide.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDivide.java
index b56c1d9..66b92a8 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDivide.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDivide.java
@@ -32,77 +32,80 @@ import org.apache.cayenne.util.ConversionUtil;
  * @since 1.1
  */
 public class ASTDivide extends SimpleNode {
-    ASTDivide(int id) {
-        super(id);
-    }
-
-    public ASTDivide() {
-        super(ExpressionParserTreeConstants.JJTDIVIDE);
-    }
-
-    public ASTDivide(Object[] nodes) {
-        super(ExpressionParserTreeConstants.JJTDIVIDE);
-        int len = nodes.length;
-        for (int i = 0; i < len; i++) {
-            jjtAddChild(wrapChild(nodes[i]), i);
-        }
-        
-        connectChildren();
-    }
-
-    public ASTDivide(Collection nodes) {
-        super(ExpressionParserTreeConstants.JJTDIVIDE);
-        int len = nodes.size();
-        Iterator it = nodes.iterator();
-        for (int i = 0; i < len; i++) {
-            jjtAddChild(wrapChild(it.next()), i);
-        }
-        
-        connectChildren();
-    }
-
-    @Override
-    protected Object evaluateNode(Object o) throws Exception {
-        int len = jjtGetNumChildren();
-        if (len == 0) {
-            return null;
-        }
-
-        BigDecimal result = null;
-        for (int i = 0; i < len; i++) {
-            BigDecimal value = ConversionUtil.toBigDecimal(evaluateChild(i, o));
-
-            if (value == null) {
-                return null;
-            }
-
-            result = (i == 0) ? value : result.divide(value, BigDecimal.ROUND_HALF_EVEN);
-        }
-
-        return result;
-    }
-
-    /**
-     * Creates a copy of this expression node, without copying children.
-     */
-    @Override
-    public Expression shallowCopy() {
-        return new ASTDivide(id);
-    }
-
-    @Override
-    protected String getExpressionOperator(int index) {
-        return "/";
-    }
-
-    @Override
-    public int getType() {
-        return Expression.DIVIDE;
-    }
-
-    @Override
-    public void jjtClose() {
-        super.jjtClose();
-        flattenTree();
-    }
+
+	private static final long serialVersionUID = -5086569683844539310L;
+
+	ASTDivide(int id) {
+		super(id);
+	}
+
+	public ASTDivide() {
+		super(ExpressionParserTreeConstants.JJTDIVIDE);
+	}
+
+	public ASTDivide(Object[] nodes) {
+		super(ExpressionParserTreeConstants.JJTDIVIDE);
+		int len = nodes.length;
+		for (int i = 0; i < len; i++) {
+			jjtAddChild(wrapChild(nodes[i]), i);
+		}
+
+		connectChildren();
+	}
+
+	public ASTDivide(Collection nodes) {
+		super(ExpressionParserTreeConstants.JJTDIVIDE);
+		int len = nodes.size();
+		Iterator it = nodes.iterator();
+		for (int i = 0; i < len; i++) {
+			jjtAddChild(wrapChild(it.next()), i);
+		}
+
+		connectChildren();
+	}
+
+	@Override
+	protected Object evaluateNode(Object o) throws Exception {
+		int len = jjtGetNumChildren();
+		if (len == 0) {
+			return null;
+		}
+
+		BigDecimal result = null;
+		for (int i = 0; i < len; i++) {
+			BigDecimal value = ConversionUtil.toBigDecimal(evaluateChild(i, o));
+
+			if (value == null) {
+				return null;
+			}
+
+			result = (i == 0) ? value : result.divide(value, BigDecimal.ROUND_HALF_EVEN);
+		}
+
+		return result;
+	}
+
+	/**
+	 * Creates a copy of this expression node, without copying children.
+	 */
+	@Override
+	public Expression shallowCopy() {
+		return new ASTDivide(id);
+	}
+
+	@Override
+	protected String getExpressionOperator(int index) {
+		return "/";
+	}
+
+	@Override
+	public int getType() {
+		return Expression.DIVIDE;
+	}
+
+	@Override
+	public void jjtClose() {
+		super.jjtClose();
+		flattenTree();
+	}
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/069b8fbb/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTNot.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTNot.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTNot.java
index b12491f..13700e5 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTNot.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTNot.java
@@ -32,63 +32,65 @@ import org.apache.cayenne.util.ConversionUtil;
  */
 public class ASTNot extends AggregateConditionNode {
 
-    ASTNot(int id) {
-        super(id);
-    }
+	private static final long serialVersionUID = 7418894098531106347L;
 
-    public ASTNot() {
-        super(ExpressionParserTreeConstants.JJTNOT);
-    }
+	ASTNot(int id) {
+		super(id);
+	}
 
-    public ASTNot(Node expression) {
-        super(ExpressionParserTreeConstants.JJTNOT);
-        jjtAddChild(expression, 0);
-        connectChildren();
-    }
+	public ASTNot() {
+		super(ExpressionParserTreeConstants.JJTNOT);
+	}
 
-    @Override
-    protected Object evaluateNode(Object o) throws Exception {
-        int len = jjtGetNumChildren();
-        if (len == 0) {
-            return Boolean.FALSE;
-        }
+	public ASTNot(Node expression) {
+		super(ExpressionParserTreeConstants.JJTNOT);
+		jjtAddChild(expression, 0);
+		connectChildren();
+	}
 
-        return ConversionUtil.toBoolean(evaluateChild(0, o)) ? Boolean.FALSE : Boolean.TRUE;
-    }
+	@Override
+	protected Object evaluateNode(Object o) throws Exception {
+		int len = jjtGetNumChildren();
+		if (len == 0) {
+			return Boolean.FALSE;
+		}
 
-    /**
-     * Creates a copy of this expression node, without copying children.
-     */
-    @Override
-    public Expression shallowCopy() {
-        return new ASTNot(id);
-    }
+		return ConversionUtil.toBoolean(evaluateChild(0, o)) ? Boolean.FALSE : Boolean.TRUE;
+	}
 
-    @Override
-    public int getType() {
-        return Expression.NOT;
-    }
+	/**
+	 * Creates a copy of this expression node, without copying children.
+	 */
+	@Override
+	public Expression shallowCopy() {
+		return new ASTNot(id);
+	}
 
-    /**
-     * @since 4.0
-     */
-    @Override
-    public void appendAsString(Appendable out) throws IOException {
-        out.append("not ");
-        super.appendAsString(out);
-    }
+	@Override
+	public int getType() {
+		return Expression.NOT;
+	}
 
-    /**
-     * @since 4.0
-     */
-    @Override
-    public void appendAsEJBQL(List<Object> parameterAccumulator, Appendable out, String rootId) throws IOException {
-        appendAsString(out);
-    }
+	/**
+	 * @since 4.0
+	 */
+	@Override
+	public void appendAsString(Appendable out) throws IOException {
+		out.append("not ");
+		super.appendAsString(out);
+	}
 
-    @Override
-    protected String getExpressionOperator(int index) {
-        throw new UnsupportedOperationException("No operator for '" + ExpressionParserTreeConstants.jjtNodeName[id]
-                + "'");
-    }
+	/**
+	 * @since 4.0
+	 */
+	@Override
+	public void appendAsEJBQL(List<Object> parameterAccumulator, Appendable out, String rootId) throws IOException {
+		appendAsString(out);
+	}
+
+	@Override
+	protected String getExpressionOperator(int index) {
+		throw new UnsupportedOperationException("No operator for '" + ExpressionParserTreeConstants.jjtNodeName[id]
+				+ "'");
+	}
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/069b8fbb/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTNotLikeIgnoreCase.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTNotLikeIgnoreCase.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTNotLikeIgnoreCase.java
index 640492f..8317775 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTNotLikeIgnoreCase.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTNotLikeIgnoreCase.java
@@ -17,7 +17,6 @@
  *  under the License.
  ****************************************************************/
 
-
 package org.apache.cayenne.exp.parser;
 
 import org.apache.cayenne.exp.Expression;
@@ -28,63 +27,66 @@ import org.apache.cayenne.util.ConversionUtil;
  * 
  */
 public class ASTNotLikeIgnoreCase extends IgnoreCaseNode {
-    ASTNotLikeIgnoreCase(int id) {
-        super(id, true);
-    }
 
-    public ASTNotLikeIgnoreCase() {
-        super(ExpressionParserTreeConstants.JJTNOTLIKEIGNORECASE, true);
-    }
+	private static final long serialVersionUID = -1837593236671099985L;
+
+	ASTNotLikeIgnoreCase(int id) {
+		super(id, true);
+	}
+
+	public ASTNotLikeIgnoreCase() {
+		super(ExpressionParserTreeConstants.JJTNOTLIKEIGNORECASE, true);
+	}
+
+	public ASTNotLikeIgnoreCase(ASTPath path, Object value) {
+		super(ExpressionParserTreeConstants.JJTNOTLIKEIGNORECASE, true);
+		jjtAddChild(path, 0);
+		jjtAddChild(new ASTScalar(value), 1);
+		connectChildren();
+	}
+
+	public ASTNotLikeIgnoreCase(ASTPath path, Object value, char escapeChar) {
+		super(ExpressionParserTreeConstants.JJTNOTLIKEIGNORECASE, true, escapeChar);
+		jjtAddChild(path, 0);
+		jjtAddChild(new ASTScalar(value), 1);
+		connectChildren();
+	}
 
-    public ASTNotLikeIgnoreCase(ASTPath path, Object value) {
-        super(ExpressionParserTreeConstants.JJTNOTLIKEIGNORECASE, true);
-        jjtAddChild(path, 0);
-        jjtAddChild(new ASTScalar(value), 1);
-        connectChildren();
-    }
-    
-    public ASTNotLikeIgnoreCase(ASTPath path, Object value, char escapeChar) {
-        super(ExpressionParserTreeConstants.JJTNOTLIKEIGNORECASE, true, escapeChar);
-        jjtAddChild(path, 0);
-        jjtAddChild(new ASTScalar(value), 1);
-        connectChildren();
-    }
+	@Override
+	protected Object evaluateNode(Object o) throws Exception {
+		int len = jjtGetNumChildren();
+		if (len != 2) {
+			return Boolean.FALSE;
+		}
 
-    @Override
-    protected Object evaluateNode(Object o) throws Exception {
-        int len = jjtGetNumChildren();
-        if (len != 2) {
-            return Boolean.FALSE;
-        }
+		String s1 = ConversionUtil.toString(evaluateChild(0, o));
+		if (s1 == null) {
+			return Boolean.FALSE;
+		}
 
-        String s1 = ConversionUtil.toString(evaluateChild(0, o));
-        if (s1 == null) {
-            return Boolean.FALSE;
-        }
+		return matchPattern(s1) ? Boolean.FALSE : Boolean.TRUE;
+	}
 
-        return matchPattern(s1) ? Boolean.FALSE : Boolean.TRUE;
-    }
+	/**
+	 * Creates a copy of this expression node, without copying children.
+	 */
+	@Override
+	public Expression shallowCopy() {
+		return new ASTNotLikeIgnoreCase(id);
+	}
 
-    /**
-     * Creates a copy of this expression node, without copying children.
-     */
-    @Override
-    public Expression shallowCopy() {
-        return new ASTNotLikeIgnoreCase(id);
-    }
+	@Override
+	protected String getExpressionOperator(int index) {
+		return "not likeIgnoreCase";
+	}
 
-    @Override
-    protected String getExpressionOperator(int index) {
-        return "not likeIgnoreCase";
-    }
-    
-    @Override
-    protected String getEJBQLExpressionOperator(int index) {
-        return "not like";
-    }
+	@Override
+	protected String getEJBQLExpressionOperator(int index) {
+		return "not like";
+	}
 
-    @Override
-    public int getType() {
-        return Expression.NOT_LIKE_IGNORE_CASE;
-    }
+	@Override
+	public int getType() {
+		return Expression.NOT_LIKE_IGNORE_CASE;
+	}
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/069b8fbb/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTObjPath.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTObjPath.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTObjPath.java
index 72f7b91..3628098 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTObjPath.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTObjPath.java
@@ -32,76 +32,79 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 public class ASTObjPath extends ASTPath {
-    private static final Log logObj = LogFactory.getLog(ASTObjPath.class);
-
-    public static final String OBJ_PREFIX = "obj:";
-
-    /**
-     * Constructor used by expression parser. Do not invoke directly.
-     */
-    ASTObjPath(int id) {
-        super(id);
-    }
-
-    public ASTObjPath() {
-        super(ExpressionParserTreeConstants.JJTOBJPATH);
-    }
-
-    public ASTObjPath(Object value) {
-        super(ExpressionParserTreeConstants.JJTOBJPATH);
-        setPath(value);
-    }
-
-    @Override
-    protected Object evaluateNode(Object o) throws Exception {
-        return (o instanceof DataObject) ? ((DataObject) o).readNestedProperty(path)
-                : (o instanceof Entity) ? evaluateEntityNode((Entity) o) : PropertyUtils.getProperty(o, path);
-    }
-
-    /**
-     * Creates a copy of this expression node, without copying children.
-     */
-    @Override
-    public Expression shallowCopy() {
-        ASTObjPath copy = new ASTObjPath(id);
-        copy.path = path;
-        return copy;
-    }
-
-    /**
-     * @since 4.0
-     */
-    @Override
-    public void appendAsEJBQL(List<Object> parameterAccumulator, Appendable out, String rootId) throws IOException {
-        out.append(rootId);
-        out.append('.');
-        out.append(path);
-    }
-
-    /**
-     * @since 4.0
-     */
-    @Override
-    public void appendAsString(Appendable out) throws IOException {
-        out.append(path);
-    }
-
-    @Override
-    public int getType() {
-        return Expression.OBJ_PATH;
-    }
-
-    void injectValue(Object source, Object value) {
-        if (getPath().indexOf(ObjEntity.PATH_SEPARATOR) == -1) {
-            try {
-                if (source instanceof DataObject) {
-                    ((DataObject) source).writeProperty(getPath(), value);
-                } else {
-                    PropertyUtils.setProperty(source, getPath(), value);
-                }
-            } catch (CayenneRuntimeException ex) {
-                logObj.warn("Failed to inject value " + value + " on path " + getPath() + " to " + source, ex);
-            }
-        }
-    }
+
+	private static final long serialVersionUID = -3574281576491705706L;
+
+	private static final Log LOGGER = LogFactory.getLog(ASTObjPath.class);
+
+	public static final String OBJ_PREFIX = "obj:";
+
+	/**
+	 * Constructor used by expression parser. Do not invoke directly.
+	 */
+	ASTObjPath(int id) {
+		super(id);
+	}
+
+	public ASTObjPath() {
+		super(ExpressionParserTreeConstants.JJTOBJPATH);
+	}
+
+	public ASTObjPath(Object value) {
+		super(ExpressionParserTreeConstants.JJTOBJPATH);
+		setPath(value);
+	}
+
+	@Override
+	protected Object evaluateNode(Object o) throws Exception {
+		return (o instanceof DataObject) ? ((DataObject) o).readNestedProperty(path)
+				: (o instanceof Entity) ? evaluateEntityNode((Entity) o) : PropertyUtils.getProperty(o, path);
+	}
+
+	/**
+	 * Creates a copy of this expression node, without copying children.
+	 */
+	@Override
+	public Expression shallowCopy() {
+		ASTObjPath copy = new ASTObjPath(id);
+		copy.path = path;
+		return copy;
+	}
+
+	/**
+	 * @since 4.0
+	 */
+	@Override
+	public void appendAsEJBQL(List<Object> parameterAccumulator, Appendable out, String rootId) throws IOException {
+		out.append(rootId);
+		out.append('.');
+		out.append(path);
+	}
+
+	/**
+	 * @since 4.0
+	 */
+	@Override
+	public void appendAsString(Appendable out) throws IOException {
+		out.append(path);
+	}
+
+	@Override
+	public int getType() {
+		return Expression.OBJ_PATH;
+	}
+
+	void injectValue(Object source, Object value) {
+		if (getPath().indexOf(ObjEntity.PATH_SEPARATOR) == -1) {
+			try {
+				if (source instanceof DataObject) {
+					((DataObject) source).writeProperty(getPath(), value);
+				} else {
+					PropertyUtils.setProperty(source, getPath(), value);
+				}
+			} catch (CayenneRuntimeException ex) {
+				LOGGER.warn("Failed to inject value " + value + " on path " + getPath() + " to " + source, ex);
+			}
+		}
+	}
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/069b8fbb/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTOr.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTOr.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTOr.java
index 74cec4b..1f6ef24 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTOr.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTOr.java
@@ -31,70 +31,73 @@ import org.apache.cayenne.util.ConversionUtil;
  * @since 1.1
  */
 public class ASTOr extends AggregateConditionNode {
-    ASTOr(int id) {
-        super(id);
-    }
-
-    public ASTOr() {
-        super(ExpressionParserTreeConstants.JJTOR);
-    }
-
-    public ASTOr(Object[] nodes) {
-        super(ExpressionParserTreeConstants.JJTOR);
-        int len = nodes.length;
-        for (int i = 0; i < len; i++) {
-            jjtAddChild((Node) nodes[i], i);
-        }
-        connectChildren();
-    }
-
-    public ASTOr(Collection<? extends Node> nodes) {
-        super(ExpressionParserTreeConstants.JJTOR);
-        int len = nodes.size();
-        Iterator<? extends Node> it = nodes.iterator();
-        for (int i = 0; i < len; i++) {
-            jjtAddChild(it.next(), i);
-        }
-        connectChildren();
-    }
-
-    @Override
-    protected Object evaluateNode(Object o) throws Exception {
-        int len = jjtGetNumChildren();
-        if (len == 0) {
-            return Boolean.FALSE;
-        }
-
-        for (int i = 0; i < len; i++) {
-            if (ConversionUtil.toBoolean(evaluateChild(i, o))) {
-                return Boolean.TRUE;
-            }
-        }
-
-        return Boolean.FALSE;
-    }
-
-    /**
-     * Creates a copy of this expression node, without copying children.
-     */
-    @Override
-    public Expression shallowCopy() {
-        return new ASTOr(id);
-    }
-
-    @Override
-    protected String getExpressionOperator(int index) {
-        return "or";
-    }
-
-    @Override
-    public int getType() {
-        return Expression.OR;
-    }
-
-    @Override
-    public void jjtClose() {
-        super.jjtClose();
-        flattenTree();
-    }
+
+	private static final long serialVersionUID = 780157841581581297L;
+
+	ASTOr(int id) {
+		super(id);
+	}
+
+	public ASTOr() {
+		super(ExpressionParserTreeConstants.JJTOR);
+	}
+
+	public ASTOr(Object[] nodes) {
+		super(ExpressionParserTreeConstants.JJTOR);
+		int len = nodes.length;
+		for (int i = 0; i < len; i++) {
+			jjtAddChild((Node) nodes[i], i);
+		}
+		connectChildren();
+	}
+
+	public ASTOr(Collection<? extends Node> nodes) {
+		super(ExpressionParserTreeConstants.JJTOR);
+		int len = nodes.size();
+		Iterator<? extends Node> it = nodes.iterator();
+		for (int i = 0; i < len; i++) {
+			jjtAddChild(it.next(), i);
+		}
+		connectChildren();
+	}
+
+	@Override
+	protected Object evaluateNode(Object o) throws Exception {
+		int len = jjtGetNumChildren();
+		if (len == 0) {
+			return Boolean.FALSE;
+		}
+
+		for (int i = 0; i < len; i++) {
+			if (ConversionUtil.toBoolean(evaluateChild(i, o))) {
+				return Boolean.TRUE;
+			}
+		}
+
+		return Boolean.FALSE;
+	}
+
+	/**
+	 * Creates a copy of this expression node, without copying children.
+	 */
+	@Override
+	public Expression shallowCopy() {
+		return new ASTOr(id);
+	}
+
+	@Override
+	protected String getExpressionOperator(int index) {
+		return "or";
+	}
+
+	@Override
+	public int getType() {
+		return Expression.OR;
+	}
+
+	@Override
+	public void jjtClose() {
+		super.jjtClose();
+		flattenTree();
+	}
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/069b8fbb/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTPath.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTPath.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTPath.java
index 111c627..2eb4170 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTPath.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTPath.java
@@ -32,76 +32,77 @@ import org.apache.cayenne.util.CayenneMapEntry;
  */
 public abstract class ASTPath extends SimpleNode {
 
-    protected String path;
-    protected Map<String, String> pathAliases;
-
-    ASTPath(int i) {
-        super(i);
-    }
-
-    @Override
-    public int getOperandCount() {
-        return 1;
-    }
-
-    @Override
-    public Object getOperand(int index) {
-        if (index == 0) {
-            return path;
-        }
-
-        throw new ArrayIndexOutOfBoundsException(index);
-    }
-
-    @Override
-    public void setOperand(int index, Object value) {
-        if (index != 0) {
-            throw new ArrayIndexOutOfBoundsException(index);
-        }
-
-        setPath(value);
-    }
-
-    protected void setPath(Object path) {
-        this.path = (path != null) ? path.toString() : null;
-    }
-
-    public String getPath() {
-        return path;
-    }
-
-    /**
-     * @since 3.0
-     */
-    @Override
-    public Map<String, String> getPathAliases() {
-        return pathAliases != null ? pathAliases : super.getPathAliases();
-    }
-    
-    /**
-     * @since 3.0
-     */
-    public void setPathAliases(Map<String, String> pathAliases) {
-        this.pathAliases = pathAliases;
-    }
-
-    /**
-     * Helper method to evaluate path expression with Cayenne Entity.
-     */
-    protected CayenneMapEntry evaluateEntityNode(Entity entity) {
-        Iterator<CayenneMapEntry> path = entity.resolvePathComponents(this);
-        CayenneMapEntry next = null;
-        while (path.hasNext()) {
-            next = path.next();
-        }
-
-        return next;
-    }
-
-    @Override
-    protected String getExpressionOperator(int index) {
-        throw new UnsupportedOperationException("No operator for '"
-                + ExpressionParserTreeConstants.jjtNodeName[id]
-                + "'");
-    }
+	private static final long serialVersionUID = -8099822503585617295L;
+	
+	protected String path;
+	protected Map<String, String> pathAliases;
+
+	ASTPath(int i) {
+		super(i);
+	}
+
+	@Override
+	public int getOperandCount() {
+		return 1;
+	}
+
+	@Override
+	public Object getOperand(int index) {
+		if (index == 0) {
+			return path;
+		}
+
+		throw new ArrayIndexOutOfBoundsException(index);
+	}
+
+	@Override
+	public void setOperand(int index, Object value) {
+		if (index != 0) {
+			throw new ArrayIndexOutOfBoundsException(index);
+		}
+
+		setPath(value);
+	}
+
+	protected void setPath(Object path) {
+		this.path = (path != null) ? path.toString() : null;
+	}
+
+	public String getPath() {
+		return path;
+	}
+
+	/**
+	 * @since 3.0
+	 */
+	@Override
+	public Map<String, String> getPathAliases() {
+		return pathAliases != null ? pathAliases : super.getPathAliases();
+	}
+
+	/**
+	 * @since 3.0
+	 */
+	public void setPathAliases(Map<String, String> pathAliases) {
+		this.pathAliases = pathAliases;
+	}
+
+	/**
+	 * Helper method to evaluate path expression with Cayenne Entity.
+	 */
+	protected CayenneMapEntry evaluateEntityNode(Entity entity) {
+		Iterator<CayenneMapEntry> path = entity.resolvePathComponents(this);
+		CayenneMapEntry next = null;
+		while (path.hasNext()) {
+			next = path.next();
+		}
+
+		return next;
+	}
+
+	@Override
+	protected String getExpressionOperator(int index) {
+		throw new UnsupportedOperationException("No operator for '" + ExpressionParserTreeConstants.jjtNodeName[id]
+				+ "'");
+	}
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/069b8fbb/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/AggregateConditionNode.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/AggregateConditionNode.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/AggregateConditionNode.java
index 676bf95..7574dfd 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/AggregateConditionNode.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/AggregateConditionNode.java
@@ -19,84 +19,80 @@
 
 package org.apache.cayenne.exp.parser;
 
-import org.apache.commons.collections.Transformer;
 import org.apache.cayenne.exp.ExpressionException;
+import org.apache.commons.collections.Transformer;
 
 /**
  * Superclass of aggregated conditional nodes such as NOT, AND, OR. Performs
- * extra checks on parent and child expressions to validate conditions that
- * are not addressed in the Cayenne expressions grammar.
+ * extra checks on parent and child expressions to validate conditions that are
+ * not addressed in the Cayenne expressions grammar.
  * 
  * @since 1.1
  */
 public abstract class AggregateConditionNode extends SimpleNode {
-    AggregateConditionNode(int i) {
-        super(i);
-    }
-
-    @Override
-    protected boolean pruneNodeForPrunedChild(Object prunedChild) {
-        return false;
-    }
-
-    @Override
-    protected Object transformExpression(Transformer transformer) {
-        Object transformed = super.transformExpression(transformer);
-
-        if (!(transformed instanceof AggregateConditionNode)) {
-            return transformed;
-        }
-        
-        AggregateConditionNode condition = (AggregateConditionNode) transformed;
-
-        // prune itself if the transformation resulted in 
-        // no children or a single child
-        switch (condition.getOperandCount()) {
-            case 1 :
-                if (condition instanceof ASTNot) {
-                    return condition;
-                }
-                else {
-                    return condition.getOperand(0);
-                }
-            case 0 :
-                return PRUNED_NODE;
-            default :
-                return condition;
-        }
-    }
-
-    @Override
-    public void jjtSetParent(Node n) {
-        // this is a check that we can't handle properly
-        // in the grammar... do it here...
-
-        // disallow non-aggregated condition parents...
-        if (!(n instanceof AggregateConditionNode)) {
-            String label =
-                (n instanceof SimpleNode)
-                    ? ((SimpleNode) n).expName()
-                    : String.valueOf(n);
-            throw new ExpressionException(expName() + ": invalid parent - " + label);
-        }
-
-        super.jjtSetParent(n);
-    }
-
-    @Override
-    public void jjtAddChild(Node n, int i) {
-        // this is a check that we can't handle properly
-        // in the grammar... do it here...
-
-        // only allow conditional nodes...no scalars
-        if (!(n instanceof ConditionNode) && !(n instanceof AggregateConditionNode)) {
-            String label =
-                (n instanceof SimpleNode)
-                    ? ((SimpleNode) n).expName()
-                    : String.valueOf(n);
-            throw new ExpressionException(expName() + ": invalid child - " + label);
-        }
-
-        super.jjtAddChild(n, i);
-    }
+
+	private static final long serialVersionUID = -636699350691988809L;
+
+	AggregateConditionNode(int i) {
+		super(i);
+	}
+
+	@Override
+	protected boolean pruneNodeForPrunedChild(Object prunedChild) {
+		return false;
+	}
+
+	@Override
+	protected Object transformExpression(Transformer transformer) {
+		Object transformed = super.transformExpression(transformer);
+
+		if (!(transformed instanceof AggregateConditionNode)) {
+			return transformed;
+		}
+
+		AggregateConditionNode condition = (AggregateConditionNode) transformed;
+
+		// prune itself if the transformation resulted in
+		// no children or a single child
+		switch (condition.getOperandCount()) {
+		case 1:
+			if (condition instanceof ASTNot) {
+				return condition;
+			} else {
+				return condition.getOperand(0);
+			}
+		case 0:
+			return PRUNED_NODE;
+		default:
+			return condition;
+		}
+	}
+
+	@Override
+	public void jjtSetParent(Node n) {
+		// this is a check that we can't handle properly
+		// in the grammar... do it here...
+
+		// disallow non-aggregated condition parents...
+		if (!(n instanceof AggregateConditionNode)) {
+			String label = (n instanceof SimpleNode) ? ((SimpleNode) n).expName() : String.valueOf(n);
+			throw new ExpressionException(expName() + ": invalid parent - " + label);
+		}
+
+		super.jjtSetParent(n);
+	}
+
+	@Override
+	public void jjtAddChild(Node n, int i) {
+		// this is a check that we can't handle properly
+		// in the grammar... do it here...
+
+		// only allow conditional nodes...no scalars
+		if (!(n instanceof ConditionNode) && !(n instanceof AggregateConditionNode)) {
+			String label = (n instanceof SimpleNode) ? ((SimpleNode) n).expName() : String.valueOf(n);
+			throw new ExpressionException(expName() + ": invalid child - " + label);
+		}
+
+		super.jjtAddChild(n, i);
+	}
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/069b8fbb/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/SimpleNode.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/SimpleNode.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/SimpleNode.java
index ca68ded..458afb4 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/SimpleNode.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/SimpleNode.java
@@ -46,446 +46,449 @@ import org.apache.cayenne.util.Util;
  */
 public abstract class SimpleNode extends Expression implements Node {
 
-    protected Node parent;
-    protected Node[] children;
-    protected int id;
-
-    /**
-     * <p>This is a utility method that can represent the supplied scalar as either an EJBQL literal into the
-     * supplied {@link java.io.PrintWriter} or is able to add the scalar to the parameters and to instead
-     * write a positional parameter to the EJBQL written to the {@link java.io.PrintWriter}.  If the parameters
-     * are null and the scalar object is not able to be represented as an EJBQL literal then the method will
-     * throw a runtime exception to indicate that it has failed to produce valid EJBQL.</p>
-     */
-
-    protected static void encodeScalarAsEJBQL(
-            List<Object> parameterAccumulator,
-            Appendable out,
-            Object scalar) throws IOException {
-
-        if (null==scalar) {
-            out.append("null");
-            return;
-        }
-
-        if (scalar instanceof Boolean) {
-            if((Boolean) scalar) {
-                out.append("true");
-            }
-            else {
-                out.append("false");
-            }
-            return;
-        }
-
-        if(null!=parameterAccumulator) {
-            parameterAccumulator.add(scalar);
-            out.append('?');
-            out.append(Integer.toString(parameterAccumulator.size())); // parameters start at 1
-            return;
-        }
-
-        if (
-                scalar instanceof Integer
-                        || scalar instanceof Long
-                        || scalar instanceof Float
-                        || scalar instanceof Double) {
-            out.append(scalar.toString());
-            return;
-        }
-
-        if (scalar instanceof Persistent) {
-            ObjectId id = ((Persistent) scalar).getObjectId();
-            Object encode = (id != null) ? id : scalar;
-            appendAsEscapedString(out, String.valueOf(encode));
-            return;
-        }
-
-        if (scalar instanceof Enum<?>) {
-            Enum<?> e = (Enum<?>) scalar;
-            out.append("enum:");
-            out.append(e.getClass().getName() + "." + e.name());
-            return;
-        }
-
-        if (scalar instanceof String) {
-            out.append('\'');
-            appendAsEscapedString(out, scalar.toString());
-            out.append('\'');
-            return;
-        }
-
-        throw new IllegalStateException("the scalar type '"+scalar.getClass().getSimpleName()+"' is not supported as a scalar type in EJBQL");
-    }
-
-    /**
-     * Utility method that encodes an object that is not an expression Node to
-     * String.
-     */
-    protected static void appendScalarAsString(Appendable out, Object scalar, char quoteChar) throws IOException {
-        boolean quote = scalar instanceof String;
-
-        if (quote) {
-            out.append(quoteChar);
-        }
-
-        // encode only ObjectId for Persistent, ensure that the order of keys is
-        // predictable....
-
-        // TODO: should we use UUID here?
-        if (scalar instanceof Persistent) {
-            ObjectId id = ((Persistent) scalar).getObjectId();
-            Object encode = (id != null) ? id : scalar;
-            appendAsEscapedString(out, String.valueOf(encode));
-        } else if (scalar instanceof Enum<?>) {
-            Enum<?> e = (Enum<?>) scalar;
-            out.append("enum:");
-            out.append(e.getClass().getName() + "." + e.name());
-        } else {
-            appendAsEscapedString(out, String.valueOf(scalar));
-        }
-
-        if (quote) {
-            out.append(quoteChar);
-        }
-    }
-
-    /**
-     * Utility method that prints a string to the provided Appendable, escaping
-     * special characters.
-     */
-    protected static void appendAsEscapedString(Appendable out, String source) throws IOException {
-        int len = source.length();
-        for (int i = 0; i < len; i++) {
-            char c = source.charAt(i);
-
-            switch (c) {
-            case '\n':
-                out.append("\\n");
-                continue;
-            case '\r':
-                out.append("\\r");
-                continue;
-            case '\t':
-                out.append("\\t");
-                continue;
-            case '\b':
-                out.append("\\b");
-                continue;
-            case '\f':
-                out.append("\\f");
-                continue;
-            case '\\':
-                out.append("\\\\");
-                continue;
-            case '\'':
-                out.append("\\'");
-                continue;
-            case '\"':
-                out.append("\\\"");
-                continue;
-            default:
-                out.append(c);
-            }
-        }
-    }
-
-    protected SimpleNode(int i) {
-        id = i;
-    }
-
-    /**
-     * Always returns empty map.
-     * 
-     * @since 3.0
-     */
-    @Override
-    public Map<String, String> getPathAliases() {
-        return Collections.emptyMap();
-    }
-
-    protected abstract String getExpressionOperator(int index);
-
-    /**
-     * Returns operator for ebjql statements, which can differ for Cayenne
-     * expression operator
-     */
-    protected String getEJBQLExpressionOperator(int index) {
-        return getExpressionOperator(index);
-    }
-
-    @Override
-    protected boolean pruneNodeForPrunedChild(Object prunedChild) {
-        return true;
-    }
-
-    /**
-     * Implemented for backwards compatibility with exp package.
-     */
-    @Override
-    public String expName() {
-        return ExpressionParserTreeConstants.jjtNodeName[id];
-    }
-
-    /**
-     * Flattens the tree under this node by eliminating any children that are of
-     * the same class as this node and copying their children to this node.
-     */
-    @Override
-    protected void flattenTree() {
-        boolean shouldFlatten = false;
-        int newSize = 0;
-
-        for (Node child : children) {
-            if (child.getClass() == getClass()) {
-                shouldFlatten = true;
-                newSize += child.jjtGetNumChildren();
-            } else {
-                newSize++;
-            }
-        }
-
-        if (shouldFlatten) {
-            Node[] newChildren = new Node[newSize];
-            int j = 0;
-
-            for (Node c : children) {
-                if (c.getClass() == getClass()) {
-                    for (int k = 0; k < c.jjtGetNumChildren(); ++k) {
-                        newChildren[j++] = c.jjtGetChild(k);
-                    }
-                } else {
-                    newChildren[j++] = c;
-                }
-            }
-
-            if (j != newSize) {
-                throw new ExpressionException("Assertion error: " + j + " != " + newSize);
-            }
-
-            this.children = newChildren;
-        }
-    }
-
-    /**
-     * @since 4.0
-     */
-    @Override
-    public void appendAsString(Appendable out) throws IOException {
-
-        if (parent != null) {
-            out.append("(");
-        }
-
-        if ((children != null) && (children.length > 0)) {
-            for (int i = 0; i < children.length; ++i) {
-                if (i > 0) {
-                    out.append(' ');
-                    out.append(getExpressionOperator(i));
-                    out.append(' ');
-                }
-
-                if (children[i] == null) {
-                    out.append("null");
-                } else {
-                    ((SimpleNode) children[i]).appendAsString(out);
-                }
-            }
-        }
-
-        if (parent != null) {
-            out.append(')');
-        }
-    }
-
-    /**
-     * @deprecated since 4.0 use {@link #appendAsString(Appendable)}.
-     */
-    @Override
-    @Deprecated
-    public void encodeAsString(PrintWriter pw) {
-        try {
-            appendAsString(pw);
-        } catch (IOException e) {
-            throw new CayenneRuntimeException("Unexpected IO exception appending to PrintWriter", e);
-        }
-    }
-
-    @Override
-    public Object getOperand(int index) {
-        Node child = jjtGetChild(index);
-
-        // unwrap ASTScalar nodes - this is likely a temporary thing to keep it
-        // compatible
-        // with QualifierTranslator. In the future we might want to keep scalar
-        // nodes
-        // for the purpose of expression evaluation.
-        return unwrapChild(child);
-    }
-
-    protected Node wrapChild(Object child) {
-        // when child is null, there's no way of telling whether this is a
-        // scalar or
-        // not... fuzzy... maybe we should stop using this method - it is too
-        // generic
-        return (child instanceof Node || child == null) ? (Node) child : new ASTScalar(child);
-    }
-
-    protected Object unwrapChild(Node child) {
-        return (child instanceof ASTScalar) ? ((ASTScalar) child).getValue() : child;
-    }
-
-    @Override
-    public int getOperandCount() {
-        return jjtGetNumChildren();
-    }
-
-    @Override
-    public void setOperand(int index, Object value) {
-        Node node = (value == null || value instanceof Node) ? (Node) value : new ASTScalar(value);
-        jjtAddChild(node, index);
-
-        // set the parent, as jjtAddChild doesn't do it...
-        if (node != null) {
-            node.jjtSetParent(this);
-        }
-    }
-
-    public void jjtOpen() {
-
-    }
-
-    public void jjtClose() {
-
-    }
-
-    public void jjtSetParent(Node n) {
-        parent = n;
-    }
-
-    public Node jjtGetParent() {
-        return parent;
-    }
-
-    public void jjtAddChild(Node n, int i) {
-        if (children == null) {
-            children = new Node[i + 1];
-        } else if (i >= children.length) {
-            Node c[] = new Node[i + 1];
-            System.arraycopy(children, 0, c, 0, children.length);
-            children = c;
-        }
-        children[i] = n;
-    }
-
-    public Node jjtGetChild(int i) {
-        return children[i];
-    }
-
-    public final int jjtGetNumChildren() {
-        return (children == null) ? 0 : children.length;
-    }
-
-    /**
-     * Evaluates itself with object, pushing result on the stack.
-     */
-    protected abstract Object evaluateNode(Object o) throws Exception;
-
-    /**
-     * Sets the parent to this for all children.
-     * 
-     * @since 3.0
-     */
-    protected void connectChildren() {
-        if (children != null) {
-            for (Node child : children) {
-                // although nulls are expected to be wrapped in scalar, still
-                // doing a
-                // check here to make it more robust
-                if (child != null) {
-                    child.jjtSetParent(this);
-                }
-            }
-        }
-    }
-
-    protected Object evaluateChild(int index, Object o) throws Exception {
-        SimpleNode node = (SimpleNode) jjtGetChild(index);
-        return node != null ? node.evaluate(o) : null;
-    }
-
-    @Override
-    public Expression notExp() {
-        return new ASTNot(this);
-    }
-
-    @Override
-    public Object evaluate(Object o) {
-        // wrap in try/catch to provide unified exception processing
-        try {
-            return evaluateNode(o);
-        } catch (Throwable th) {
-            String string = this.toString();
-            throw new ExpressionException("Error evaluating expression '" + string + "'", string,
-                    Util.unwindException(th));
-        }
-    }
-
-    /**
-     * @since 3.0
-     * @deprecated since 4.0 use {@link #appendAsEJBQL(Appendable, String)}.
-     */
-    @Override
-    @Deprecated
-    public void encodeAsEJBQL(PrintWriter pw, String rootId) {
-        try {
-            appendAsEJBQL(pw, rootId);
-        } catch (IOException e) {
-            throw new CayenneRuntimeException("Unexpected IO exception appending to PrintWriter", e);
-        }
-    }
-
-    /**
-     * @since 4.0
-     */
-    public void appendAsEJBQL(Appendable out, String rootId) throws IOException {
-         appendAsEJBQL(null,out,rootId);
-    }
-
-        /**
-         * @since 4.0
-         */
-    @Override
-    public void appendAsEJBQL(List<Object> parameterAccumulator, Appendable out, String rootId) throws IOException {
-        if (parent != null) {
-            out.append("(");
-        }
-
-        if ((children != null) && (children.length > 0)) {
-            appendChildrenAsEJBQL(parameterAccumulator, out, rootId);
-        }
-
-        if (parent != null) {
-            out.append(')');
-        }
-    }
-
-    /**
-     * Encodes child of this node with specified index to EJBQL
-     */
-    protected void appendChildrenAsEJBQL(List<Object> parameterAccumulator, Appendable out, String rootId) throws IOException {
-        for (int i = 0; i < children.length; ++i) {
-            if (i > 0) {
-                out.append(' ');
-                out.append(getEJBQLExpressionOperator(i));
-                out.append(' ');
-            }
-
-            if (children[i] == null) {
-                out.append("null");
-            } else {
-                ((SimpleNode) children[i]).appendAsEJBQL(parameterAccumulator, out, rootId);
-            }
-        }
-    }
+	private static final long serialVersionUID = 4471832357335707557L;
+	
+	protected Node parent;
+	protected Node[] children;
+	protected int id;
+
+	/**
+	 * <p>
+	 * This is a utility method that can represent the supplied scalar as either
+	 * an EJBQL literal into the supplied {@link java.io.PrintWriter} or is able
+	 * to add the scalar to the parameters and to instead write a positional
+	 * parameter to the EJBQL written to the {@link java.io.PrintWriter}. If the
+	 * parameters are null and the scalar object is not able to be represented
+	 * as an EJBQL literal then the method will throw a runtime exception to
+	 * indicate that it has failed to produce valid EJBQL.
+	 * </p>
+	 */
+
+	protected static void encodeScalarAsEJBQL(List<Object> parameterAccumulator, Appendable out, Object scalar)
+			throws IOException {
+
+		if (null == scalar) {
+			out.append("null");
+			return;
+		}
+
+		if (scalar instanceof Boolean) {
+			if ((Boolean) scalar) {
+				out.append("true");
+			} else {
+				out.append("false");
+			}
+			return;
+		}
+
+		if (null != parameterAccumulator) {
+			parameterAccumulator.add(scalar);
+			out.append('?');
+			out.append(Integer.toString(parameterAccumulator.size())); // parameters
+																		// start
+																		// at 1
+			return;
+		}
+
+		if (scalar instanceof Integer || scalar instanceof Long || scalar instanceof Float || scalar instanceof Double) {
+			out.append(scalar.toString());
+			return;
+		}
+
+		if (scalar instanceof Persistent) {
+			ObjectId id = ((Persistent) scalar).getObjectId();
+			Object encode = (id != null) ? id : scalar;
+			appendAsEscapedString(out, String.valueOf(encode));
+			return;
+		}
+
+		if (scalar instanceof Enum<?>) {
+			Enum<?> e = (Enum<?>) scalar;
+			out.append("enum:");
+			out.append(e.getClass().getName() + "." + e.name());
+			return;
+		}
+
+		if (scalar instanceof String) {
+			out.append('\'');
+			appendAsEscapedString(out, scalar.toString());
+			out.append('\'');
+			return;
+		}
+
+		throw new IllegalStateException("the scalar type '" + scalar.getClass().getSimpleName()
+				+ "' is not supported as a scalar type in EJBQL");
+	}
+
+	/**
+	 * Utility method that encodes an object that is not an expression Node to
+	 * String.
+	 */
+	protected static void appendScalarAsString(Appendable out, Object scalar, char quoteChar) throws IOException {
+		boolean quote = scalar instanceof String;
+
+		if (quote) {
+			out.append(quoteChar);
+		}
+
+		// encode only ObjectId for Persistent, ensure that the order of keys is
+		// predictable....
+
+		// TODO: should we use UUID here?
+		if (scalar instanceof Persistent) {
+			ObjectId id = ((Persistent) scalar).getObjectId();
+			Object encode = (id != null) ? id : scalar;
+			appendAsEscapedString(out, String.valueOf(encode));
+		} else if (scalar instanceof Enum<?>) {
+			Enum<?> e = (Enum<?>) scalar;
+			out.append("enum:");
+			out.append(e.getClass().getName() + "." + e.name());
+		} else {
+			appendAsEscapedString(out, String.valueOf(scalar));
+		}
+
+		if (quote) {
+			out.append(quoteChar);
+		}
+	}
+
+	/**
+	 * Utility method that prints a string to the provided Appendable, escaping
+	 * special characters.
+	 */
+	protected static void appendAsEscapedString(Appendable out, String source) throws IOException {
+		int len = source.length();
+		for (int i = 0; i < len; i++) {
+			char c = source.charAt(i);
+
+			switch (c) {
+			case '\n':
+				out.append("\\n");
+				continue;
+			case '\r':
+				out.append("\\r");
+				continue;
+			case '\t':
+				out.append("\\t");
+				continue;
+			case '\b':
+				out.append("\\b");
+				continue;
+			case '\f':
+				out.append("\\f");
+				continue;
+			case '\\':
+				out.append("\\\\");
+				continue;
+			case '\'':
+				out.append("\\'");
+				continue;
+			case '\"':
+				out.append("\\\"");
+				continue;
+			default:
+				out.append(c);
+			}
+		}
+	}
+
+	protected SimpleNode(int i) {
+		id = i;
+	}
+
+	/**
+	 * Always returns empty map.
+	 * 
+	 * @since 3.0
+	 */
+	@Override
+	public Map<String, String> getPathAliases() {
+		return Collections.emptyMap();
+	}
+
+	protected abstract String getExpressionOperator(int index);
+
+	/**
+	 * Returns operator for ebjql statements, which can differ for Cayenne
+	 * expression operator
+	 */
+	protected String getEJBQLExpressionOperator(int index) {
+		return getExpressionOperator(index);
+	}
+
+	@Override
+	protected boolean pruneNodeForPrunedChild(Object prunedChild) {
+		return true;
+	}
+
+	/**
+	 * Implemented for backwards compatibility with exp package.
+	 */
+	@Override
+	public String expName() {
+		return ExpressionParserTreeConstants.jjtNodeName[id];
+	}
+
+	/**
+	 * Flattens the tree under this node by eliminating any children that are of
+	 * the same class as this node and copying their children to this node.
+	 */
+	@Override
+	protected void flattenTree() {
+		boolean shouldFlatten = false;
+		int newSize = 0;
+
+		for (Node child : children) {
+			if (child.getClass() == getClass()) {
+				shouldFlatten = true;
+				newSize += child.jjtGetNumChildren();
+			} else {
+				newSize++;
+			}
+		}
+
+		if (shouldFlatten) {
+			Node[] newChildren = new Node[newSize];
+			int j = 0;
+
+			for (Node c : children) {
+				if (c.getClass() == getClass()) {
+					for (int k = 0; k < c.jjtGetNumChildren(); ++k) {
+						newChildren[j++] = c.jjtGetChild(k);
+					}
+				} else {
+					newChildren[j++] = c;
+				}
+			}
+
+			if (j != newSize) {
+				throw new ExpressionException("Assertion error: " + j + " != " + newSize);
+			}
+
+			this.children = newChildren;
+		}
+	}
+
+	/**
+	 * @since 4.0
+	 */
+	@Override
+	public void appendAsString(Appendable out) throws IOException {
+
+		if (parent != null) {
+			out.append("(");
+		}
+
+		if ((children != null) && (children.length > 0)) {
+			for (int i = 0; i < children.length; ++i) {
+				if (i > 0) {
+					out.append(' ');
+					out.append(getExpressionOperator(i));
+					out.append(' ');
+				}
+
+				if (children[i] == null) {
+					out.append("null");
+				} else {
+					((SimpleNode) children[i]).appendAsString(out);
+				}
+			}
+		}
+
+		if (parent != null) {
+			out.append(')');
+		}
+	}
+
+	/**
+	 * @deprecated since 4.0 use {@link #appendAsString(Appendable)}.
+	 */
+	@Override
+	@Deprecated
+	public void encodeAsString(PrintWriter pw) {
+		try {
+			appendAsString(pw);
+		} catch (IOException e) {
+			throw new CayenneRuntimeException("Unexpected IO exception appending to PrintWriter", e);
+		}
+	}
+
+	@Override
+	public Object getOperand(int index) {
+		Node child = jjtGetChild(index);
+
+		// unwrap ASTScalar nodes - this is likely a temporary thing to keep it
+		// compatible
+		// with QualifierTranslator. In the future we might want to keep scalar
+		// nodes
+		// for the purpose of expression evaluation.
+		return unwrapChild(child);
+	}
+
+	protected Node wrapChild(Object child) {
+		// when child is null, there's no way of telling whether this is a
+		// scalar or
+		// not... fuzzy... maybe we should stop using this method - it is too
+		// generic
+		return (child instanceof Node || child == null) ? (Node) child : new ASTScalar(child);
+	}
+
+	protected Object unwrapChild(Node child) {
+		return (child instanceof ASTScalar) ? ((ASTScalar) child).getValue() : child;
+	}
+
+	@Override
+	public int getOperandCount() {
+		return jjtGetNumChildren();
+	}
+
+	@Override
+	public void setOperand(int index, Object value) {
+		Node node = (value == null || value instanceof Node) ? (Node) value : new ASTScalar(value);
+		jjtAddChild(node, index);
+
+		// set the parent, as jjtAddChild doesn't do it...
+		if (node != null) {
+			node.jjtSetParent(this);
+		}
+	}
+
+	public void jjtOpen() {
+
+	}
+
+	public void jjtClose() {
+
+	}
+
+	public void jjtSetParent(Node n) {
+		parent = n;
+	}
+
+	public Node jjtGetParent() {
+		return parent;
+	}
+
+	public void jjtAddChild(Node n, int i) {
+		if (children == null) {
+			children = new Node[i + 1];
+		} else if (i >= children.length) {
+			Node c[] = new Node[i + 1];
+			System.arraycopy(children, 0, c, 0, children.length);
+			children = c;
+		}
+		children[i] = n;
+	}
+
+	public Node jjtGetChild(int i) {
+		return children[i];
+	}
+
+	public final int jjtGetNumChildren() {
+		return (children == null) ? 0 : children.length;
+	}
+
+	/**
+	 * Evaluates itself with object, pushing result on the stack.
+	 */
+	protected abstract Object evaluateNode(Object o) throws Exception;
+
+	/**
+	 * Sets the parent to this for all children.
+	 * 
+	 * @since 3.0
+	 */
+	protected void connectChildren() {
+		if (children != null) {
+			for (Node child : children) {
+				// although nulls are expected to be wrapped in scalar, still
+				// doing a
+				// check here to make it more robust
+				if (child != null) {
+					child.jjtSetParent(this);
+				}
+			}
+		}
+	}
+
+	protected Object evaluateChild(int index, Object o) throws Exception {
+		SimpleNode node = (SimpleNode) jjtGetChild(index);
+		return node != null ? node.evaluate(o) : null;
+	}
+
+	@Override
+	public Expression notExp() {
+		return new ASTNot(this);
+	}
+
+	@Override
+	public Object evaluate(Object o) {
+		// wrap in try/catch to provide unified exception processing
+		try {
+			return evaluateNode(o);
+		} catch (Throwable th) {
+			String string = this.toString();
+			throw new ExpressionException("Error evaluating expression '" + string + "'", string,
+					Util.unwindException(th));
+		}
+	}
+
+	/**
+	 * @since 3.0
+	 * @deprecated since 4.0 use {@link #appendAsEJBQL(Appendable, String)}.
+	 */
+	@Override
+	@Deprecated
+	public void encodeAsEJBQL(PrintWriter pw, String rootId) {
+		try {
+			appendAsEJBQL(pw, rootId);
+		} catch (IOException e) {
+			throw new CayenneRuntimeException("Unexpected IO exception appending to PrintWriter", e);
+		}
+	}
+
+	/**
+	 * @since 4.0
+	 */
+	public void appendAsEJBQL(Appendable out, String rootId) throws IOException {
+		appendAsEJBQL(null, out, rootId);
+	}
+
+	/**
+	 * @since 4.0
+	 */
+	@Override
+	public void appendAsEJBQL(List<Object> parameterAccumulator, Appendable out, String rootId) throws IOException {
+		if (parent != null) {
+			out.append("(");
+		}
+
+		if ((children != null) && (children.length > 0)) {
+			appendChildrenAsEJBQL(parameterAccumulator, out, rootId);
+		}
+
+		if (parent != null) {
+			out.append(')');
+		}
+	}
+
+	/**
+	 * Encodes child of this node with specified index to EJBQL
+	 */
+	protected void appendChildrenAsEJBQL(List<Object> parameterAccumulator, Appendable out, String rootId)
+			throws IOException {
+		for (int i = 0; i < children.length; ++i) {
+			if (i > 0) {
+				out.append(' ');
+				out.append(getEJBQLExpressionOperator(i));
+				out.append(' ');
+			}
+
+			if (children[i] == null) {
+				out.append("null");
+			} else {
+				((SimpleNode) children[i]).appendAsEJBQL(parameterAccumulator, out, rootId);
+			}
+		}
+	}
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/069b8fbb/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTBetweenTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTBetweenTest.java b/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTBetweenTest.java
new file mode 100644
index 0000000..ada9877
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTBetweenTest.java
@@ -0,0 +1,71 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.exp.parser;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.math.BigDecimal;
+
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.testdo.testmap.Painting;
+import org.junit.Test;
+
+public class ASTBetweenTest {
+
+	@Test
+	public void testEvaluateBETWEEN() {
+		// evaluate both BETWEEN and NOT_BETWEEN
+		Expression between = new ASTBetween(new ASTObjPath("estimatedPrice"), new BigDecimal(10d), new BigDecimal(20d));
+		Expression notBetween = new ASTNotBetween(new ASTObjPath("estimatedPrice"), new BigDecimal(10d),
+				new BigDecimal(20d));
+
+		Painting noMatch = new Painting();
+		noMatch.setEstimatedPrice(new BigDecimal(21));
+		assertFalse(between.match(noMatch));
+		assertTrue(notBetween.match(noMatch));
+
+		Painting match1 = new Painting();
+		match1.setEstimatedPrice(new BigDecimal(20));
+		assertTrue(between.match(match1));
+		assertFalse(notBetween.match(match1));
+
+		Painting match2 = new Painting();
+		match2.setEstimatedPrice(new BigDecimal(10));
+		assertTrue("Failed: " + between, between.match(match2));
+		assertFalse("Failed: " + notBetween, notBetween.match(match2));
+
+		Painting match3 = new Painting();
+		match3.setEstimatedPrice(new BigDecimal(11));
+		assertTrue("Failed: " + between, between.match(match3));
+		assertFalse("Failed: " + notBetween, notBetween.match(match3));
+	}
+
+	@Test
+	public void testEvaluateBETWEEN_Null() {
+		Expression btNull = new ASTBetween(new ASTObjPath("estimatedPrice"), new BigDecimal(10d), new BigDecimal(20d));
+		Expression btNotNull = new ASTNotBetween(new ASTObjPath("estimatedPrice"), new BigDecimal(10d), new BigDecimal(
+				20d));
+
+		Painting noMatch = new Painting();
+		assertFalse(btNull.match(noMatch));
+		assertFalse(btNotNull.match(noMatch));
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/069b8fbb/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTDbPathIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTDbPathIT.java b/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTDbPathIT.java
new file mode 100644
index 0000000..d4ae269
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTDbPathIT.java
@@ -0,0 +1,72 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.exp.parser;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.cayenne.Cayenne;
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.ExpressionFactory;
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.testdo.testmap.Artist;
+import org.apache.cayenne.unit.di.server.CayenneProjects;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+import org.junit.Test;
+
+@UseServerRuntime(CayenneProjects.TESTMAP_PROJECT)
+public class ASTDbPathIT extends ServerCase {
+
+	@Inject
+	private ObjectContext context;
+
+	@Test
+	public void testEvaluate_DbPath_DataObject() {
+
+		Artist a1 = context.newObject(Artist.class);
+		a1.setArtistName("a1");
+		context.commitChanges();
+
+		Expression idExp = ExpressionFactory.exp("db:ARTIST_ID");
+		assertEquals(Cayenne.longPKForObject(a1), idExp.evaluate(a1));
+
+		Expression columnExp = ExpressionFactory.exp("db:ARTIST_NAME");
+		assertEquals("a1", columnExp.evaluate(a1));
+	}
+
+	@Test
+	public void testEvaluate_DbPath_DbEntity() {
+		Expression e = ExpressionFactory.exp("db:paintingArray.PAINTING_TITLE");
+
+		ObjEntity ae = context.getEntityResolver().getObjEntity(Artist.class);
+		DbEntity ade = ae.getDbEntity();
+
+		Object objTarget = e.evaluate(ae);
+		assertTrue(objTarget instanceof DbAttribute);
+
+		Object dbTarget = e.evaluate(ade);
+		assertTrue(dbTarget instanceof DbAttribute);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/069b8fbb/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTDbPathTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTDbPathTest.java b/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTDbPathTest.java
index 3707b50..4e9f243 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTDbPathTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTDbPathTest.java
@@ -34,9 +34,7 @@ public class ASTDbPathTest {
     @Test
     public void testAppendAsString() throws IOException {
         StringBuilder buffer = new StringBuilder();
-
         new ASTDbPath("x.y").appendAsString(buffer);
-
         assertEquals("db:x.y", buffer.toString());
     }
     

http://git-wip-us.apache.org/repos/asf/cayenne/blob/069b8fbb/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTEqualIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTEqualIT.java b/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTEqualIT.java
new file mode 100644
index 0000000..5b056f2
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTEqualIT.java
@@ -0,0 +1,112 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.exp.parser;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.cayenne.Cayenne;
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.testdo.testmap.Artist;
+import org.apache.cayenne.testdo.testmap.Painting;
+import org.apache.cayenne.unit.di.server.CayenneProjects;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+import org.junit.Test;
+
+@UseServerRuntime(CayenneProjects.TESTMAP_PROJECT)
+public class ASTEqualIT extends ServerCase {
+
+	@Inject
+	private ObjectContext context;
+
+	@Test
+	public void testEvaluate_DataObject() {
+		Artist a1 = context.newObject(Artist.class);
+		Artist a2 = context.newObject(Artist.class);
+		Painting p1 = context.newObject(Painting.class);
+		Painting p2 = context.newObject(Painting.class);
+		Painting p3 = context.newObject(Painting.class);
+
+		a1.setArtistName("a1");
+		a2.setArtistName("a2");
+		p1.setPaintingTitle("p1");
+		p2.setPaintingTitle("p2");
+		p3.setPaintingTitle("p3");
+
+		context.commitChanges();
+
+		p1.setToArtist(a1);
+		p2.setToArtist(a2);
+
+		Expression e = new ASTEqual(new ASTObjPath("toArtist"), a1);
+
+		assertTrue(e.match(p1));
+		assertFalse(e.match(p2));
+		assertFalse(e.match(p3));
+	}
+
+	@Test
+	public void testEvaluate_TempId() {
+		Artist a1 = context.newObject(Artist.class);
+		Artist a2 = context.newObject(Artist.class);
+		Painting p1 = context.newObject(Painting.class);
+		Painting p2 = context.newObject(Painting.class);
+		Painting p3 = context.newObject(Painting.class);
+
+		p1.setToArtist(a1);
+		p2.setToArtist(a2);
+
+		Expression e = new ASTEqual(new ASTObjPath("toArtist"), a1.getObjectId());
+
+		assertTrue(e.match(p1));
+		assertFalse(e.match(p2));
+		assertFalse(e.match(p3));
+	}
+
+	@Test
+	public void testEvaluate_Id() throws Exception {
+
+		Artist a1 = context.newObject(Artist.class);
+		Artist a2 = context.newObject(Artist.class);
+		Painting p1 = context.newObject(Painting.class);
+		Painting p2 = context.newObject(Painting.class);
+		Painting p3 = context.newObject(Painting.class);
+		
+		a1.setArtistName("a1");
+		a2.setArtistName("a2");
+		p1.setPaintingTitle("p1");
+		p2.setPaintingTitle("p2");
+		p3.setPaintingTitle("p3");
+
+		p1.setToArtist(a1);
+		p2.setToArtist(a2);
+
+		context.commitChanges();
+
+		Expression e = new ASTEqual(new ASTObjPath("toArtist"), Cayenne.intPKForObject(a1));
+
+		assertTrue(e.match(p1));
+		assertFalse(e.match(p2));
+		assertFalse(e.match(p3));
+	}
+
+}