cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aadamc...@apache.org
Subject [3/8] Rename Integration Tests in cayenne-client (*IT.java instead of *Test.java)
Date Sun, 02 Nov 2014 07:38:59 GMT
http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/access/ClientServerChannelQueryIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/access/ClientServerChannelQueryIT.java b/cayenne-client/src/test/java/org/apache/cayenne/access/ClientServerChannelQueryIT.java
new file mode 100644
index 0000000..3210bbe
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/access/ClientServerChannelQueryIT.java
@@ -0,0 +1,239 @@
+/*****************************************************************
+ *   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.access;
+
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.ValueHolder;
+import org.apache.cayenne.cache.QueryCache;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.query.NamedQuery;
+import org.apache.cayenne.query.SelectQuery;
+import org.apache.cayenne.query.SortOrder;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.test.jdbc.TableHelper;
+import org.apache.cayenne.testdo.mt.ClientMtTable1;
+import org.apache.cayenne.testdo.mt.ClientMtTable2;
+import org.apache.cayenne.unit.di.client.ClientCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+import org.apache.cayenne.util.PersistentObjectHolder;
+import org.apache.cayenne.util.PersistentObjectList;
+
+import java.util.Collections;
+import java.util.List;
+
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class ClientServerChannelQueryIT extends ClientCase {
+
+    @Inject(ClientCase.ROP_CLIENT_KEY)
+    protected ObjectContext context;
+
+    @Inject
+    private ClientServerChannel serverChannel;
+
+    @Inject
+    private DBHelper dbHelper;
+
+    private TableHelper tMtTable1;
+    private TableHelper tMtTable2;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("MT_TABLE2");
+        dbHelper.deleteAll("MT_TABLE1");
+
+        tMtTable1 = new TableHelper(dbHelper, "MT_TABLE1");
+        tMtTable1.setColumns("TABLE1_ID", "GLOBAL_ATTRIBUTE1", "SERVER_ATTRIBUTE1");
+
+        tMtTable2 = new TableHelper(dbHelper, "MT_TABLE2");
+        tMtTable2.setColumns("TABLE2_ID", "TABLE1_ID", "GLOBAL_ATTRIBUTE");
+    }
+
+    protected void createSevenMtTable1sDataSet() throws Exception {
+
+        for (int i = 1; i <= 7; i++) {
+            tMtTable1.insert(i, "g" + i, "s" + i);
+        }
+    }
+
+    protected void createTwoMtTable1sAnd2sDataSet() throws Exception {
+
+        tMtTable1.insert(1, "g1", "s1");
+        tMtTable1.insert(2, "g2", "s2");
+
+        tMtTable2.insert(1, 1, "g1");
+        tMtTable2.insert(2, 1, "g2");
+    }
+
+    public void testPaginatedQueryServerCacheOverflow() throws Exception {
+        createSevenMtTable1sDataSet();
+
+        SelectQuery query = new SelectQuery(ClientMtTable1.class);
+        query.addOrdering(ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY, SortOrder.ASCENDING);
+        query.setPageSize(3);
+
+        List<?> results = context.performQuery(query);
+
+        // read page 1
+        assertTrue(results.get(0) instanceof ClientMtTable1);
+
+        // now kick out the server-side list from local cache, and see if the query would
+        // recover...
+        QueryCache qc = serverChannel.getQueryCache();
+        assertEquals(1, qc.size());
+        qc.clear();
+        assertEquals(0, qc.size());
+
+        assertTrue(results.get(3) instanceof ClientMtTable1);
+    }
+
+    public void testParameterizedMappedToEJBQLQueries() throws Exception {
+        createTwoMtTable1sAnd2sDataSet();
+
+        NamedQuery query = new NamedQuery("ParameterizedEJBQLMtQuery", Collections.singletonMap("g", "g1"));
+        
+        List<?> r1 = context.performQuery(query);
+        assertEquals(1, r1.size());
+        assertTrue(r1.get(0) instanceof ClientMtTable1);
+    }
+    
+    public void testNamedQuery() throws Exception {
+        createTwoMtTable1sAnd2sDataSet();
+
+        NamedQuery q = new NamedQuery("AllMtTable1");
+        List<?> results = context.performQuery(q);
+
+        assertEquals(2, results.size());
+        assertTrue(results.get(0) instanceof ClientMtTable1);
+    }
+
+    public void testSelectQueryEntityNameRoot() throws Exception {
+        createTwoMtTable1sAnd2sDataSet();
+
+        SelectQuery q = new SelectQuery("MtTable1");
+        List<?> results = context.performQuery(q);
+
+        assertEquals(2, results.size());
+
+        assertTrue(results.get(0) instanceof ClientMtTable1);
+    }
+
+    public void testSelectQueryClientClassRoot() throws Exception {
+        createTwoMtTable1sAnd2sDataSet();
+
+        SelectQuery q = new SelectQuery(ClientMtTable1.class);
+        List<?> results = context.performQuery(q);
+
+        assertEquals(2, results.size());
+        assertTrue(results.get(0) instanceof ClientMtTable1);
+    }
+
+    public void testSelectQuerySimpleQualifier() throws Exception {
+        createTwoMtTable1sAnd2sDataSet();
+
+        SelectQuery q = new SelectQuery(ClientMtTable1.class, Expression
+                .fromString("globalAttribute1 = 'g1'"));
+        List<?> results = context.performQuery(q);
+
+        assertEquals(1, results.size());
+
+        assertTrue(results.get(0) instanceof ClientMtTable1);
+    }
+
+    public void testSelectQueryToManyRelationshipQualifier() throws Exception {
+        createTwoMtTable1sAnd2sDataSet();
+
+        SelectQuery q = new SelectQuery(ClientMtTable1.class, Expression
+                .fromString("table2Array.globalAttribute = 'g1'"));
+        List<?> results = context.performQuery(q);
+
+        assertEquals(1, results.size());
+        assertTrue(results.get(0) instanceof ClientMtTable1);
+    }
+
+    public void testSelectQueryOrdering() throws Exception {
+        createTwoMtTable1sAnd2sDataSet();
+
+        SelectQuery q = new SelectQuery("MtTable1");
+        q.addOrdering(ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY, SortOrder.ASCENDING);
+        List<?> results = context.performQuery(q);
+
+        assertEquals(2, results.size());
+
+        ClientMtTable1 o1 = (ClientMtTable1) results.get(0);
+        ClientMtTable1 o2 = (ClientMtTable1) results.get(1);
+        assertTrue(o1.getGlobalAttribute1().compareTo(o2.getGlobalAttribute1()) < 0);
+
+        // now run the same query with reverse ordering to check that the first ordering
+        // result wasn't coincidental.
+
+        q.clearOrderings();
+        q.addOrdering(ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY, SortOrder.DESCENDING);
+        List<?> results1 = context.performQuery(q);
+
+        assertEquals(2, results1.size());
+
+        ClientMtTable1 o3 = (ClientMtTable1) results1.get(0);
+        ClientMtTable1 o4 = (ClientMtTable1) results1.get(1);
+        assertTrue(o3.getGlobalAttribute1().compareTo(o4.getGlobalAttribute1()) > 0);
+    }
+
+    public void testSelectQueryPrefetchToOne() throws Exception {
+        createTwoMtTable1sAnd2sDataSet();
+
+        SelectQuery q = new SelectQuery(ClientMtTable2.class, Expression
+                .fromString("globalAttribute = 'g1'"));
+        q.addPrefetch(ClientMtTable2.TABLE1_PROPERTY);
+        List<?> results = context.performQuery(q);
+
+        assertEquals(1, results.size());
+
+        ClientMtTable2 result = (ClientMtTable2) results.get(0);
+
+        ValueHolder holder = result.getTable1Direct();
+        assertNotNull(holder);
+        assertTrue(holder instanceof PersistentObjectHolder);
+        PersistentObjectHolder objectHolder = (PersistentObjectHolder) holder;
+        assertFalse(objectHolder.isFault());
+
+        ClientMtTable1 target = (ClientMtTable1) objectHolder.getValue();
+        assertNotNull(target);
+    }
+
+    public void testSelectQueryPrefetchToMany() throws Exception {
+        createTwoMtTable1sAnd2sDataSet();
+
+        SelectQuery q = new SelectQuery(ClientMtTable1.class, Expression
+                .fromString("globalAttribute1 = 'g1'"));
+        q.addPrefetch(ClientMtTable1.TABLE2ARRAY_PROPERTY);
+        List<?> results = context.performQuery(q);
+
+        assertEquals(1, results.size());
+
+        ClientMtTable1 result = (ClientMtTable1) results.get(0);
+
+        List<?> holder = result.getTable2ArrayDirect();
+        assertNotNull(holder);
+        assertTrue(holder instanceof PersistentObjectList);
+        PersistentObjectList objectHolder = (PersistentObjectList) holder;
+        assertFalse(objectHolder.isFault());
+        assertEquals(2, objectHolder.size());
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/access/ClientServerChannelQueryTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/access/ClientServerChannelQueryTest.java b/cayenne-client/src/test/java/org/apache/cayenne/access/ClientServerChannelQueryTest.java
deleted file mode 100644
index 4f117c1..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/access/ClientServerChannelQueryTest.java
+++ /dev/null
@@ -1,239 +0,0 @@
-/*****************************************************************
- *   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.access;
-
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.cayenne.ObjectContext;
-import org.apache.cayenne.ValueHolder;
-import org.apache.cayenne.cache.QueryCache;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.exp.Expression;
-import org.apache.cayenne.query.NamedQuery;
-import org.apache.cayenne.query.SelectQuery;
-import org.apache.cayenne.query.SortOrder;
-import org.apache.cayenne.test.jdbc.DBHelper;
-import org.apache.cayenne.test.jdbc.TableHelper;
-import org.apache.cayenne.testdo.mt.ClientMtTable1;
-import org.apache.cayenne.testdo.mt.ClientMtTable2;
-import org.apache.cayenne.unit.di.client.ClientCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-import org.apache.cayenne.util.PersistentObjectHolder;
-import org.apache.cayenne.util.PersistentObjectList;
-
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class ClientServerChannelQueryTest extends ClientCase {
-
-    @Inject(ClientCase.ROP_CLIENT_KEY)
-    protected ObjectContext context;
-
-    @Inject
-    private ClientServerChannel serverChannel;
-
-    @Inject
-    private DBHelper dbHelper;
-
-    private TableHelper tMtTable1;
-    private TableHelper tMtTable2;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("MT_TABLE2");
-        dbHelper.deleteAll("MT_TABLE1");
-
-        tMtTable1 = new TableHelper(dbHelper, "MT_TABLE1");
-        tMtTable1.setColumns("TABLE1_ID", "GLOBAL_ATTRIBUTE1", "SERVER_ATTRIBUTE1");
-
-        tMtTable2 = new TableHelper(dbHelper, "MT_TABLE2");
-        tMtTable2.setColumns("TABLE2_ID", "TABLE1_ID", "GLOBAL_ATTRIBUTE");
-    }
-
-    protected void createSevenMtTable1sDataSet() throws Exception {
-
-        for (int i = 1; i <= 7; i++) {
-            tMtTable1.insert(i, "g" + i, "s" + i);
-        }
-    }
-
-    protected void createTwoMtTable1sAnd2sDataSet() throws Exception {
-
-        tMtTable1.insert(1, "g1", "s1");
-        tMtTable1.insert(2, "g2", "s2");
-
-        tMtTable2.insert(1, 1, "g1");
-        tMtTable2.insert(2, 1, "g2");
-    }
-
-    public void testPaginatedQueryServerCacheOverflow() throws Exception {
-        createSevenMtTable1sDataSet();
-
-        SelectQuery query = new SelectQuery(ClientMtTable1.class);
-        query.addOrdering(ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY, SortOrder.ASCENDING);
-        query.setPageSize(3);
-
-        List<?> results = context.performQuery(query);
-
-        // read page 1
-        assertTrue(results.get(0) instanceof ClientMtTable1);
-
-        // now kick out the server-side list from local cache, and see if the query would
-        // recover...
-        QueryCache qc = serverChannel.getQueryCache();
-        assertEquals(1, qc.size());
-        qc.clear();
-        assertEquals(0, qc.size());
-
-        assertTrue(results.get(3) instanceof ClientMtTable1);
-    }
-
-    public void testParameterizedMappedToEJBQLQueries() throws Exception {
-        createTwoMtTable1sAnd2sDataSet();
-
-        NamedQuery query = new NamedQuery("ParameterizedEJBQLMtQuery", Collections.singletonMap("g", "g1"));
-        
-        List<?> r1 = context.performQuery(query);
-        assertEquals(1, r1.size());
-        assertTrue(r1.get(0) instanceof ClientMtTable1);
-    }
-    
-    public void testNamedQuery() throws Exception {
-        createTwoMtTable1sAnd2sDataSet();
-
-        NamedQuery q = new NamedQuery("AllMtTable1");
-        List<?> results = context.performQuery(q);
-
-        assertEquals(2, results.size());
-        assertTrue(results.get(0) instanceof ClientMtTable1);
-    }
-
-    public void testSelectQueryEntityNameRoot() throws Exception {
-        createTwoMtTable1sAnd2sDataSet();
-
-        SelectQuery q = new SelectQuery("MtTable1");
-        List<?> results = context.performQuery(q);
-
-        assertEquals(2, results.size());
-
-        assertTrue(results.get(0) instanceof ClientMtTable1);
-    }
-
-    public void testSelectQueryClientClassRoot() throws Exception {
-        createTwoMtTable1sAnd2sDataSet();
-
-        SelectQuery q = new SelectQuery(ClientMtTable1.class);
-        List<?> results = context.performQuery(q);
-
-        assertEquals(2, results.size());
-        assertTrue(results.get(0) instanceof ClientMtTable1);
-    }
-
-    public void testSelectQuerySimpleQualifier() throws Exception {
-        createTwoMtTable1sAnd2sDataSet();
-
-        SelectQuery q = new SelectQuery(ClientMtTable1.class, Expression
-                .fromString("globalAttribute1 = 'g1'"));
-        List<?> results = context.performQuery(q);
-
-        assertEquals(1, results.size());
-
-        assertTrue(results.get(0) instanceof ClientMtTable1);
-    }
-
-    public void testSelectQueryToManyRelationshipQualifier() throws Exception {
-        createTwoMtTable1sAnd2sDataSet();
-
-        SelectQuery q = new SelectQuery(ClientMtTable1.class, Expression
-                .fromString("table2Array.globalAttribute = 'g1'"));
-        List<?> results = context.performQuery(q);
-
-        assertEquals(1, results.size());
-        assertTrue(results.get(0) instanceof ClientMtTable1);
-    }
-
-    public void testSelectQueryOrdering() throws Exception {
-        createTwoMtTable1sAnd2sDataSet();
-
-        SelectQuery q = new SelectQuery("MtTable1");
-        q.addOrdering(ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY, SortOrder.ASCENDING);
-        List<?> results = context.performQuery(q);
-
-        assertEquals(2, results.size());
-
-        ClientMtTable1 o1 = (ClientMtTable1) results.get(0);
-        ClientMtTable1 o2 = (ClientMtTable1) results.get(1);
-        assertTrue(o1.getGlobalAttribute1().compareTo(o2.getGlobalAttribute1()) < 0);
-
-        // now run the same query with reverse ordering to check that the first ordering
-        // result wasn't coincidental.
-
-        q.clearOrderings();
-        q.addOrdering(ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY, SortOrder.DESCENDING);
-        List<?> results1 = context.performQuery(q);
-
-        assertEquals(2, results1.size());
-
-        ClientMtTable1 o3 = (ClientMtTable1) results1.get(0);
-        ClientMtTable1 o4 = (ClientMtTable1) results1.get(1);
-        assertTrue(o3.getGlobalAttribute1().compareTo(o4.getGlobalAttribute1()) > 0);
-    }
-
-    public void testSelectQueryPrefetchToOne() throws Exception {
-        createTwoMtTable1sAnd2sDataSet();
-
-        SelectQuery q = new SelectQuery(ClientMtTable2.class, Expression
-                .fromString("globalAttribute = 'g1'"));
-        q.addPrefetch(ClientMtTable2.TABLE1_PROPERTY);
-        List<?> results = context.performQuery(q);
-
-        assertEquals(1, results.size());
-
-        ClientMtTable2 result = (ClientMtTable2) results.get(0);
-
-        ValueHolder holder = result.getTable1Direct();
-        assertNotNull(holder);
-        assertTrue(holder instanceof PersistentObjectHolder);
-        PersistentObjectHolder objectHolder = (PersistentObjectHolder) holder;
-        assertFalse(objectHolder.isFault());
-
-        ClientMtTable1 target = (ClientMtTable1) objectHolder.getValue();
-        assertNotNull(target);
-    }
-
-    public void testSelectQueryPrefetchToMany() throws Exception {
-        createTwoMtTable1sAnd2sDataSet();
-
-        SelectQuery q = new SelectQuery(ClientMtTable1.class, Expression
-                .fromString("globalAttribute1 = 'g1'"));
-        q.addPrefetch(ClientMtTable1.TABLE2ARRAY_PROPERTY);
-        List<?> results = context.performQuery(q);
-
-        assertEquals(1, results.size());
-
-        ClientMtTable1 result = (ClientMtTable1) results.get(0);
-
-        List<?> holder = result.getTable2ArrayDirect();
-        assertNotNull(holder);
-        assertTrue(holder instanceof PersistentObjectList);
-        PersistentObjectList objectHolder = (PersistentObjectList) holder;
-        assertFalse(objectHolder.isFault());
-        assertEquals(2, objectHolder.size());
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/access/ClientServerChannelTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/access/ClientServerChannelTest.java b/cayenne-client/src/test/java/org/apache/cayenne/access/ClientServerChannelTest.java
deleted file mode 100644
index cc5cd9e..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/access/ClientServerChannelTest.java
+++ /dev/null
@@ -1,260 +0,0 @@
-/*****************************************************************
- *   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.access;
-
-import java.util.List;
-
-import org.apache.cayenne.DataChannel;
-import org.apache.cayenne.MockDataChannel;
-import org.apache.cayenne.ObjectContext;
-import org.apache.cayenne.ObjectId;
-import org.apache.cayenne.QueryResponse;
-import org.apache.cayenne.ValueHolder;
-import org.apache.cayenne.configuration.server.ServerRuntime;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.graph.MockGraphDiff;
-import org.apache.cayenne.graph.NodeCreateOperation;
-import org.apache.cayenne.log.JdbcEventLogger;
-import org.apache.cayenne.map.EntityResolver;
-import org.apache.cayenne.query.MockQuery;
-import org.apache.cayenne.query.Query;
-import org.apache.cayenne.query.SelectQuery;
-import org.apache.cayenne.query.SortOrder;
-import org.apache.cayenne.remote.QueryMessage;
-import org.apache.cayenne.test.jdbc.DBHelper;
-import org.apache.cayenne.test.jdbc.TableHelper;
-import org.apache.cayenne.testdo.mt.ClientMtTable1;
-import org.apache.cayenne.testdo.mt.ClientMtTable1Subclass1;
-import org.apache.cayenne.testdo.mt.ClientMtTable2;
-import org.apache.cayenne.testdo.mt.ClientMtTable3;
-import org.apache.cayenne.testdo.mt.MtTable1;
-import org.apache.cayenne.unit.di.DataChannelInterceptor;
-import org.apache.cayenne.unit.di.UnitTestClosure;
-import org.apache.cayenne.unit.di.client.ClientCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-import org.apache.cayenne.util.EqualsBuilder;
-
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class ClientServerChannelTest extends ClientCase {
-
-    @Inject
-    protected DataContext serverContext;
-
-    @Inject
-    protected ClientServerChannel clientServerChannel;
-
-    @Inject
-    protected DBHelper dbHelper;
-
-    @Inject
-    protected DataChannelInterceptor queryInterceptor;
-
-    @Inject
-    protected JdbcEventLogger logger;
-
-    @Inject
-    private ServerRuntime runtime;
-
-    private TableHelper tMtTable1;
-    private TableHelper tMtTable2;
-    private TableHelper tMtTable3;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("MT_TABLE2");
-        dbHelper.deleteAll("MT_TABLE1");
-        dbHelper.deleteAll("MT_TABLE3");
-
-        tMtTable1 = new TableHelper(dbHelper, "MT_TABLE1");
-        tMtTable1.setColumns("TABLE1_ID", "GLOBAL_ATTRIBUTE1", "SERVER_ATTRIBUTE1");
-
-        tMtTable2 = new TableHelper(dbHelper, "MT_TABLE2");
-        tMtTable2.setColumns("TABLE2_ID", "TABLE1_ID", "GLOBAL_ATTRIBUTE");
-
-        tMtTable3 = new TableHelper(dbHelper, "MT_TABLE3");
-        tMtTable3.setColumns("TABLE3_ID", "BINARY_COLUMN", "CHAR_COLUMN", "INT_COLUMN");
-    }
-
-    protected void createTwoMtTable1sAnd2sDataSet() throws Exception {
-
-        tMtTable1.insert(1, "g1", "s1");
-        tMtTable1.insert(2, "g2", "s2");
-
-        tMtTable2.insert(1, 1, "g1");
-        tMtTable2.insert(2, 1, "g2");
-    }
-
-    public void testGetEntityResolver() throws Exception {
-        EntityResolver resolver = clientServerChannel.getEntityResolver();
-        assertNotNull(resolver);
-        assertNull(resolver.getObjEntity(ClientMtTable1.class));
-        assertNotNull(resolver.getClientEntityResolver().getObjEntity(ClientMtTable1.class));
-    }
-
-    public void testSynchronizeCommit() throws Exception {
-
-        SelectQuery query = new SelectQuery(MtTable1.class);
-
-        // no changes...
-        clientServerChannel.onSync(serverContext, new MockGraphDiff(), DataChannel.FLUSH_CASCADE_SYNC);
-
-        assertEquals(0, serverContext.performQuery(query).size());
-
-        // introduce changes
-        clientServerChannel.onSync(serverContext, new NodeCreateOperation(new ObjectId("MtTable1")),
-                DataChannel.FLUSH_CASCADE_SYNC);
-
-        assertEquals(1, serverContext.performQuery(query).size());
-    }
-
-    public void testPerformQueryObjectIDInjection() throws Exception {
-        tMtTable1.insert(55, "g1", "s1");
-
-        Query query = new SelectQuery("MtTable1");
-        QueryResponse response = clientServerChannel.onQuery(null, query);
-
-        assertNotNull(response);
-
-        List<?> results = response.firstList();
-
-        assertNotNull(results);
-        assertEquals(1, results.size());
-
-        Object result = results.get(0);
-        assertTrue(result instanceof ClientMtTable1);
-        ClientMtTable1 clientObject = (ClientMtTable1) result;
-        assertNotNull(clientObject.getObjectId());
-
-        assertEquals(new ObjectId("MtTable1", MtTable1.TABLE1_ID_PK_COLUMN, 55), clientObject.getObjectId());
-    }
-
-    public void testPerformQueryValuePropagation() throws Exception {
-
-        byte[] bytes = new byte[] { 1, 2, 3 };
-
-        tMtTable3.insert(1, bytes, "abc", 4);
-
-        Query query = new SelectQuery("MtTable3");
-        QueryResponse response = clientServerChannel.onQuery(null, query);
-
-        assertNotNull(response);
-
-        List<?> results = response.firstList();
-
-        assertNotNull(results);
-        assertEquals(1, results.size());
-
-        Object result = results.get(0);
-        assertTrue("Result is of wrong type: " + result, result instanceof ClientMtTable3);
-        ClientMtTable3 clientObject = (ClientMtTable3) result;
-
-        assertEquals("abc", clientObject.getCharColumn());
-        assertEquals(new Integer(4), clientObject.getIntColumn());
-        assertTrue(new EqualsBuilder().append(clientObject.getBinaryColumn(), bytes).isEquals());
-    }
-
-    public void testPerformQueryPropagationInheritance() throws Exception {
-
-        tMtTable1.insert(65, "sub1", "xyz");
-
-        SelectQuery query = new SelectQuery(ClientMtTable1.class);
-        QueryResponse response = clientServerChannel.onQuery(null, query);
-
-        assertNotNull(response);
-
-        List<?> results = response.firstList();
-
-        assertNotNull(results);
-        assertEquals(1, results.size());
-
-        Object result = results.get(0);
-        assertTrue("Result is of wrong type: " + result, result instanceof ClientMtTable1Subclass1);
-        ClientMtTable1Subclass1 clientObject = (ClientMtTable1Subclass1) result;
-
-        assertEquals("sub1", clientObject.getGlobalAttribute1());
-    }
-
-    public void testOnQuery() {
-
-        final boolean[] genericDone = new boolean[1];
-        MockDataChannel parent = new MockDataChannel(new EntityResolver()) {
-
-            @Override
-            public QueryResponse onQuery(ObjectContext context, Query query) {
-                genericDone[0] = true;
-                return super.onQuery(context, query);
-            }
-        };
-        DataContext context = (DataContext) runtime.newContext(parent);
-
-        QueryMessage message = new QueryMessage(new MockQuery());
-        new ClientServerChannel(context).onQuery(null, message.getQuery());
-        assertTrue(genericDone[0]);
-    }
-
-    public void testOnQueryPrefetchingToMany() throws Exception {
-        createTwoMtTable1sAnd2sDataSet();
-
-        SelectQuery query = new SelectQuery(ClientMtTable1.class);
-        query.addOrdering(ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY, SortOrder.ASCENDING);
-        query.addPrefetch(ClientMtTable1.TABLE2ARRAY_PROPERTY);
-
-        final List<?> results = clientServerChannel.onQuery(null, query).firstList();
-
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                ClientMtTable1 o1 = (ClientMtTable1) results.get(0);
-                assertNull(o1.getObjectContext());
-
-                List<ClientMtTable2> children1 = o1.getTable2Array();
-
-                assertEquals(2, children1.size());
-                for (ClientMtTable2 o : children1) {
-                    assertNull(o.getObjectContext());
-                }
-            }
-        });
-    }
-
-    public void testOnQueryPrefetchingToManyEmpty() throws Exception {
-        createTwoMtTable1sAnd2sDataSet();
-
-        SelectQuery q = new SelectQuery(ClientMtTable1.class);
-        q.addOrdering(ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY, SortOrder.ASCENDING);
-        q.addPrefetch(ClientMtTable1.TABLE2ARRAY_PROPERTY);
-
-        final List<?> results = clientServerChannel.onQuery(null, q).firstList();
-
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-
-                ClientMtTable1 o2 = (ClientMtTable1) results.get(1);
-                assertNull(o2.getObjectContext());
-
-                List<?> children2 = o2.getTable2Array();
-                assertNotNull(children2);
-                assertFalse(((ValueHolder) children2).isFault());
-                assertEquals(0, children2.size());
-            }
-        });
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/map/ClientEntityResolverIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/map/ClientEntityResolverIT.java b/cayenne-client/src/test/java/org/apache/cayenne/map/ClientEntityResolverIT.java
new file mode 100644
index 0000000..b2a9549
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/map/ClientEntityResolverIT.java
@@ -0,0 +1,62 @@
+/*****************************************************************
+ *   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.map;
+
+import org.apache.cayenne.remote.hessian.service.HessianUtil;
+import org.apache.cayenne.testdo.testmap.Artist;
+import org.apache.cayenne.unit.di.client.ClientCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+import java.util.Collection;
+import java.util.Collections;
+
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class ClientEntityResolverIT extends ClientCase {
+
+    public void testSerializabilityWithHessian() throws Exception {
+        ObjEntity entity = new ObjEntity("test_entity");
+        entity.setClassName(Artist.class.getName());
+
+        DataMap dataMap = new DataMap("test");
+        dataMap.addObjEntity(entity);
+        Collection<DataMap> maps = Collections.singleton(dataMap);
+        EntityResolver resolver = new EntityResolver(maps);
+
+        // 1. simple case
+        Object c1 = HessianUtil.cloneViaClientServerSerialization(resolver, new EntityResolver());
+
+        assertNotNull(c1);
+        assertTrue(c1 instanceof EntityResolver);
+        EntityResolver cr1 = (EntityResolver) c1;
+
+        assertNotSame(resolver, cr1);
+        assertEquals(1, cr1.getObjEntities().size());
+        assertNotNull(cr1.getObjEntity(entity.getName()));
+
+        // 2. with descriptors resolved...
+        assertNotNull(resolver.getClassDescriptor(entity.getName()));
+
+        EntityResolver cr2 = (EntityResolver) HessianUtil.cloneViaClientServerSerialization(resolver,
+                new EntityResolver());
+        assertNotNull(cr2);
+        assertEquals(1, cr2.getObjEntities().size());
+        assertNotNull(cr2.getObjEntity(entity.getName()));
+        assertNotNull(cr2.getClassDescriptor(entity.getName()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/map/ClientEntityResolverTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/map/ClientEntityResolverTest.java b/cayenne-client/src/test/java/org/apache/cayenne/map/ClientEntityResolverTest.java
deleted file mode 100644
index 93420cd..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/map/ClientEntityResolverTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*****************************************************************
- *   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.map;
-
-import java.util.Collection;
-import java.util.Collections;
-
-import org.apache.cayenne.remote.hessian.service.HessianUtil;
-import org.apache.cayenne.testdo.testmap.Artist;
-import org.apache.cayenne.unit.di.client.ClientCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class ClientEntityResolverTest extends ClientCase {
-
-    public void testSerializabilityWithHessian() throws Exception {
-        ObjEntity entity = new ObjEntity("test_entity");
-        entity.setClassName(Artist.class.getName());
-
-        DataMap dataMap = new DataMap("test");
-        dataMap.addObjEntity(entity);
-        Collection<DataMap> maps = Collections.singleton(dataMap);
-        EntityResolver resolver = new EntityResolver(maps);
-
-        // 1. simple case
-        Object c1 = HessianUtil.cloneViaClientServerSerialization(resolver, new EntityResolver());
-
-        assertNotNull(c1);
-        assertTrue(c1 instanceof EntityResolver);
-        EntityResolver cr1 = (EntityResolver) c1;
-
-        assertNotSame(resolver, cr1);
-        assertEquals(1, cr1.getObjEntities().size());
-        assertNotNull(cr1.getObjEntity(entity.getName()));
-
-        // 2. with descriptors resolved...
-        assertNotNull(resolver.getClassDescriptor(entity.getName()));
-
-        EntityResolver cr2 = (EntityResolver) HessianUtil.cloneViaClientServerSerialization(resolver,
-                new EntityResolver());
-        assertNotNull(cr2);
-        assertEquals(1, cr2.getObjEntities().size());
-        assertNotNull(cr2.getObjEntity(entity.getName()));
-        assertNotNull(cr2.getClassDescriptor(entity.getName()));
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/query/ClientExpressionIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/query/ClientExpressionIT.java b/cayenne-client/src/test/java/org/apache/cayenne/query/ClientExpressionIT.java
new file mode 100644
index 0000000..643de29
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/query/ClientExpressionIT.java
@@ -0,0 +1,319 @@
+/*****************************************************************
+ *   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.query;
+
+import org.apache.cayenne.CayenneContext;
+import org.apache.cayenne.ObjectId;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.ExpressionFactory;
+import org.apache.cayenne.exp.parser.ASTEqual;
+import org.apache.cayenne.exp.parser.ASTList;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.test.jdbc.TableHelper;
+import org.apache.cayenne.testdo.mt.ClientMtTable1;
+import org.apache.cayenne.testdo.mt.ClientMtTable2;
+import org.apache.cayenne.unit.di.client.ClientCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class ClientExpressionIT extends ClientCase {
+    
+    @Inject
+    private CayenneContext context;
+    
+    @Inject
+    private DBHelper dbHelper;
+    
+    private TableHelper tMtTable1;
+    private TableHelper tMtTable2;
+    
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("MT_TABLE2");
+        dbHelper.deleteAll("MT_TABLE1");
+        
+        tMtTable1 = new TableHelper(dbHelper, "MT_TABLE1");
+        tMtTable1.setColumns("TABLE1_ID", "GLOBAL_ATTRIBUTE1", "SERVER_ATTRIBUTE1");
+        
+        tMtTable2 = new TableHelper(dbHelper, "MT_TABLE2");
+        tMtTable2.setColumns("TABLE2_ID", "TABLE1_ID", "GLOBAL_ATTRIBUTE");
+    }
+    
+    protected void createDataSet() throws Exception {
+        for(int i = 1; i <= 10; i++) {
+            tMtTable1.insert(i ,"1_global" + i, "server" + i);
+            tMtTable2.insert(i , i, "2_global" + i);
+            tMtTable2.insert(i + 10, i, "2_global" + (i + 10));
+        }
+    }
+    
+    public void testPersistentValueInExpression() throws Exception {
+        ClientMtTable1 t1 = context.newObject(ClientMtTable1.class);
+        ClientMtTable1 t2 = context.newObject(ClientMtTable1.class);
+        
+        context.commitChanges();
+        
+        Expression scalar = ExpressionFactory.matchExp(null, t1);
+        Expression list = ExpressionFactory.matchAllExp("|", Arrays.asList(t1, t2));
+        
+        assertEquals(t1.getObjectId(), scalar.getOperand(1));
+        assertEquals(t1.getObjectId(), ((ASTEqual)list.getOperand(0)).getOperand(1));
+        assertEquals(t2.getObjectId(), ((ASTEqual)list.getOperand(1)).getOperand(1));
+    }
+    
+    public void testListInASTList() throws Exception {
+        ClientMtTable1 t1 = context.newObject(ClientMtTable1.class);
+        ClientMtTable1 t2 = context.newObject(ClientMtTable1.class);
+        
+        context.commitChanges();
+        
+        List<ClientMtTable1> table1List = new ArrayList<ClientMtTable1>();
+        table1List.add(t1);
+        table1List.add(t2);
+        
+        // send list in expression factory
+        Expression list = ExpressionFactory.inExp(ClientMtTable2.TABLE1_PROPERTY, table1List);
+        
+        Object[] values = (Object[])((ASTList)list.getOperand(1)).getOperand(0);
+        assertEquals(t1.getObjectId(), values[0]);
+        assertEquals(t2.getObjectId(), values[1]);
+        
+        ObjectId t1Id = new ObjectId("MtTable1", "TABLE1_ID", 1);
+        ObjectId t2Id = new ObjectId("MtTable1", "TABLE1_ID", 2);
+        t1.setObjectId(t1Id);
+        t2.setObjectId(t2Id);
+
+        //Expression and client have different copies of object
+        assertNotSame(t1.getObjectId(), values[0]);
+        assertNotSame(t2.getObjectId(), values[1]);
+    }
+    
+    public void testArrayInASTList() throws Exception {
+        ClientMtTable1 t1 = context.newObject(ClientMtTable1.class);
+        ClientMtTable1 t2 = context.newObject(ClientMtTable1.class);
+        ClientMtTable1 t3 = context.newObject(ClientMtTable1.class);
+        
+        context.commitChanges();
+        
+        Object[] tArray = new Object[3];
+        tArray[0] = t1;
+        tArray[1] = t2;
+        
+        // send array in expression factory
+        Expression list = ExpressionFactory.inExp(ClientMtTable2.TABLE1_PROPERTY, tArray);
+        tArray[2] = t3;
+        
+        Object[] values = (Object[])((ASTList)list.getOperand(1)).getOperand(0);
+        assertEquals(tArray.length, values.length);
+        assertNotSame(tArray[2], values[2]);
+        assertEquals(t1.getObjectId(), values[0]);
+        assertEquals(t2.getObjectId(), values[1]);
+        
+        ObjectId t1Id = new ObjectId("MtTable1", "TABLE1_ID", 1);
+        ObjectId t2Id = new ObjectId("MtTable1", "TABLE1_ID", 2);
+        t1.setObjectId(t1Id);
+        t2.setObjectId(t2Id);
+        
+        // Expression and client have different arrays
+        assertNotSame(t1.getObjectId(), values[0]);
+        assertNotSame(t2.getObjectId(), values[1]);
+    }
+    
+    public void testExpressionFactoryMatch() throws Exception {
+        createDataSet();
+        
+        SelectQuery<ClientMtTable1> table1Query = new SelectQuery<ClientMtTable1>(ClientMtTable1.class);
+        table1Query.addOrdering(new Ordering("db:TABLE1_ID", SortOrder.ASCENDING));
+        List<ClientMtTable1> table1List = context.select(table1Query);
+        
+        assertNotNull(table1List);
+        
+        ClientMtTable1 element_1 = table1List.get(0);
+        ClientMtTable1 element_2 = table1List.get(1);
+        
+        Expression exp = ExpressionFactory.matchExp(ClientMtTable2.TABLE1_PROPERTY, element_1);
+        SelectQuery<ClientMtTable2> table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class, exp);
+        List<ClientMtTable2> table2List = context.select(table2Query);
+        
+        assertNotNull(table2List);
+        assertEquals(2, table2List.size());
+        
+        exp = ExpressionFactory.matchExp(element_2);
+        table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class, exp);
+        table2List = context.select(table2Query);
+
+        assertNotNull(table2List);
+        assertEquals(2, table2List.size());
+    }
+    
+    public void testExpressionFactoryMatchAll() throws Exception {
+        createDataSet();
+        
+        SelectQuery<ClientMtTable2> table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class);
+        table2Query.addOrdering(new Ordering("db:TABLE2_ID", SortOrder.ASCENDING));
+        List<ClientMtTable2> table2List = context.select(table2Query);
+        
+        ClientMtTable2 element_1 = table2List.get(0);
+        ClientMtTable2 element_2 = table2List.get(10);
+        
+        assertEquals(element_1.getTable1(), element_2.getTable1());
+        
+        Expression exp = ExpressionFactory.matchAllExp("|"+ClientMtTable1.TABLE2ARRAY_PROPERTY, Arrays.asList(element_1, element_2));
+        SelectQuery<ClientMtTable1> table1Query = new SelectQuery<ClientMtTable1>(ClientMtTable1.class, exp);
+        List<ClientMtTable1> table1List = context.select(table1Query);
+        
+        assertEquals(1, table1List.size());
+    }
+    
+    public void testExpressionFactoryMatchAny() throws Exception {
+        createDataSet();
+        
+        SelectQuery<ClientMtTable2> table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class);
+        table2Query.addOrdering(new Ordering("db:TABLE2_ID", SortOrder.ASCENDING));
+        List<ClientMtTable2> table2List = context.select(table2Query);
+        
+        ClientMtTable2 element_1 = table2List.get(0);
+        ClientMtTable2 element_2 = table2List.get(10);
+        
+        Expression exp = ExpressionFactory.matchAnyExp(element_1, element_2);
+        table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class, exp);
+        table2List = context.select(table2Query);
+        
+        assertEquals(2, table2List.size());
+    }
+    
+    public void testExpressionFactoryIn() throws Exception {
+        createDataSet();
+        
+        SelectQuery<ClientMtTable1> table1Query = new SelectQuery<ClientMtTable1>(ClientMtTable1.class);
+        table1Query.addOrdering(new Ordering("db:TABLE1_ID", SortOrder.ASCENDING));
+        List<ClientMtTable1> table1List = context.select(table1Query);
+        
+        ClientMtTable1 element_3 = table1List.get(2);
+        ClientMtTable1 element_8 = table1List.get(7);
+        
+        // IN expression via Collection
+        Expression exp = ExpressionFactory.inExp(ClientMtTable2.TABLE1_PROPERTY, table1List.subList(3, 6));
+        SelectQuery<ClientMtTable2> table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class, exp);
+        List<ClientMtTable2> table2List = context.select(table2Query);
+        
+        assertEquals(6, table2List.size());
+        
+        // IN expression via Array
+        exp = ExpressionFactory.inExp(ClientMtTable2.TABLE1_PROPERTY, element_3, element_8);
+        table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class, exp);
+        table2List = context.select(table2Query);
+        
+        assertEquals(4, table2List.size());
+    }
+    
+    public void testExpressionFactoryBetween() throws Exception {
+        createDataSet();
+        
+        SelectQuery<ClientMtTable1> table1Query = new SelectQuery<ClientMtTable1>(ClientMtTable1.class);
+        table1Query.addOrdering(new Ordering("db:TABLE1_ID", SortOrder.ASCENDING));
+        List<ClientMtTable1> table1List = context.select(table1Query);
+        
+        ClientMtTable1 element_1 = table1List.get(0);
+        ClientMtTable1 element_7 = table1List.get(6);
+        
+        // between
+        Expression exp = ExpressionFactory.betweenExp(ClientMtTable2.TABLE1_PROPERTY, element_1, element_7);
+        SelectQuery<ClientMtTable2> table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class, exp);
+        List<ClientMtTable2> table2List = context.select(table2Query);
+        
+        assertEquals(14, table2List.size());
+        
+        // not between
+        exp = ExpressionFactory.notBetweenExp(ClientMtTable2.TABLE1_PROPERTY, element_1, element_7);
+        table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class, exp);
+        table2List = context.select(table2Query);
+        
+        assertEquals(6, table2List.size());
+    }
+    
+    public void testExpressionFactoryOperators() throws Exception {
+        createDataSet();
+        
+        SelectQuery<ClientMtTable1> table1Query = new SelectQuery<ClientMtTable1>(ClientMtTable1.class);
+        table1Query.addOrdering(new Ordering("db:TABLE1_ID", SortOrder.ASCENDING));
+        List<ClientMtTable1> table1List = context.select(table1Query);
+        
+        ClientMtTable1 element_7 = table1List.get(6);
+        
+        // greater than, ">"
+        Expression exp = ExpressionFactory.greaterExp(ClientMtTable2.TABLE1_PROPERTY, element_7);
+        SelectQuery<ClientMtTable2> table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class, exp);
+        List<ClientMtTable2> table2List = context.select(table2Query);
+        
+        assertEquals(6, table2List.size());
+        
+        // greater than or equal, ">="
+        exp = ExpressionFactory.greaterOrEqualExp(ClientMtTable2.TABLE1_PROPERTY, element_7);
+        table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class, exp);
+        table2List = context.select(table2Query);
+        
+        assertEquals(8, table2List.size());
+        
+        // less than, "<"
+        exp = ExpressionFactory.lessExp(ClientMtTable2.TABLE1_PROPERTY, element_7);
+        table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class, exp);
+        table2List = context.select(table2Query);
+        
+        assertEquals(12, table2List.size());
+        
+        // less than or equal, "<="
+        exp = ExpressionFactory.lessOrEqualExp(ClientMtTable2.TABLE1_PROPERTY, element_7);
+        table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class, exp);
+        table2List = context.select(table2Query);
+        
+        assertEquals(14, table2List.size());
+    }
+    
+    public void testExpressionWithParameters() throws Exception {
+        createDataSet();
+        
+        SelectQuery<ClientMtTable1> table1Query = new SelectQuery<ClientMtTable1>(ClientMtTable1.class);
+        table1Query.addOrdering(new Ordering("db:TABLE1_ID", SortOrder.ASCENDING));
+        List<ClientMtTable1> table1List = context.select(table1Query);
+        
+        ClientMtTable1 element_1 = table1List.get(0);
+        ClientMtTable1 element_5 = table1List.get(4);
+        
+        Expression exp = Expression.fromString("table1 = $attr");
+        exp = exp.expWithParameters(Collections.singletonMap("attr", element_1));
+        SelectQuery<ClientMtTable2> table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class, exp);
+        List<ClientMtTable2> table2List = context.select(table2Query);
+        
+        assertEquals(2, table2List.size());
+        
+        exp = exp.andExp(Expression.fromString("table1 = $attr"))
+                .expWithParameters(Collections.singletonMap("attr", element_5));
+        table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class, exp);
+        table2List = context.select(table2Query);
+        
+        assertEquals(0, table2List.size());
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/query/ClientExpressionTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/query/ClientExpressionTest.java b/cayenne-client/src/test/java/org/apache/cayenne/query/ClientExpressionTest.java
deleted file mode 100644
index 1b36e88..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/query/ClientExpressionTest.java
+++ /dev/null
@@ -1,319 +0,0 @@
-/*****************************************************************
- *   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.query;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.cayenne.CayenneContext;
-import org.apache.cayenne.ObjectId;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.exp.Expression;
-import org.apache.cayenne.exp.ExpressionFactory;
-import org.apache.cayenne.exp.parser.ASTEqual;
-import org.apache.cayenne.exp.parser.ASTList;
-import org.apache.cayenne.test.jdbc.DBHelper;
-import org.apache.cayenne.test.jdbc.TableHelper;
-import org.apache.cayenne.testdo.mt.ClientMtTable1;
-import org.apache.cayenne.testdo.mt.ClientMtTable2;
-import org.apache.cayenne.unit.di.client.ClientCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class ClientExpressionTest extends ClientCase {
-    
-    @Inject
-    private CayenneContext context;
-    
-    @Inject
-    private DBHelper dbHelper;
-    
-    private TableHelper tMtTable1;
-    private TableHelper tMtTable2;
-    
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("MT_TABLE2");
-        dbHelper.deleteAll("MT_TABLE1");
-        
-        tMtTable1 = new TableHelper(dbHelper, "MT_TABLE1");
-        tMtTable1.setColumns("TABLE1_ID", "GLOBAL_ATTRIBUTE1", "SERVER_ATTRIBUTE1");
-        
-        tMtTable2 = new TableHelper(dbHelper, "MT_TABLE2");
-        tMtTable2.setColumns("TABLE2_ID", "TABLE1_ID", "GLOBAL_ATTRIBUTE");
-    }
-    
-    protected void createDataSet() throws Exception {
-        for(int i = 1; i <= 10; i++) {
-            tMtTable1.insert(i ,"1_global" + i, "server" + i);
-            tMtTable2.insert(i , i, "2_global" + i);
-            tMtTable2.insert(i + 10, i, "2_global" + (i + 10));
-        }
-    }
-    
-    public void testPersistentValueInExpression() throws Exception {
-        ClientMtTable1 t1 = context.newObject(ClientMtTable1.class);
-        ClientMtTable1 t2 = context.newObject(ClientMtTable1.class);
-        
-        context.commitChanges();
-        
-        Expression scalar = ExpressionFactory.matchExp(null, t1);
-        Expression list = ExpressionFactory.matchAllExp("|", Arrays.asList(t1, t2));
-        
-        assertEquals(t1.getObjectId(), scalar.getOperand(1));
-        assertEquals(t1.getObjectId(), ((ASTEqual)list.getOperand(0)).getOperand(1));
-        assertEquals(t2.getObjectId(), ((ASTEqual)list.getOperand(1)).getOperand(1));
-    }
-    
-    public void testListInASTList() throws Exception {
-        ClientMtTable1 t1 = context.newObject(ClientMtTable1.class);
-        ClientMtTable1 t2 = context.newObject(ClientMtTable1.class);
-        
-        context.commitChanges();
-        
-        List<ClientMtTable1> table1List = new ArrayList<ClientMtTable1>();
-        table1List.add(t1);
-        table1List.add(t2);
-        
-        // send list in expression factory
-        Expression list = ExpressionFactory.inExp(ClientMtTable2.TABLE1_PROPERTY, table1List);
-        
-        Object[] values = (Object[])((ASTList)list.getOperand(1)).getOperand(0);
-        assertEquals(t1.getObjectId(), values[0]);
-        assertEquals(t2.getObjectId(), values[1]);
-        
-        ObjectId t1Id = new ObjectId("MtTable1", "TABLE1_ID", 1);
-        ObjectId t2Id = new ObjectId("MtTable1", "TABLE1_ID", 2);
-        t1.setObjectId(t1Id);
-        t2.setObjectId(t2Id);
-
-        //Expression and client have different copies of object
-        assertNotSame(t1.getObjectId(), values[0]);
-        assertNotSame(t2.getObjectId(), values[1]);
-    }
-    
-    public void testArrayInASTList() throws Exception {
-        ClientMtTable1 t1 = context.newObject(ClientMtTable1.class);
-        ClientMtTable1 t2 = context.newObject(ClientMtTable1.class);
-        ClientMtTable1 t3 = context.newObject(ClientMtTable1.class);
-        
-        context.commitChanges();
-        
-        Object[] tArray = new Object[3];
-        tArray[0] = t1;
-        tArray[1] = t2;
-        
-        // send array in expression factory
-        Expression list = ExpressionFactory.inExp(ClientMtTable2.TABLE1_PROPERTY, tArray);
-        tArray[2] = t3;
-        
-        Object[] values = (Object[])((ASTList)list.getOperand(1)).getOperand(0);
-        assertEquals(tArray.length, values.length);
-        assertNotSame(tArray[2], values[2]);
-        assertEquals(t1.getObjectId(), values[0]);
-        assertEquals(t2.getObjectId(), values[1]);
-        
-        ObjectId t1Id = new ObjectId("MtTable1", "TABLE1_ID", 1);
-        ObjectId t2Id = new ObjectId("MtTable1", "TABLE1_ID", 2);
-        t1.setObjectId(t1Id);
-        t2.setObjectId(t2Id);
-        
-        // Expression and client have different arrays
-        assertNotSame(t1.getObjectId(), values[0]);
-        assertNotSame(t2.getObjectId(), values[1]);
-    }
-    
-    public void testExpressionFactoryMatch() throws Exception {
-        createDataSet();
-        
-        SelectQuery<ClientMtTable1> table1Query = new SelectQuery<ClientMtTable1>(ClientMtTable1.class);
-        table1Query.addOrdering(new Ordering("db:TABLE1_ID", SortOrder.ASCENDING));
-        List<ClientMtTable1> table1List = context.select(table1Query);
-        
-        assertNotNull(table1List);
-        
-        ClientMtTable1 element_1 = table1List.get(0);
-        ClientMtTable1 element_2 = table1List.get(1);
-        
-        Expression exp = ExpressionFactory.matchExp(ClientMtTable2.TABLE1_PROPERTY, element_1);
-        SelectQuery<ClientMtTable2> table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class, exp);
-        List<ClientMtTable2> table2List = context.select(table2Query);
-        
-        assertNotNull(table2List);
-        assertEquals(2, table2List.size());
-        
-        exp = ExpressionFactory.matchExp(element_2);
-        table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class, exp);
-        table2List = context.select(table2Query);
-
-        assertNotNull(table2List);
-        assertEquals(2, table2List.size());
-    }
-    
-    public void testExpressionFactoryMatchAll() throws Exception {
-        createDataSet();
-        
-        SelectQuery<ClientMtTable2> table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class);
-        table2Query.addOrdering(new Ordering("db:TABLE2_ID", SortOrder.ASCENDING));
-        List<ClientMtTable2> table2List = context.select(table2Query);
-        
-        ClientMtTable2 element_1 = table2List.get(0);
-        ClientMtTable2 element_2 = table2List.get(10);
-        
-        assertEquals(element_1.getTable1(), element_2.getTable1());
-        
-        Expression exp = ExpressionFactory.matchAllExp("|"+ClientMtTable1.TABLE2ARRAY_PROPERTY, Arrays.asList(element_1, element_2));
-        SelectQuery<ClientMtTable1> table1Query = new SelectQuery<ClientMtTable1>(ClientMtTable1.class, exp);
-        List<ClientMtTable1> table1List = context.select(table1Query);
-        
-        assertEquals(1, table1List.size());
-    }
-    
-    public void testExpressionFactoryMatchAny() throws Exception {
-        createDataSet();
-        
-        SelectQuery<ClientMtTable2> table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class);
-        table2Query.addOrdering(new Ordering("db:TABLE2_ID", SortOrder.ASCENDING));
-        List<ClientMtTable2> table2List = context.select(table2Query);
-        
-        ClientMtTable2 element_1 = table2List.get(0);
-        ClientMtTable2 element_2 = table2List.get(10);
-        
-        Expression exp = ExpressionFactory.matchAnyExp(element_1, element_2);
-        table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class, exp);
-        table2List = context.select(table2Query);
-        
-        assertEquals(2, table2List.size());
-    }
-    
-    public void testExpressionFactoryIn() throws Exception {
-        createDataSet();
-        
-        SelectQuery<ClientMtTable1> table1Query = new SelectQuery<ClientMtTable1>(ClientMtTable1.class);
-        table1Query.addOrdering(new Ordering("db:TABLE1_ID", SortOrder.ASCENDING));
-        List<ClientMtTable1> table1List = context.select(table1Query);
-        
-        ClientMtTable1 element_3 = table1List.get(2);
-        ClientMtTable1 element_8 = table1List.get(7);
-        
-        // IN expression via Collection
-        Expression exp = ExpressionFactory.inExp(ClientMtTable2.TABLE1_PROPERTY, table1List.subList(3, 6));
-        SelectQuery<ClientMtTable2> table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class, exp);
-        List<ClientMtTable2> table2List = context.select(table2Query);
-        
-        assertEquals(6, table2List.size());
-        
-        // IN expression via Array
-        exp = ExpressionFactory.inExp(ClientMtTable2.TABLE1_PROPERTY, element_3, element_8);
-        table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class, exp);
-        table2List = context.select(table2Query);
-        
-        assertEquals(4, table2List.size());
-    }
-    
-    public void testExpressionFactoryBetween() throws Exception {
-        createDataSet();
-        
-        SelectQuery<ClientMtTable1> table1Query = new SelectQuery<ClientMtTable1>(ClientMtTable1.class);
-        table1Query.addOrdering(new Ordering("db:TABLE1_ID", SortOrder.ASCENDING));
-        List<ClientMtTable1> table1List = context.select(table1Query);
-        
-        ClientMtTable1 element_1 = table1List.get(0);
-        ClientMtTable1 element_7 = table1List.get(6);
-        
-        // between
-        Expression exp = ExpressionFactory.betweenExp(ClientMtTable2.TABLE1_PROPERTY, element_1, element_7);
-        SelectQuery<ClientMtTable2> table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class, exp);
-        List<ClientMtTable2> table2List = context.select(table2Query);
-        
-        assertEquals(14, table2List.size());
-        
-        // not between
-        exp = ExpressionFactory.notBetweenExp(ClientMtTable2.TABLE1_PROPERTY, element_1, element_7);
-        table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class, exp);
-        table2List = context.select(table2Query);
-        
-        assertEquals(6, table2List.size());
-    }
-    
-    public void testExpressionFactoryOperators() throws Exception {
-        createDataSet();
-        
-        SelectQuery<ClientMtTable1> table1Query = new SelectQuery<ClientMtTable1>(ClientMtTable1.class);
-        table1Query.addOrdering(new Ordering("db:TABLE1_ID", SortOrder.ASCENDING));
-        List<ClientMtTable1> table1List = context.select(table1Query);
-        
-        ClientMtTable1 element_7 = table1List.get(6);
-        
-        // greater than, ">"
-        Expression exp = ExpressionFactory.greaterExp(ClientMtTable2.TABLE1_PROPERTY, element_7);
-        SelectQuery<ClientMtTable2> table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class, exp);
-        List<ClientMtTable2> table2List = context.select(table2Query);
-        
-        assertEquals(6, table2List.size());
-        
-        // greater than or equal, ">="
-        exp = ExpressionFactory.greaterOrEqualExp(ClientMtTable2.TABLE1_PROPERTY, element_7);
-        table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class, exp);
-        table2List = context.select(table2Query);
-        
-        assertEquals(8, table2List.size());
-        
-        // less than, "<"
-        exp = ExpressionFactory.lessExp(ClientMtTable2.TABLE1_PROPERTY, element_7);
-        table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class, exp);
-        table2List = context.select(table2Query);
-        
-        assertEquals(12, table2List.size());
-        
-        // less than or equal, "<="
-        exp = ExpressionFactory.lessOrEqualExp(ClientMtTable2.TABLE1_PROPERTY, element_7);
-        table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class, exp);
-        table2List = context.select(table2Query);
-        
-        assertEquals(14, table2List.size());
-    }
-    
-    public void testExpressionWithParameters() throws Exception {
-        createDataSet();
-        
-        SelectQuery<ClientMtTable1> table1Query = new SelectQuery<ClientMtTable1>(ClientMtTable1.class);
-        table1Query.addOrdering(new Ordering("db:TABLE1_ID", SortOrder.ASCENDING));
-        List<ClientMtTable1> table1List = context.select(table1Query);
-        
-        ClientMtTable1 element_1 = table1List.get(0);
-        ClientMtTable1 element_5 = table1List.get(4);
-        
-        Expression exp = Expression.fromString("table1 = $attr");
-        exp = exp.expWithParameters(Collections.singletonMap("attr", element_1));
-        SelectQuery<ClientMtTable2> table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class, exp);
-        List<ClientMtTable2> table2List = context.select(table2Query);
-        
-        assertEquals(2, table2List.size());
-        
-        exp = exp.andExp(Expression.fromString("table1 = $attr"))
-                .expWithParameters(Collections.singletonMap("attr", element_5));
-        table2Query = new SelectQuery<ClientMtTable2>(ClientMtTable2.class, exp);
-        table2List = context.select(table2Query);
-        
-        assertEquals(0, table2List.size());
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/query/ClientSelectQueryExpressionIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/query/ClientSelectQueryExpressionIT.java b/cayenne-client/src/test/java/org/apache/cayenne/query/ClientSelectQueryExpressionIT.java
new file mode 100644
index 0000000..2eabb35
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/query/ClientSelectQueryExpressionIT.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.query;
+
+import org.apache.cayenne.CayenneContext;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.ExpressionFactory;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.test.jdbc.TableHelper;
+import org.apache.cayenne.testdo.mt.ClientMtTable1;
+import org.apache.cayenne.unit.di.client.ClientCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+import java.util.List;
+
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class ClientSelectQueryExpressionIT extends ClientCase {
+
+    @Inject
+    private CayenneContext context;
+
+    @Inject
+    private DBHelper dbHelper;
+
+    private TableHelper tMtTable1;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("MT_TABLE2");
+        dbHelper.deleteAll("MT_TABLE1");
+
+        tMtTable1 = new TableHelper(dbHelper, "MT_TABLE1");
+        tMtTable1.setColumns("TABLE1_ID", "GLOBAL_ATTRIBUTE1", "SERVER_ATTRIBUTE1");
+    }
+
+    protected void createMtTable1DataSet() throws Exception {
+        for (int i = 1; i <= 20; i++) {
+            tMtTable1.insert(i, "globalAttr" + i, "serverAttr" + i);
+        }
+    }
+
+    public void testDoubleSelectLikeExpression() throws Exception {
+        createMtTable1DataSet();
+
+        List<ClientMtTable1> mtTable1List = context.select(SelectQuery.query(ClientMtTable1.class));
+
+        Expression exp = ExpressionFactory.likeExp(ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY, "globalAttr1%");
+        exp.filterObjects(mtTable1List);
+
+        List<ClientMtTable1> matchingMtTableList = context.select(SelectQuery.query(ClientMtTable1.class, exp));
+
+        assertEquals(11, matchingMtTableList.size());
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/query/ClientSelectQueryExpressionTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/query/ClientSelectQueryExpressionTest.java b/cayenne-client/src/test/java/org/apache/cayenne/query/ClientSelectQueryExpressionTest.java
deleted file mode 100644
index cdd6181..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/query/ClientSelectQueryExpressionTest.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*****************************************************************
- *   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.query;
-
-import java.util.List;
-
-import org.apache.cayenne.CayenneContext;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.exp.Expression;
-import org.apache.cayenne.exp.ExpressionFactory;
-import org.apache.cayenne.test.jdbc.DBHelper;
-import org.apache.cayenne.test.jdbc.TableHelper;
-import org.apache.cayenne.testdo.mt.ClientMtTable1;
-import org.apache.cayenne.unit.di.client.ClientCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class ClientSelectQueryExpressionTest extends ClientCase {
-
-    @Inject
-    private CayenneContext context;
-
-    @Inject
-    private DBHelper dbHelper;
-
-    private TableHelper tMtTable1;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("MT_TABLE2");
-        dbHelper.deleteAll("MT_TABLE1");
-
-        tMtTable1 = new TableHelper(dbHelper, "MT_TABLE1");
-        tMtTable1.setColumns("TABLE1_ID", "GLOBAL_ATTRIBUTE1", "SERVER_ATTRIBUTE1");
-    }
-
-    protected void createMtTable1DataSet() throws Exception {
-        for (int i = 1; i <= 20; i++) {
-            tMtTable1.insert(i, "globalAttr" + i, "serverAttr" + i);
-        }
-    }
-
-    public void testDoubleSelectLikeExpression() throws Exception {
-        createMtTable1DataSet();
-
-        List<ClientMtTable1> mtTable1List = context.select(SelectQuery.query(ClientMtTable1.class));
-
-        Expression exp = ExpressionFactory.likeExp(ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY, "globalAttr1%");
-        exp.filterObjects(mtTable1List);
-
-        List<ClientMtTable1> matchingMtTableList = context.select(SelectQuery.query(ClientMtTable1.class, exp));
-
-        assertEquals(11, matchingMtTableList.size());
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/remote/CayenneContextDeletionIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/remote/CayenneContextDeletionIT.java b/cayenne-client/src/test/java/org/apache/cayenne/remote/CayenneContextDeletionIT.java
new file mode 100644
index 0000000..08df05f
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/remote/CayenneContextDeletionIT.java
@@ -0,0 +1,38 @@
+/*****************************************************************
+ *   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.remote;
+
+import org.apache.cayenne.testdo.mt.ClientMtTable1;
+import org.apache.cayenne.unit.di.client.ClientCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class CayenneContextDeletionIT extends RemoteCayenneCase {
+
+    public void testDeletion() {
+        ClientMtTable1 object = clientContext.newObject(ClientMtTable1.class);
+        clientContext.commitChanges();
+
+        clientContext.deleteObjects(object);
+
+        // now check that the object is unregistered
+        clientContext.commitChanges();
+        assertNull(clientContext.getGraphManager().getNode(object.getObjectId()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/remote/CayenneContextDeletionTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/remote/CayenneContextDeletionTest.java b/cayenne-client/src/test/java/org/apache/cayenne/remote/CayenneContextDeletionTest.java
deleted file mode 100644
index 4a82a75..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/remote/CayenneContextDeletionTest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*****************************************************************
- *   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.remote;
-
-import org.apache.cayenne.testdo.mt.ClientMtTable1;
-import org.apache.cayenne.unit.di.client.ClientCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class CayenneContextDeletionTest extends RemoteCayenneCase {
-
-    public void testDeletion() {
-        ClientMtTable1 object = clientContext.newObject(ClientMtTable1.class);
-        clientContext.commitChanges();
-
-        clientContext.deleteObjects(object);
-
-        // now check that the object is unregistered
-        clientContext.commitChanges();
-        assertNull(clientContext.getGraphManager().getNode(object.getObjectId()));
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/remote/ClientChannelServerDiffsIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/remote/ClientChannelServerDiffsIT.java b/cayenne-client/src/test/java/org/apache/cayenne/remote/ClientChannelServerDiffsIT.java
new file mode 100644
index 0000000..d3e9e52
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/remote/ClientChannelServerDiffsIT.java
@@ -0,0 +1,263 @@
+/*****************************************************************
+ *   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.remote;
+
+import org.apache.cayenne.CayenneContext;
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.ObjectId;
+import org.apache.cayenne.access.ClientServerChannel;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.event.MockEventManager;
+import org.apache.cayenne.graph.GraphChangeHandler;
+import org.apache.cayenne.graph.GraphDiff;
+import org.apache.cayenne.map.LifecycleEvent;
+import org.apache.cayenne.reflect.LifecycleCallbackRegistry;
+import org.apache.cayenne.testdo.mt.ClientMtTable1;
+import org.apache.cayenne.testdo.mt.ClientMtTable2;
+import org.apache.cayenne.testdo.mt.MtTable1;
+import org.apache.cayenne.unit.di.client.ClientCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class ClientChannelServerDiffsIT extends ClientCase {
+
+    @Inject
+    private ClientServerChannel clientServerChannel;
+
+    @Inject
+    private ClientConnection connection;
+
+    public void testReturnIdDiff() {
+
+        final Object[] ids = new Object[2];
+
+        final GraphChangeHandler diffReader = new NoopGraphChangeHandler() {
+
+            @Override
+            public void nodeIdChanged(Object oldId, Object newId) {
+                ids[0] = oldId;
+                ids[1] = newId;
+            }
+        };
+
+        ClientChannel channel = new ClientChannel(
+                connection,
+                false,
+                new MockEventManager(),
+                false) {
+
+            @Override
+            public GraphDiff onSync(
+                    ObjectContext originatingContext,
+                    GraphDiff changes,
+                    int syncType) {
+
+                GraphDiff serverDiff = super
+                        .onSync(originatingContext, changes, syncType);
+
+                assertNotNull(serverDiff);
+                serverDiff.apply(diffReader);
+                return serverDiff;
+            }
+        };
+
+        CayenneContext context = new CayenneContext(channel);
+        context.newObject(ClientMtTable1.class);
+        context.commitChanges();
+
+        assertTrue(ids[0] instanceof ObjectId);
+        assertTrue(((ObjectId) ids[0]).isTemporary());
+
+        assertTrue(ids[1] instanceof ObjectId);
+        assertFalse(((ObjectId) ids[1]).isTemporary());
+    }
+
+    public void testReturnDiffInPrePersist() {
+
+        final List<GenericDiff> diffs = new ArrayList<GenericDiff>();
+        final NoopGraphChangeHandler diffReader = new NoopGraphChangeHandler() {
+
+            @Override
+            public void nodePropertyChanged(
+                    Object nodeId,
+                    String property,
+                    Object oldValue,
+                    Object newValue) {
+
+                super.nodePropertyChanged(nodeId, property, oldValue, newValue);
+                diffs
+                        .add(new GenericDiff(
+                                (ObjectId) nodeId,
+                                property,
+                                oldValue,
+                                newValue));
+            }
+
+        };
+
+        LifecycleCallbackRegistry callbackRegistry = clientServerChannel
+                .getEntityResolver()
+                .getCallbackRegistry();
+
+        try {
+
+            callbackRegistry.addListener(
+                    LifecycleEvent.POST_ADD,
+                    MtTable1.class,
+                    new ClientChannelServerDiffsListener1(),
+                    "prePersist");
+
+            ClientChannel channel = new ClientChannel(
+                    connection,
+                    false,
+                    new MockEventManager(),
+                    false) {
+
+                @Override
+                public GraphDiff onSync(
+                        ObjectContext originatingContext,
+                        GraphDiff changes,
+                        int syncType) {
+
+                    GraphDiff serverDiff = super.onSync(
+                            originatingContext,
+                            changes,
+                            syncType);
+
+                    assertNotNull(serverDiff);
+                    serverDiff.apply(diffReader);
+                    return serverDiff;
+                }
+            };
+
+            CayenneContext context = new CayenneContext(channel);
+            ClientMtTable1 o = context.newObject(ClientMtTable1.class);
+            ObjectId tempId = o.getObjectId();
+            o.setServerAttribute1("YY");
+            context.commitChanges();
+
+            assertEquals(2, diffReader.size);
+            assertEquals(1, diffs.size());
+            assertEquals(tempId, diffs.get(0).sourceId);
+            assertEquals(ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY, diffs.get(0).property);
+            assertNull(diffs.get(0).oldValue);
+            assertEquals("XXX", diffs.get(0).newValue);
+        }
+        finally {
+            callbackRegistry.clear();
+        }
+    }
+
+    public void testReturnDiffClientArcChanges() {
+
+        final NoopGraphChangeHandler diffReader = new NoopGraphChangeHandler();
+
+        ClientChannel channel = new ClientChannel(
+                connection,
+                false,
+                new MockEventManager(),
+                false) {
+
+            @Override
+            public GraphDiff onSync(
+                    ObjectContext originatingContext,
+                    GraphDiff changes,
+                    int syncType) {
+
+                GraphDiff serverDiff = super
+                        .onSync(originatingContext, changes, syncType);
+
+                assertNotNull(serverDiff);
+                serverDiff.apply(diffReader);
+                return serverDiff;
+            }
+        };
+
+        CayenneContext context = new CayenneContext(channel);
+        ClientMtTable1 o = context.newObject(ClientMtTable1.class);
+        ClientMtTable2 o2 = context.newObject(ClientMtTable2.class);
+        o.addToTable2Array(o2);
+        context.commitChanges();
+
+        assertEquals(2, diffReader.size);
+
+        diffReader.reset();
+
+        ClientMtTable2 o3 = context.newObject(ClientMtTable2.class);
+        o3.setTable1(o);
+        context.commitChanges();
+        assertEquals(1, diffReader.size);
+    }
+
+    class NoopGraphChangeHandler implements GraphChangeHandler {
+
+        int size;
+
+        void reset() {
+            size = 0;
+        }
+
+        public void nodePropertyChanged(
+                Object nodeId,
+                String property,
+                Object oldValue,
+                Object newValue) {
+
+            size++;
+        }
+
+        public void arcCreated(Object nodeId, Object targetNodeId, Object arcId) {
+            size++;
+        }
+
+        public void arcDeleted(Object nodeId, Object targetNodeId, Object arcId) {
+            size++;
+        }
+
+        public void nodeCreated(Object nodeId) {
+            size++;
+        }
+
+        public void nodeIdChanged(Object nodeId, Object newId) {
+            size++;
+        }
+
+        public void nodeRemoved(Object nodeId) {
+            size++;
+        }
+    }
+
+    class GenericDiff {
+
+        private String property;
+        private Object oldValue;
+        private Object newValue;
+        private ObjectId sourceId;
+
+        GenericDiff(ObjectId sourceId, String property, Object oldValue, Object newValue) {
+            this.sourceId = sourceId;
+            this.property = property;
+            this.oldValue = oldValue;
+            this.newValue = newValue;
+        }
+    }
+}


Mime
View raw message