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 2014/11/02 08:38:57 UTC

[1/8] Rename Integration Tests in cayenne-client (*IT.java instead of *Test.java)

Repository: cayenne
Updated Branches:
  refs/heads/master 5fdb08035 -> dd009c6d9


http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/remote/RemoteIncrementalFaultListTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/remote/RemoteIncrementalFaultListTest.java b/cayenne-client/src/test/java/org/apache/cayenne/remote/RemoteIncrementalFaultListTest.java
deleted file mode 100644
index 2351f9c..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/remote/RemoteIncrementalFaultListTest.java
+++ /dev/null
@@ -1,266 +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 java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-
-import org.apache.cayenne.CayenneContext;
-import org.apache.cayenne.Persistent;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.exp.Expression;
-import org.apache.cayenne.exp.ExpressionFactory;
-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.MtTable1;
-import org.apache.cayenne.unit.di.client.ClientCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class RemoteIncrementalFaultListTest extends ClientCase {
-
-    private static final int COUNT = 25;
-
-    @Inject
-    private CayenneContext clientContext;
-
-    @Inject
-    private DBHelper dbHelper;
-
-    private TableHelper tMTTable;
-
-    private RemoteIncrementalFaultList list;
-    private SelectQuery query;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("MT_TABLE2");
-        dbHelper.deleteAll("MT_TABLE1");
-
-        tMTTable = new TableHelper(dbHelper, "MT_TABLE1");
-        tMTTable.setColumns("TABLE1_ID", "GLOBAL_ATTRIBUTE1", "SERVER_ATTRIBUTE1");
-    }
-
-    protected void createObjectsDataSet() throws Exception {
-        tMTTable.insert(1, "g1", "s1");
-        tMTTable.insert(2, "g2", "s2");
-        tMTTable.insert(3, "g3", "s3");
-        tMTTable.insert(4, "g4", "s4");
-        tMTTable.insert(5, "g5", "s5");
-        tMTTable.insert(6, "g6", "s6");
-        tMTTable.insert(7, "g7", "s7");
-        tMTTable.insert(8, "g8", "s8");
-        tMTTable.insert(9, "g9", "s9");
-        tMTTable.insert(10, "g10", "s10");
-        tMTTable.insert(11, "g11", "s11");
-        tMTTable.insert(12, "g12", "s12");
-        tMTTable.insert(13, "g13", "s13");
-        tMTTable.insert(14, "g14", "s14");
-        tMTTable.insert(15, "g15", "s15");
-        tMTTable.insert(16, "g16", "s16");
-        tMTTable.insert(17, "g17", "s17");
-        tMTTable.insert(18, "g18", "s18");
-        tMTTable.insert(19, "g19", "s19");
-        tMTTable.insert(20, "g20", "s20");
-        tMTTable.insert(21, "g21", "s21");
-        tMTTable.insert(22, "g22", "s22");
-        tMTTable.insert(23, "g23", "s23");
-        tMTTable.insert(24, "g24", "s24");
-        tMTTable.insert(25, "g25", "s25");
-    }
-
-    private void prepareList(int pageSize) throws Exception {
-
-        createObjectsDataSet();
-
-        query = new SelectQuery(ClientMtTable1.class);
-
-        // make sure total number of objects is not divisable
-        // by the page size, to test the last smaller page
-        query.setPageSize(pageSize);
-        query.addOrdering("db:" + MtTable1.TABLE1_ID_PK_COLUMN, SortOrder.ASCENDING);
-
-        list = new RemoteIncrementalFaultList(clientContext, query);
-    }
-
-    public void testSize() throws Exception {
-        prepareList(6);
-        assertEquals(COUNT, list.size());
-    }
-
-    public void testIteratorPageSize1() throws Exception {
-        doTestIterator(1);
-    }
-
-    public void testIteratorPageSize5() throws Exception {
-        // size divisiable by page size
-        doTestIterator(5);
-    }
-
-    public void testIteratorPageSize6() throws Exception {
-        // size not divisable by page size
-        doTestIterator(6);
-    }
-
-    public void testIteratorPageSize25() throws Exception {
-        // size equals to page size
-        doTestIterator(COUNT);
-    }
-
-    public void testIteratorPageSize26() throws Exception {
-        // size exceeding page size
-        doTestIterator(COUNT + 1);
-    }
-
-    public void testListIterator() throws Exception {
-        prepareList(6);
-        ListIterator<?> it = list.listIterator();
-
-        assertTrue(it.hasNext());
-
-        int counter = 0;
-        while (it.hasNext()) {
-            Object obj = it.next();
-            assertNotNull(obj);
-            assertTrue(obj instanceof Persistent);
-
-            // iterator must be resolved page by page
-            int expectedResolved = list.pageIndex(counter)
-                    * list.getPageSize()
-                    + list.getPageSize();
-            if (expectedResolved > list.size()) {
-                expectedResolved = list.size();
-            }
-
-            assertEquals(list.size() - expectedResolved, list.getUnfetchedObjects());
-
-            counter++;
-        }
-    }
-
-    public void testUnfetchedObjects() throws Exception {
-        prepareList(6);
-        assertEquals(COUNT - 6, list.getUnfetchedObjects());
-        list.get(7);
-        assertEquals(COUNT - 12, list.getUnfetchedObjects());
-        list.resolveAll();
-        assertEquals(0, list.getUnfetchedObjects());
-    }
-
-    public void testPageIndex() throws Exception {
-        prepareList(6);
-        assertEquals(0, list.pageIndex(0));
-        assertEquals(0, list.pageIndex(1));
-        assertEquals(1, list.pageIndex(6));
-
-        try {
-            assertEquals(13, list.pageIndex(82));
-            fail("Element index beyound array size must throw an IndexOutOfBoundsException.");
-        }
-        catch (IndexOutOfBoundsException ex) {
-            // exception expercted
-        }
-    }
-
-    public void testPagesRead1() throws Exception {
-        prepareList(6);
-        assertTrue(list.elements.get(0) instanceof ClientMtTable1);
-        assertSame(RemoteIncrementalFaultList.PLACEHOLDER, list.elements.get(8));
-
-        list.resolveInterval(5, 10);
-        assertTrue(list.elements.get(7) instanceof ClientMtTable1);
-
-        list.resolveAll();
-        assertTrue((list.elements.get(list.size() - 1)) instanceof ClientMtTable1);
-    }
-
-    public void testGet1() throws Exception {
-        prepareList(6);
-        assertTrue(list.elements.get(0) instanceof ClientMtTable1);
-        assertSame(RemoteIncrementalFaultList.PLACEHOLDER, list.elements.get(8));
-
-        Object a = list.get(8);
-
-        assertNotNull(a);
-        assertTrue(a instanceof ClientMtTable1);
-        assertTrue(list.elements.get(8) instanceof ClientMtTable1);
-    }
-
-    public void testIndexOf() throws Exception {
-        prepareList(6);
-
-        Expression qual = ExpressionFactory.matchExp(
-                ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY,
-                "g20");
-        SelectQuery query = new SelectQuery(ClientMtTable1.class, qual);
-        List<?> artists = list.context.performQuery(query);
-
-        assertEquals(1, artists.size());
-
-        ClientMtTable1 row = (ClientMtTable1) artists.get(0);
-        assertEquals(19, list.indexOf(row));
-        assertEquals(-1, list.indexOf(list.context.newObject(ClientMtTable1.class)));
-    }
-
-    public void testLastIndexOf() throws Exception {
-        prepareList(6);
-        Expression qual = ExpressionFactory.matchExp(
-                ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY,
-                "g20");
-        SelectQuery query = new SelectQuery(ClientMtTable1.class, qual);
-        List<?> objects = list.context.performQuery(query);
-
-        assertEquals(1, objects.size());
-
-        ClientMtTable1 row = (ClientMtTable1) objects.get(0);
-        assertEquals(19, list.lastIndexOf(row));
-        assertEquals(-1, list.lastIndexOf(list.context.newObject(ClientMtTable1.class)));
-    }
-
-    private void doTestIterator(int size) throws Exception {
-        prepareList(size);
-        Iterator<?> it = list.iterator();
-
-        assertTrue(it.hasNext());
-
-        int counter = 0;
-        while (it.hasNext()) {
-            Object obj = it.next();
-            assertNotNull(obj);
-            assertTrue(obj instanceof Persistent);
-
-            // iterator must be resolved page by page
-            int expectedResolved = list.pageIndex(counter)
-                    * list.getPageSize()
-                    + list.getPageSize();
-            if (expectedResolved > list.size()) {
-                expectedResolved = list.size();
-            }
-
-            assertEquals(list.size() - expectedResolved, list.getUnfetchedObjects());
-
-            counter++;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/remote/RemoteRollbackIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/remote/RemoteRollbackIT.java b/cayenne-client/src/test/java/org/apache/cayenne/remote/RemoteRollbackIT.java
new file mode 100644
index 0000000..ceeadcd
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/remote/RemoteRollbackIT.java
@@ -0,0 +1,147 @@
+/*****************************************************************
+ *   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.PersistenceState;
+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;
+
+/**
+ * This is a test primarily for CAY-1103
+ */
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class RemoteRollbackIT extends RemoteCayenneCase {
+    
+    public void testRollbackNew() {
+        ClientMtTable1 o1 = clientContext.newObject(ClientMtTable1.class);
+        o1.setGlobalAttribute1("a");
+
+        ClientMtTable2 p1 = clientContext.newObject(ClientMtTable2.class);
+        p1.setGlobalAttribute("p1");
+        p1.setTable1(o1);
+
+        ClientMtTable2 p2 = clientContext.newObject(ClientMtTable2.class);
+        p2.setGlobalAttribute("p2");
+        p2.setTable1(o1);
+
+        ClientMtTable2 p3 = clientContext.newObject(ClientMtTable2.class);
+        p3.setGlobalAttribute("p3");
+        p3.setTable1(o1);
+
+        // before:
+        assertEquals(o1, p1.getTable1());
+        assertEquals(3, o1.getTable2Array().size());
+
+        clientContext.rollbackChanges();
+
+        // after:
+        assertEquals(PersistenceState.TRANSIENT, o1.getPersistenceState());
+
+        // TODO: should we expect relationships to be unset?
+        // assertNull(p1.getToClientMtTable1());
+        // assertEquals(0, o1.getClientMtTable2Array().size());
+    }
+
+    public void testRollbackNewObject() {
+        String o1Name = "revertTestClientMtTable1";
+        ClientMtTable1 o1 = clientContext.newObject(ClientMtTable1.class);
+        o1.setGlobalAttribute1(o1Name);
+
+        clientContext.rollbackChanges();
+
+        assertEquals(PersistenceState.TRANSIENT, o1.getPersistenceState());
+        clientContext.commitChanges();
+    }
+
+    // Catches a bug where new objects were unregistered within an object iterator, thus
+    // modifying the
+    // collection the iterator was iterating over (ConcurrentModificationException)
+    public void testRollbackWithMultipleNewObjects() {
+        String o1Name = "rollbackTestClientMtTable1";
+        String o2Title = "rollbackTestClientMtTable2";
+        ClientMtTable1 o1 = clientContext.newObject(ClientMtTable1.class);
+        o1.setGlobalAttribute1(o1Name);
+
+        ClientMtTable2 o2 = clientContext.newObject(ClientMtTable2.class);
+        o2.setGlobalAttribute(o2Title);
+        o2.setTable1(o1);
+
+        try {
+            clientContext.rollbackChanges();
+        }
+        catch (Exception e) {
+            e.printStackTrace();
+            fail("rollbackChanges should not have caused the exception " + e.getMessage());
+        }
+
+        assertEquals(PersistenceState.TRANSIENT, o1.getPersistenceState());
+    }
+
+    public void testRollbackRelationshipModification() {
+        String o1Name = "relationshipModClientMtTable1";
+        String o2Title = "relationshipTestClientMtTable2";
+        ClientMtTable1 o1 = clientContext.newObject(ClientMtTable1.class);
+        o1.setGlobalAttribute1(o1Name);
+        ClientMtTable2 o2 = clientContext.newObject(ClientMtTable2.class);
+        o2.setGlobalAttribute(o2Title);
+        o2.setTable1(o1);
+        
+        assertEquals(1, o1.getTable2Array().size());
+        clientContext.commitChanges();
+
+        assertEquals(1, o1.getTable2Array().size());
+        o2.setTable1(null);
+        assertEquals(0, o1.getTable2Array().size());
+        clientContext.rollbackChanges();
+
+        assertEquals(1, o1.getTable2Array().size());
+        assertEquals(o1, o2.getTable1());
+    }
+
+    public void testRollbackDeletedObject() {
+        String o1Name = "deleteTestClientMtTable1";
+        ClientMtTable1 o1 = clientContext.newObject(ClientMtTable1.class);
+        o1.setGlobalAttribute1(o1Name);
+        clientContext.commitChanges();
+        // Save... cayenne doesn't yet handle deleting objects that are uncommitted
+        clientContext.deleteObjects(o1);
+        clientContext.rollbackChanges();
+
+        //TODO: The state is committed for Cayenne context, but Hollow for DataContext?!
+        // Now check everything is as it should be
+        assertEquals(PersistenceState.COMMITTED, o1.getPersistenceState());
+    }
+
+    public void testRollbackModifiedObject() {
+        String o1Name = "initialTestClientMtTable1";
+        ClientMtTable1 o1 = clientContext.newObject(ClientMtTable1.class);
+        o1.setGlobalAttribute1(o1Name);
+        clientContext.commitChanges();
+
+        o1.setGlobalAttribute1("a new value");
+
+        clientContext.rollbackChanges();
+
+        // Make sure the inmemory changes have been rolled back
+        assertEquals(PersistenceState.COMMITTED, o1.getPersistenceState());
+        assertEquals(o1Name, o1.getGlobalAttribute1());
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/remote/RemoteRollbackTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/remote/RemoteRollbackTest.java b/cayenne-client/src/test/java/org/apache/cayenne/remote/RemoteRollbackTest.java
deleted file mode 100644
index 7bb4ba8..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/remote/RemoteRollbackTest.java
+++ /dev/null
@@ -1,147 +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.PersistenceState;
-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;
-
-/**
- * This is a test primarily for CAY-1103
- */
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class RemoteRollbackTest extends RemoteCayenneCase {
-    
-    public void testRollbackNew() {
-        ClientMtTable1 o1 = clientContext.newObject(ClientMtTable1.class);
-        o1.setGlobalAttribute1("a");
-
-        ClientMtTable2 p1 = clientContext.newObject(ClientMtTable2.class);
-        p1.setGlobalAttribute("p1");
-        p1.setTable1(o1);
-
-        ClientMtTable2 p2 = clientContext.newObject(ClientMtTable2.class);
-        p2.setGlobalAttribute("p2");
-        p2.setTable1(o1);
-
-        ClientMtTable2 p3 = clientContext.newObject(ClientMtTable2.class);
-        p3.setGlobalAttribute("p3");
-        p3.setTable1(o1);
-
-        // before:
-        assertEquals(o1, p1.getTable1());
-        assertEquals(3, o1.getTable2Array().size());
-
-        clientContext.rollbackChanges();
-
-        // after:
-        assertEquals(PersistenceState.TRANSIENT, o1.getPersistenceState());
-
-        // TODO: should we expect relationships to be unset?
-        // assertNull(p1.getToClientMtTable1());
-        // assertEquals(0, o1.getClientMtTable2Array().size());
-    }
-
-    public void testRollbackNewObject() {
-        String o1Name = "revertTestClientMtTable1";
-        ClientMtTable1 o1 = clientContext.newObject(ClientMtTable1.class);
-        o1.setGlobalAttribute1(o1Name);
-
-        clientContext.rollbackChanges();
-
-        assertEquals(PersistenceState.TRANSIENT, o1.getPersistenceState());
-        clientContext.commitChanges();
-    }
-
-    // Catches a bug where new objects were unregistered within an object iterator, thus
-    // modifying the
-    // collection the iterator was iterating over (ConcurrentModificationException)
-    public void testRollbackWithMultipleNewObjects() {
-        String o1Name = "rollbackTestClientMtTable1";
-        String o2Title = "rollbackTestClientMtTable2";
-        ClientMtTable1 o1 = clientContext.newObject(ClientMtTable1.class);
-        o1.setGlobalAttribute1(o1Name);
-
-        ClientMtTable2 o2 = clientContext.newObject(ClientMtTable2.class);
-        o2.setGlobalAttribute(o2Title);
-        o2.setTable1(o1);
-
-        try {
-            clientContext.rollbackChanges();
-        }
-        catch (Exception e) {
-            e.printStackTrace();
-            fail("rollbackChanges should not have caused the exception " + e.getMessage());
-        }
-
-        assertEquals(PersistenceState.TRANSIENT, o1.getPersistenceState());
-    }
-
-    public void testRollbackRelationshipModification() {
-        String o1Name = "relationshipModClientMtTable1";
-        String o2Title = "relationshipTestClientMtTable2";
-        ClientMtTable1 o1 = clientContext.newObject(ClientMtTable1.class);
-        o1.setGlobalAttribute1(o1Name);
-        ClientMtTable2 o2 = clientContext.newObject(ClientMtTable2.class);
-        o2.setGlobalAttribute(o2Title);
-        o2.setTable1(o1);
-        
-        assertEquals(1, o1.getTable2Array().size());
-        clientContext.commitChanges();
-
-        assertEquals(1, o1.getTable2Array().size());
-        o2.setTable1(null);
-        assertEquals(0, o1.getTable2Array().size());
-        clientContext.rollbackChanges();
-
-        assertEquals(1, o1.getTable2Array().size());
-        assertEquals(o1, o2.getTable1());
-    }
-
-    public void testRollbackDeletedObject() {
-        String o1Name = "deleteTestClientMtTable1";
-        ClientMtTable1 o1 = clientContext.newObject(ClientMtTable1.class);
-        o1.setGlobalAttribute1(o1Name);
-        clientContext.commitChanges();
-        // Save... cayenne doesn't yet handle deleting objects that are uncommitted
-        clientContext.deleteObjects(o1);
-        clientContext.rollbackChanges();
-
-        //TODO: The state is committed for Cayenne context, but Hollow for DataContext?!
-        // Now check everything is as it should be
-        assertEquals(PersistenceState.COMMITTED, o1.getPersistenceState());
-    }
-
-    public void testRollbackModifiedObject() {
-        String o1Name = "initialTestClientMtTable1";
-        ClientMtTable1 o1 = clientContext.newObject(ClientMtTable1.class);
-        o1.setGlobalAttribute1(o1Name);
-        clientContext.commitChanges();
-
-        o1.setGlobalAttribute1("a new value");
-
-        clientContext.rollbackChanges();
-
-        // Make sure the inmemory changes have been rolled back
-        assertEquals(PersistenceState.COMMITTED, o1.getPersistenceState());
-        assertEquals(o1Name, o1.getGlobalAttribute1());
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/remote/ValueInjectorIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/remote/ValueInjectorIT.java b/cayenne-client/src/test/java/org/apache/cayenne/remote/ValueInjectorIT.java
new file mode 100644
index 0000000..de09b70
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/remote/ValueInjectorIT.java
@@ -0,0 +1,73 @@
+/*****************************************************************
+ *   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.ObjectContext;
+import org.apache.cayenne.access.DataContext;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.testdo.mt.ClientMtTable1Subclass1;
+import org.apache.cayenne.testdo.mt.MtTable1Subclass1;
+import org.apache.cayenne.unit.di.client.ClientCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class ValueInjectorIT extends RemoteCayenneCase {
+
+    @Inject
+    protected DataContext serverContext;
+
+    public void testServer() {
+        ObjEntity entity = serverContext.getEntityResolver().getObjEntity(MtTable1Subclass1.class);
+        Expression qualifier = entity.getDeclaredQualifier();
+
+        try {
+            MtTable1Subclass1 ee = serverContext.newObject(MtTable1Subclass1.class);
+            assertEquals(ee.getGlobalAttribute1(), "sub1");
+
+            // check AND
+            entity.setDeclaredQualifier(qualifier.andExp(Expression.fromString("serverAttribute1 = 'sa'")));
+            ee = serverContext.newObject(MtTable1Subclass1.class);
+            assertEquals(ee.getGlobalAttribute1(), "sub1");
+            assertEquals(ee.getServerAttribute1(), "sa");
+        } finally {
+            entity.setDeclaredQualifier(qualifier);
+        }
+    }
+
+    public void testClient() {
+        ObjectContext context = createROPContext();
+        ObjEntity entity = context.getEntityResolver().getObjEntity(ClientMtTable1Subclass1.class);
+        Expression qualifier = entity.getDeclaredQualifier();
+
+        try {
+            ClientMtTable1Subclass1 ee = context.newObject(ClientMtTable1Subclass1.class);
+            assertEquals(ee.getGlobalAttribute1(), "sub1");
+
+            // check AND
+            entity.setDeclaredQualifier(qualifier.andExp(Expression.fromString("serverAttribute1 = 'sa'")));
+            ee = context.newObject(ClientMtTable1Subclass1.class);
+            assertEquals(ee.getGlobalAttribute1(), "sub1");
+            assertEquals(ee.getServerAttribute1(), "sa");
+        } finally {
+            entity.setDeclaredQualifier(qualifier);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/remote/ValueInjectorTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/remote/ValueInjectorTest.java b/cayenne-client/src/test/java/org/apache/cayenne/remote/ValueInjectorTest.java
deleted file mode 100644
index 0f08768..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/remote/ValueInjectorTest.java
+++ /dev/null
@@ -1,73 +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.ObjectContext;
-import org.apache.cayenne.access.DataContext;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.exp.Expression;
-import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.testdo.mt.ClientMtTable1Subclass1;
-import org.apache.cayenne.testdo.mt.MtTable1Subclass1;
-import org.apache.cayenne.unit.di.client.ClientCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class ValueInjectorTest extends RemoteCayenneCase {
-
-    @Inject
-    protected DataContext serverContext;
-
-    public void testServer() {
-        ObjEntity entity = serverContext.getEntityResolver().getObjEntity(MtTable1Subclass1.class);
-        Expression qualifier = entity.getDeclaredQualifier();
-
-        try {
-            MtTable1Subclass1 ee = serverContext.newObject(MtTable1Subclass1.class);
-            assertEquals(ee.getGlobalAttribute1(), "sub1");
-
-            // check AND
-            entity.setDeclaredQualifier(qualifier.andExp(Expression.fromString("serverAttribute1 = 'sa'")));
-            ee = serverContext.newObject(MtTable1Subclass1.class);
-            assertEquals(ee.getGlobalAttribute1(), "sub1");
-            assertEquals(ee.getServerAttribute1(), "sa");
-        } finally {
-            entity.setDeclaredQualifier(qualifier);
-        }
-    }
-
-    public void testClient() {
-        ObjectContext context = createROPContext();
-        ObjEntity entity = context.getEntityResolver().getObjEntity(ClientMtTable1Subclass1.class);
-        Expression qualifier = entity.getDeclaredQualifier();
-
-        try {
-            ClientMtTable1Subclass1 ee = context.newObject(ClientMtTable1Subclass1.class);
-            assertEquals(ee.getGlobalAttribute1(), "sub1");
-
-            // check AND
-            entity.setDeclaredQualifier(qualifier.andExp(Expression.fromString("serverAttribute1 = 'sa'")));
-            ee = context.newObject(ClientMtTable1Subclass1.class);
-            assertEquals(ee.getGlobalAttribute1(), "sub1");
-            assertEquals(ee.getServerAttribute1(), "sa");
-        } finally {
-            entity.setDeclaredQualifier(qualifier);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/unit/di/client/ClientCaseSelfIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/unit/di/client/ClientCaseSelfIT.java b/cayenne-client/src/test/java/org/apache/cayenne/unit/di/client/ClientCaseSelfIT.java
new file mode 100644
index 0000000..1db7f61
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/unit/di/client/ClientCaseSelfIT.java
@@ -0,0 +1,46 @@
+/*****************************************************************
+ *   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.unit.di.client;
+
+import org.apache.cayenne.configuration.server.ServerRuntime;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.di.Provider;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class ClientCaseSelfIT extends ClientCase {
+
+    @Inject
+    protected ServerRuntime runtime;
+
+    @Inject
+    protected Provider<ServerRuntime> runtimeProvider;
+
+    public void testServerSetup_TearDown_Runtime() throws Exception {
+
+        ServerRuntime local = this.runtime;
+        assertNotNull(local);
+        assertSame(local, runtimeProvider.get());
+
+        tearDown();
+
+        setUp();
+        assertNotSame(local, this.runtime);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/unit/di/client/ClientCaseSelfTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/unit/di/client/ClientCaseSelfTest.java b/cayenne-client/src/test/java/org/apache/cayenne/unit/di/client/ClientCaseSelfTest.java
deleted file mode 100644
index 36fc9c8..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/unit/di/client/ClientCaseSelfTest.java
+++ /dev/null
@@ -1,46 +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.unit.di.client;
-
-import org.apache.cayenne.configuration.server.ServerRuntime;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.di.Provider;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class ClientCaseSelfTest extends ClientCase {
-
-    @Inject
-    protected ServerRuntime runtime;
-
-    @Inject
-    protected Provider<ServerRuntime> runtimeProvider;
-
-    public void testServerSetup_TearDown_Runtime() throws Exception {
-
-        ServerRuntime local = this.runtime;
-        assertNotNull(local);
-        assertSame(local, runtimeProvider.get());
-
-        tearDown();
-
-        setUp();
-        assertNotSame(local, this.runtime);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/util/ObjectDetachOperationIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/util/ObjectDetachOperationIT.java b/cayenne-client/src/test/java/org/apache/cayenne/util/ObjectDetachOperationIT.java
new file mode 100644
index 0000000..813e64b
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/util/ObjectDetachOperationIT.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.util;
+
+import org.apache.cayenne.ObjectId;
+import org.apache.cayenne.PersistenceState;
+import org.apache.cayenne.access.DataContext;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.map.EntityResolver;
+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.MtTable1;
+import org.apache.cayenne.unit.di.client.ClientCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class ObjectDetachOperationIT extends ClientCase {
+
+    @Inject
+    private DataContext serverContext;
+
+    @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");
+    }
+
+    public void testDetachCommitted() {
+
+        EntityResolver serverResover = serverContext.getEntityResolver();
+        EntityResolver clientResolver = serverResover.getClientEntityResolver();
+        ObjectDetachOperation op = new ObjectDetachOperation(clientResolver);
+
+        ObjectId oid = new ObjectId("MtTable1", MtTable1.TABLE1_ID_PK_COLUMN, 456);
+        MtTable1 so = new MtTable1();
+        so.setObjectId(oid);
+        so.setGlobalAttribute1("gx");
+        so.setPersistenceState(PersistenceState.COMMITTED);
+        so.setObjectContext(serverContext);
+        serverContext.getGraphManager().registerNode(oid, so);
+
+        Object detached = op.detach(
+                so,
+                serverResover.getClassDescriptor("MtTable1"),
+                null);
+        assertNotNull(detached);
+        assertNotSame(so, detached);
+        assertTrue(detached instanceof ClientMtTable1);
+
+        ClientMtTable1 co = (ClientMtTable1) detached;
+        assertEquals(oid, co.getObjectId());
+        assertEquals("gx", co.getGlobalAttribute1());
+        assertEquals(PersistenceState.TRANSIENT, co.getPersistenceState());
+        assertNull(co.getObjectContext());
+    }
+
+    public void testDetachHollow() throws Exception {
+
+        tMtTable1.insert(4, "g1", "s1");
+
+        EntityResolver serverResover = serverContext.getEntityResolver();
+        EntityResolver clientResolver = serverResover.getClientEntityResolver();
+        ObjectDetachOperation op = new ObjectDetachOperation(clientResolver);
+
+        ObjectId oid = new ObjectId("MtTable1", MtTable1.TABLE1_ID_PK_COLUMN, 4);
+        MtTable1 so = new MtTable1();
+        so.setObjectId(oid);
+        so.setPersistenceState(PersistenceState.HOLLOW);
+        so.setObjectContext(serverContext);
+        serverContext.getGraphManager().registerNode(oid, so);
+
+        Object detached = op.detach(
+                so,
+                serverResover.getClassDescriptor("MtTable1"),
+                null);
+        assertNotNull(detached);
+        assertNotSame(so, detached);
+        assertTrue(detached instanceof ClientMtTable1);
+
+        ClientMtTable1 co = (ClientMtTable1) detached;
+        assertEquals(oid, co.getObjectId());
+        assertEquals("g1", co.getGlobalAttribute1());
+        assertEquals(PersistenceState.TRANSIENT, co.getPersistenceState());
+        assertNull(co.getObjectContext());
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/util/ObjectDetachOperationTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/util/ObjectDetachOperationTest.java b/cayenne-client/src/test/java/org/apache/cayenne/util/ObjectDetachOperationTest.java
deleted file mode 100644
index 985333f..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/util/ObjectDetachOperationTest.java
+++ /dev/null
@@ -1,112 +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.util;
-
-import org.apache.cayenne.ObjectId;
-import org.apache.cayenne.PersistenceState;
-import org.apache.cayenne.access.DataContext;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.map.EntityResolver;
-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.MtTable1;
-import org.apache.cayenne.unit.di.client.ClientCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class ObjectDetachOperationTest extends ClientCase {
-
-    @Inject
-    private DataContext serverContext;
-
-    @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");
-    }
-
-    public void testDetachCommitted() {
-
-        EntityResolver serverResover = serverContext.getEntityResolver();
-        EntityResolver clientResolver = serverResover.getClientEntityResolver();
-        ObjectDetachOperation op = new ObjectDetachOperation(clientResolver);
-
-        ObjectId oid = new ObjectId("MtTable1", MtTable1.TABLE1_ID_PK_COLUMN, 456);
-        MtTable1 so = new MtTable1();
-        so.setObjectId(oid);
-        so.setGlobalAttribute1("gx");
-        so.setPersistenceState(PersistenceState.COMMITTED);
-        so.setObjectContext(serverContext);
-        serverContext.getGraphManager().registerNode(oid, so);
-
-        Object detached = op.detach(
-                so,
-                serverResover.getClassDescriptor("MtTable1"),
-                null);
-        assertNotNull(detached);
-        assertNotSame(so, detached);
-        assertTrue(detached instanceof ClientMtTable1);
-
-        ClientMtTable1 co = (ClientMtTable1) detached;
-        assertEquals(oid, co.getObjectId());
-        assertEquals("gx", co.getGlobalAttribute1());
-        assertEquals(PersistenceState.TRANSIENT, co.getPersistenceState());
-        assertNull(co.getObjectContext());
-    }
-
-    public void testDetachHollow() throws Exception {
-
-        tMtTable1.insert(4, "g1", "s1");
-
-        EntityResolver serverResover = serverContext.getEntityResolver();
-        EntityResolver clientResolver = serverResover.getClientEntityResolver();
-        ObjectDetachOperation op = new ObjectDetachOperation(clientResolver);
-
-        ObjectId oid = new ObjectId("MtTable1", MtTable1.TABLE1_ID_PK_COLUMN, 4);
-        MtTable1 so = new MtTable1();
-        so.setObjectId(oid);
-        so.setPersistenceState(PersistenceState.HOLLOW);
-        so.setObjectContext(serverContext);
-        serverContext.getGraphManager().registerNode(oid, so);
-
-        Object detached = op.detach(
-                so,
-                serverResover.getClassDescriptor("MtTable1"),
-                null);
-        assertNotNull(detached);
-        assertNotSame(so, detached);
-        assertTrue(detached instanceof ClientMtTable1);
-
-        ClientMtTable1 co = (ClientMtTable1) detached;
-        assertEquals(oid, co.getObjectId());
-        assertEquals("g1", co.getGlobalAttribute1());
-        assertEquals(PersistenceState.TRANSIENT, co.getPersistenceState());
-        assertNull(co.getObjectContext());
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/util/ShallowMergeOperation_ClientIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/util/ShallowMergeOperation_ClientIT.java b/cayenne-client/src/test/java/org/apache/cayenne/util/ShallowMergeOperation_ClientIT.java
new file mode 100644
index 0000000..ec8bbdb
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/util/ShallowMergeOperation_ClientIT.java
@@ -0,0 +1,210 @@
+/*****************************************************************
+ *   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.util;
+
+import org.apache.cayenne.Cayenne;
+import org.apache.cayenne.CayenneContext;
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.PersistenceState;
+import org.apache.cayenne.Persistent;
+import org.apache.cayenne.configuration.rop.client.ClientRuntime;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.query.ObjectIdQuery;
+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.DataChannelInterceptor;
+import org.apache.cayenne.unit.di.UnitTestClosure;
+import org.apache.cayenne.unit.di.client.ClientCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class ShallowMergeOperation_ClientIT extends ClientCase {
+
+    @Inject
+    private ClientRuntime runtime;
+
+    @Inject
+    private CayenneContext context;
+
+    @Inject
+    private DataChannelInterceptor queryInterceptor;
+
+    @Inject
+    private DBHelper dbHelper;
+
+    private TableHelper tMtTable1;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("MT_TABLE2");
+        dbHelper.deleteAll("MT_TABLE1");
+        dbHelper.deleteAll("MT_JOIN45");
+        dbHelper.deleteAll("MT_TABLE4");
+        dbHelper.deleteAll("MT_TABLE5");
+
+        tMtTable1 = new TableHelper(dbHelper, "MT_TABLE1");
+        tMtTable1.setColumns("TABLE1_ID", "GLOBAL_ATTRIBUTE1", "SERVER_ATTRIBUTE1");
+    }
+
+    private void createMtTable1DataSet() throws Exception {
+        tMtTable1.insert(33001, "g1", "s1");
+        tMtTable1.insert(33002, "g2", "s2");
+        tMtTable1.insert(33003, "g3", "s3");
+        tMtTable1.insert(33004, "g4", "s4");
+    }
+
+    public void testMerge_Relationship() throws Exception {
+
+        ObjectContext childContext = runtime.newContext(context);
+        final ShallowMergeOperation op = new ShallowMergeOperation(childContext);
+
+        ClientMtTable1 _new = context.newObject(ClientMtTable1.class);
+        final ClientMtTable2 _new2 = context.newObject(ClientMtTable2.class);
+        _new.addToTable2Array(_new2);
+
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                ClientMtTable2 child2 = op.merge(_new2);
+                assertEquals(PersistenceState.COMMITTED, child2.getPersistenceState());
+                assertNotNull(child2.getTable1());
+                assertEquals(PersistenceState.COMMITTED, child2
+                        .getTable1()
+                        .getPersistenceState());
+            }
+        });
+    }
+
+    public void testMerge_NoOverride() throws Exception {
+
+        ObjectContext childContext = runtime.newContext(context);
+        final ShallowMergeOperation op = new ShallowMergeOperation(childContext);
+
+        final ClientMtTable1 modified = context.newObject(ClientMtTable1.class);
+        context.commitChanges();
+
+        final ClientMtTable1 peerModified = (ClientMtTable1) Cayenne.objectForQuery(
+                childContext,
+                new ObjectIdQuery(modified.getObjectId()));
+
+        modified.setGlobalAttribute1("M1");
+        peerModified.setGlobalAttribute1("M2");
+
+        assertEquals(PersistenceState.MODIFIED, modified.getPersistenceState());
+        assertEquals(PersistenceState.MODIFIED, peerModified.getPersistenceState());
+
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                Persistent peerModified2 = op.merge(modified);
+                assertSame(peerModified, peerModified2);
+                assertEquals(
+                        PersistenceState.MODIFIED,
+                        peerModified2.getPersistenceState());
+                assertEquals("M2", peerModified.getGlobalAttribute1());
+                assertEquals("M1", modified.getGlobalAttribute1());
+            }
+        });
+    }
+
+    public void testMerge_PersistenceStates() throws Exception {
+
+        createMtTable1DataSet();
+
+        final ObjectContext childContext = runtime.newContext(context);
+        final ShallowMergeOperation op = new ShallowMergeOperation(childContext);
+
+        final ClientMtTable1 _new = context.newObject(ClientMtTable1.class);
+
+        final ClientMtTable1 hollow = Cayenne.objectForPK(
+                context,
+                ClientMtTable1.class,
+                33001);
+        context.invalidateObjects(hollow);
+
+        final ClientMtTable1 committed = Cayenne.objectForPK(
+                context,
+                ClientMtTable1.class,
+                33002);
+
+        final ClientMtTable1 modified = Cayenne.objectForPK(
+                context,
+                ClientMtTable1.class,
+                33003);
+        modified.setGlobalAttribute1("XXX");
+
+        final ClientMtTable1 deleted = Cayenne.objectForPK(
+                context,
+                ClientMtTable1.class,
+                33004);
+        context.deleteObjects(deleted);
+
+        assertEquals(PersistenceState.HOLLOW, hollow.getPersistenceState());
+        assertEquals(PersistenceState.COMMITTED, committed.getPersistenceState());
+        assertEquals(PersistenceState.MODIFIED, modified.getPersistenceState());
+        assertEquals(PersistenceState.DELETED, deleted.getPersistenceState());
+        assertEquals(PersistenceState.NEW, _new.getPersistenceState());
+
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                Persistent newPeer = op.merge(_new);
+
+                assertEquals(_new.getObjectId(), newPeer.getObjectId());
+                assertEquals(PersistenceState.COMMITTED, newPeer.getPersistenceState());
+
+                assertSame(childContext, newPeer.getObjectContext());
+                assertSame(context, _new.getObjectContext());
+
+                Persistent hollowPeer = op.merge(hollow);
+                assertEquals(PersistenceState.HOLLOW, hollowPeer.getPersistenceState());
+                assertEquals(hollow.getObjectId(), hollowPeer.getObjectId());
+                assertSame(childContext, hollowPeer.getObjectContext());
+                assertSame(context, hollow.getObjectContext());
+
+                Persistent committedPeer = op.merge(committed);
+                assertEquals(
+                        PersistenceState.COMMITTED,
+                        committedPeer.getPersistenceState());
+                assertEquals(committed.getObjectId(), committedPeer.getObjectId());
+                assertSame(childContext, committedPeer.getObjectContext());
+                assertSame(context, committed.getObjectContext());
+
+                ClientMtTable1 modifiedPeer = op.merge(modified);
+                assertEquals(
+                        PersistenceState.COMMITTED,
+                        modifiedPeer.getPersistenceState());
+                assertEquals(modified.getObjectId(), modifiedPeer.getObjectId());
+                assertEquals("XXX", modifiedPeer.getGlobalAttribute1());
+                assertSame(childContext, modifiedPeer.getObjectContext());
+                assertSame(context, modified.getObjectContext());
+
+                Persistent deletedPeer = op.merge(deleted);
+                assertEquals(
+                        PersistenceState.COMMITTED,
+                        deletedPeer.getPersistenceState());
+                assertEquals(deleted.getObjectId(), deletedPeer.getObjectId());
+                assertSame(childContext, deletedPeer.getObjectContext());
+                assertSame(context, deleted.getObjectContext());
+            }
+        });
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/util/ShallowMergeOperation_ClientTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/util/ShallowMergeOperation_ClientTest.java b/cayenne-client/src/test/java/org/apache/cayenne/util/ShallowMergeOperation_ClientTest.java
deleted file mode 100644
index cedbf4f..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/util/ShallowMergeOperation_ClientTest.java
+++ /dev/null
@@ -1,210 +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.util;
-
-import org.apache.cayenne.Cayenne;
-import org.apache.cayenne.CayenneContext;
-import org.apache.cayenne.ObjectContext;
-import org.apache.cayenne.PersistenceState;
-import org.apache.cayenne.Persistent;
-import org.apache.cayenne.configuration.rop.client.ClientRuntime;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.query.ObjectIdQuery;
-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.DataChannelInterceptor;
-import org.apache.cayenne.unit.di.UnitTestClosure;
-import org.apache.cayenne.unit.di.client.ClientCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class ShallowMergeOperation_ClientTest extends ClientCase {
-
-    @Inject
-    private ClientRuntime runtime;
-
-    @Inject
-    private CayenneContext context;
-
-    @Inject
-    private DataChannelInterceptor queryInterceptor;
-
-    @Inject
-    private DBHelper dbHelper;
-
-    private TableHelper tMtTable1;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("MT_TABLE2");
-        dbHelper.deleteAll("MT_TABLE1");
-        dbHelper.deleteAll("MT_JOIN45");
-        dbHelper.deleteAll("MT_TABLE4");
-        dbHelper.deleteAll("MT_TABLE5");
-
-        tMtTable1 = new TableHelper(dbHelper, "MT_TABLE1");
-        tMtTable1.setColumns("TABLE1_ID", "GLOBAL_ATTRIBUTE1", "SERVER_ATTRIBUTE1");
-    }
-
-    private void createMtTable1DataSet() throws Exception {
-        tMtTable1.insert(33001, "g1", "s1");
-        tMtTable1.insert(33002, "g2", "s2");
-        tMtTable1.insert(33003, "g3", "s3");
-        tMtTable1.insert(33004, "g4", "s4");
-    }
-
-    public void testMerge_Relationship() throws Exception {
-
-        ObjectContext childContext = runtime.newContext(context);
-        final ShallowMergeOperation op = new ShallowMergeOperation(childContext);
-
-        ClientMtTable1 _new = context.newObject(ClientMtTable1.class);
-        final ClientMtTable2 _new2 = context.newObject(ClientMtTable2.class);
-        _new.addToTable2Array(_new2);
-
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                ClientMtTable2 child2 = op.merge(_new2);
-                assertEquals(PersistenceState.COMMITTED, child2.getPersistenceState());
-                assertNotNull(child2.getTable1());
-                assertEquals(PersistenceState.COMMITTED, child2
-                        .getTable1()
-                        .getPersistenceState());
-            }
-        });
-    }
-
-    public void testMerge_NoOverride() throws Exception {
-
-        ObjectContext childContext = runtime.newContext(context);
-        final ShallowMergeOperation op = new ShallowMergeOperation(childContext);
-
-        final ClientMtTable1 modified = context.newObject(ClientMtTable1.class);
-        context.commitChanges();
-
-        final ClientMtTable1 peerModified = (ClientMtTable1) Cayenne.objectForQuery(
-                childContext,
-                new ObjectIdQuery(modified.getObjectId()));
-
-        modified.setGlobalAttribute1("M1");
-        peerModified.setGlobalAttribute1("M2");
-
-        assertEquals(PersistenceState.MODIFIED, modified.getPersistenceState());
-        assertEquals(PersistenceState.MODIFIED, peerModified.getPersistenceState());
-
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                Persistent peerModified2 = op.merge(modified);
-                assertSame(peerModified, peerModified2);
-                assertEquals(
-                        PersistenceState.MODIFIED,
-                        peerModified2.getPersistenceState());
-                assertEquals("M2", peerModified.getGlobalAttribute1());
-                assertEquals("M1", modified.getGlobalAttribute1());
-            }
-        });
-    }
-
-    public void testMerge_PersistenceStates() throws Exception {
-
-        createMtTable1DataSet();
-
-        final ObjectContext childContext = runtime.newContext(context);
-        final ShallowMergeOperation op = new ShallowMergeOperation(childContext);
-
-        final ClientMtTable1 _new = context.newObject(ClientMtTable1.class);
-
-        final ClientMtTable1 hollow = Cayenne.objectForPK(
-                context,
-                ClientMtTable1.class,
-                33001);
-        context.invalidateObjects(hollow);
-
-        final ClientMtTable1 committed = Cayenne.objectForPK(
-                context,
-                ClientMtTable1.class,
-                33002);
-
-        final ClientMtTable1 modified = Cayenne.objectForPK(
-                context,
-                ClientMtTable1.class,
-                33003);
-        modified.setGlobalAttribute1("XXX");
-
-        final ClientMtTable1 deleted = Cayenne.objectForPK(
-                context,
-                ClientMtTable1.class,
-                33004);
-        context.deleteObjects(deleted);
-
-        assertEquals(PersistenceState.HOLLOW, hollow.getPersistenceState());
-        assertEquals(PersistenceState.COMMITTED, committed.getPersistenceState());
-        assertEquals(PersistenceState.MODIFIED, modified.getPersistenceState());
-        assertEquals(PersistenceState.DELETED, deleted.getPersistenceState());
-        assertEquals(PersistenceState.NEW, _new.getPersistenceState());
-
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                Persistent newPeer = op.merge(_new);
-
-                assertEquals(_new.getObjectId(), newPeer.getObjectId());
-                assertEquals(PersistenceState.COMMITTED, newPeer.getPersistenceState());
-
-                assertSame(childContext, newPeer.getObjectContext());
-                assertSame(context, _new.getObjectContext());
-
-                Persistent hollowPeer = op.merge(hollow);
-                assertEquals(PersistenceState.HOLLOW, hollowPeer.getPersistenceState());
-                assertEquals(hollow.getObjectId(), hollowPeer.getObjectId());
-                assertSame(childContext, hollowPeer.getObjectContext());
-                assertSame(context, hollow.getObjectContext());
-
-                Persistent committedPeer = op.merge(committed);
-                assertEquals(
-                        PersistenceState.COMMITTED,
-                        committedPeer.getPersistenceState());
-                assertEquals(committed.getObjectId(), committedPeer.getObjectId());
-                assertSame(childContext, committedPeer.getObjectContext());
-                assertSame(context, committed.getObjectContext());
-
-                ClientMtTable1 modifiedPeer = op.merge(modified);
-                assertEquals(
-                        PersistenceState.COMMITTED,
-                        modifiedPeer.getPersistenceState());
-                assertEquals(modified.getObjectId(), modifiedPeer.getObjectId());
-                assertEquals("XXX", modifiedPeer.getGlobalAttribute1());
-                assertSame(childContext, modifiedPeer.getObjectContext());
-                assertSame(context, modified.getObjectContext());
-
-                Persistent deletedPeer = op.merge(deleted);
-                assertEquals(
-                        PersistenceState.COMMITTED,
-                        deletedPeer.getPersistenceState());
-                assertEquals(deleted.getObjectId(), deletedPeer.getObjectId());
-                assertSame(childContext, deletedPeer.getObjectContext());
-                assertSame(context, deleted.getObjectContext());
-            }
-        });
-    }
-}


[2/8] Rename Integration Tests in cayenne-client (*IT.java instead of *Test.java)

Posted by aa...@apache.org.
http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/remote/ClientChannelServerDiffsTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/remote/ClientChannelServerDiffsTest.java b/cayenne-client/src/test/java/org/apache/cayenne/remote/ClientChannelServerDiffsTest.java
deleted file mode 100644
index 6481114..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/remote/ClientChannelServerDiffsTest.java
+++ /dev/null
@@ -1,263 +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 java.util.ArrayList;
-import java.util.List;
-
-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;
-
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class ClientChannelServerDiffsTest 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;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/remote/LightSuperClassIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/remote/LightSuperClassIT.java b/cayenne-client/src/test/java/org/apache/cayenne/remote/LightSuperClassIT.java
new file mode 100644
index 0000000..a3ff1b5
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/remote/LightSuperClassIT.java
@@ -0,0 +1,95 @@
+/*****************************************************************
+ *   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.ObjectContext;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.query.RefreshQuery;
+import org.apache.cayenne.query.SelectQuery;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.testdo.persistent.Continent;
+import org.apache.cayenne.testdo.persistent.Country;
+import org.apache.cayenne.unit.di.client.ClientCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+/**
+ * Test for entites that are implemented in same class on client and server
+ */
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class LightSuperClassIT extends RemoteCayenneCase {
+
+    @Inject
+    private DBHelper dbHelper;
+
+    private boolean server;
+
+    @Override
+    public void setUpAfterInjection() throws Exception {
+        super.setUpAfterInjection();
+
+        dbHelper.deleteAll("CONTINENT");
+        dbHelper.deleteAll("COUNTRY");
+    }
+
+    @Override
+    public void runBare() throws Throwable {
+        server = true;
+        super.runBare();
+        server = false;
+
+        // testing ROP with all serialization policies
+        runBareSimple();
+    }
+
+    private ObjectContext createContext() {
+        if (server) {
+            return serverContext;
+        }
+        else {
+            return createROPContext();
+        }
+    }
+
+    public void testServer() throws Exception {
+        ObjectContext context = createContext();
+        Continent continent = context.newObject(Continent.class);
+        continent.setName("Europe");
+
+        Country country = new Country();
+        context.registerNewObject(country);
+
+        // TODO: setting property before object creation does not work on ROP (CAY-1320)
+        country.setName("Russia");
+
+        country.setContinent(continent);
+        assertEquals(continent.getCountries().size(), 1);
+
+        context.commitChanges();
+
+        context.deleteObjects(country);
+        assertEquals(continent.getCountries().size(), 0);
+        continent.setName("Australia");
+
+        context.commitChanges();
+        context.performQuery(new RefreshQuery());
+
+        assertEquals(context.performQuery(new SelectQuery(Country.class)).size(), 0);
+        assertEquals(context.performQuery(new SelectQuery(Continent.class)).size(), 1);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/remote/LightSuperClassTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/remote/LightSuperClassTest.java b/cayenne-client/src/test/java/org/apache/cayenne/remote/LightSuperClassTest.java
deleted file mode 100644
index 80853f3..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/remote/LightSuperClassTest.java
+++ /dev/null
@@ -1,95 +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.ObjectContext;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.query.RefreshQuery;
-import org.apache.cayenne.query.SelectQuery;
-import org.apache.cayenne.test.jdbc.DBHelper;
-import org.apache.cayenne.testdo.persistent.Continent;
-import org.apache.cayenne.testdo.persistent.Country;
-import org.apache.cayenne.unit.di.client.ClientCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-/**
- * Test for entites that are implemented in same class on client and server
- */
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class LightSuperClassTest extends RemoteCayenneCase {
-
-    @Inject
-    private DBHelper dbHelper;
-
-    private boolean server;
-
-    @Override
-    public void setUpAfterInjection() throws Exception {
-        super.setUpAfterInjection();
-
-        dbHelper.deleteAll("CONTINENT");
-        dbHelper.deleteAll("COUNTRY");
-    }
-
-    @Override
-    public void runBare() throws Throwable {
-        server = true;
-        super.runBare();
-        server = false;
-
-        // testing ROP with all serialization policies
-        runBareSimple();
-    }
-
-    private ObjectContext createContext() {
-        if (server) {
-            return serverContext;
-        }
-        else {
-            return createROPContext();
-        }
-    }
-
-    public void testServer() throws Exception {
-        ObjectContext context = createContext();
-        Continent continent = context.newObject(Continent.class);
-        continent.setName("Europe");
-
-        Country country = new Country();
-        context.registerNewObject(country);
-
-        // TODO: setting property before object creation does not work on ROP (CAY-1320)
-        country.setName("Russia");
-
-        country.setContinent(continent);
-        assertEquals(continent.getCountries().size(), 1);
-
-        context.commitChanges();
-
-        context.deleteObjects(country);
-        assertEquals(continent.getCountries().size(), 0);
-        continent.setName("Australia");
-
-        context.commitChanges();
-        context.performQuery(new RefreshQuery());
-
-        assertEquals(context.performQuery(new SelectQuery(Country.class)).size(), 0);
-        assertEquals(context.performQuery(new SelectQuery(Continent.class)).size(), 1);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextLocalIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextLocalIT.java b/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextLocalIT.java
new file mode 100644
index 0000000..991072f
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextLocalIT.java
@@ -0,0 +1,58 @@
+/*****************************************************************
+ *   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 java.util.List;
+
+import org.apache.cayenne.BaseContext;
+import org.apache.cayenne.configuration.rop.client.ClientRuntime;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.query.QueryCacheStrategy;
+import org.apache.cayenne.query.SelectQuery;
+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 NestedObjectContextLocalIT extends RemoteCayenneCase {
+    
+    @Inject
+    private ClientRuntime runtime;
+
+    public void testLocalCacheStaysLocal() {
+
+        SelectQuery query = new SelectQuery(ClientMtTable1.class);
+        query.setCacheStrategy(QueryCacheStrategy.LOCAL_CACHE);
+
+        BaseContext child1 = (BaseContext) runtime.newContext(clientContext);
+
+        assertNull(child1.getQueryCache().get(
+                query.getMetaData(child1.getEntityResolver())));
+
+        assertNull(clientContext.getQueryCache().get(
+                query.getMetaData(clientContext.getEntityResolver())));
+
+        List<?> results = child1.performQuery(query);
+        assertSame(results, child1.getQueryCache().get(
+                query.getMetaData(child1.getEntityResolver())));
+
+        assertNull(clientContext.getQueryCache().get(
+                query.getMetaData(clientContext.getEntityResolver())));
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextLocalTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextLocalTest.java b/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextLocalTest.java
deleted file mode 100644
index 24ddc82..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextLocalTest.java
+++ /dev/null
@@ -1,58 +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 java.util.List;
-
-import org.apache.cayenne.BaseContext;
-import org.apache.cayenne.configuration.rop.client.ClientRuntime;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.query.QueryCacheStrategy;
-import org.apache.cayenne.query.SelectQuery;
-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 NestedObjectContextLocalTest extends RemoteCayenneCase {
-    
-    @Inject
-    private ClientRuntime runtime;
-
-    public void testLocalCacheStaysLocal() {
-
-        SelectQuery query = new SelectQuery(ClientMtTable1.class);
-        query.setCacheStrategy(QueryCacheStrategy.LOCAL_CACHE);
-
-        BaseContext child1 = (BaseContext) runtime.newContext(clientContext);
-
-        assertNull(child1.getQueryCache().get(
-                query.getMetaData(child1.getEntityResolver())));
-
-        assertNull(clientContext.getQueryCache().get(
-                query.getMetaData(clientContext.getEntityResolver())));
-
-        List<?> results = child1.performQuery(query);
-        assertSame(results, child1.getQueryCache().get(
-                query.getMetaData(child1.getEntityResolver())));
-
-        assertNull(clientContext.getQueryCache().get(
-                query.getMetaData(clientContext.getEntityResolver())));
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextParentEventsIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextParentEventsIT.java b/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextParentEventsIT.java
new file mode 100644
index 0000000..ba4ad9a
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextParentEventsIT.java
@@ -0,0 +1,64 @@
+/*****************************************************************
+ *   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.ObjectContext;
+import org.apache.cayenne.configuration.rop.client.ClientRuntime;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.test.jdbc.DBHelper;
+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 NestedObjectContextParentEventsIT extends RemoteCayenneCase {
+
+    @Inject
+    private DBHelper dbHelper;
+    
+    @Inject
+    private ClientRuntime runtime;
+
+    @Override
+    public void setUpAfterInjection() throws Exception {
+        super.setUpAfterInjection();
+
+        dbHelper.deleteAll("MT_TABLE2");
+        dbHelper.deleteAll("MT_TABLE1");
+    }
+
+    public void testParentUpdatedId() throws Exception {
+        ObjectContext child = runtime.newContext(clientContext);
+
+        ClientMtTable1 ac = child.newObject(ClientMtTable1.class);
+        ac.setGlobalAttribute1("X");
+        child.commitChangesToParent();
+
+        ClientMtTable1 ap = (ClientMtTable1) clientContext.getGraphManager().getNode(
+                ac.getObjectId());
+        assertNotNull(ap);
+
+        assertTrue(ap.getObjectId().isTemporary());
+        clientContext.commitChanges();
+
+        assertFalse(ap.getObjectId().isTemporary());
+        assertEquals(ap.getObjectId(), ac.getObjectId());
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextParentEventsTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextParentEventsTest.java b/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextParentEventsTest.java
deleted file mode 100644
index 1f40a8f..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextParentEventsTest.java
+++ /dev/null
@@ -1,64 +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.ObjectContext;
-import org.apache.cayenne.configuration.rop.client.ClientRuntime;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.test.jdbc.DBHelper;
-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 NestedObjectContextParentEventsTest extends RemoteCayenneCase {
-
-    @Inject
-    private DBHelper dbHelper;
-    
-    @Inject
-    private ClientRuntime runtime;
-
-    @Override
-    public void setUpAfterInjection() throws Exception {
-        super.setUpAfterInjection();
-
-        dbHelper.deleteAll("MT_TABLE2");
-        dbHelper.deleteAll("MT_TABLE1");
-    }
-
-    public void testParentUpdatedId() throws Exception {
-        ObjectContext child = runtime.newContext(clientContext);
-
-        ClientMtTable1 ac = child.newObject(ClientMtTable1.class);
-        ac.setGlobalAttribute1("X");
-        child.commitChangesToParent();
-
-        ClientMtTable1 ap = (ClientMtTable1) clientContext.getGraphManager().getNode(
-                ac.getObjectId());
-        assertNotNull(ap);
-
-        assertTrue(ap.getObjectId().isTemporary());
-        clientContext.commitChanges();
-
-        assertFalse(ap.getObjectId().isTemporary());
-        assertEquals(ap.getObjectId(), ac.getObjectId());
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextPeerEventsIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextPeerEventsIT.java b/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextPeerEventsIT.java
new file mode 100644
index 0000000..5ad385a
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextPeerEventsIT.java
@@ -0,0 +1,149 @@
+/*****************************************************************
+ *   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.ObjectContext;
+import org.apache.cayenne.ObjectId;
+import org.apache.cayenne.configuration.rop.client.ClientRuntime;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.test.jdbc.DBHelper;
+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 NestedObjectContextPeerEventsIT extends RemoteCayenneCase {
+
+    @Inject
+    private ClientRuntime runtime;
+    
+    @Inject
+    private DBHelper dbHelper;
+
+    @Override
+    public void setUpAfterInjection() throws Exception {
+        super.setUpAfterInjection();
+
+        dbHelper.deleteAll("MT_TABLE2");
+        dbHelper.deleteAll("MT_TABLE1");
+    }
+
+    public void testPeerObjectUpdatedTempOID() throws Exception {
+        ObjectContext peer1 = runtime.newContext(clientContext);
+        ClientMtTable1 a1 = peer1.newObject(ClientMtTable1.class);
+        a1.setGlobalAttribute1("Y");
+        ObjectId a1TempId = a1.getObjectId();
+
+        ObjectContext peer2 = runtime.newContext(clientContext);
+        ClientMtTable1 a2 = peer2.localObject(a1);
+
+        assertEquals(a1TempId, a2.getObjectId());
+
+        peer1.commitChanges();
+        assertFalse(a1.getObjectId().isTemporary());
+        assertFalse(a2.getObjectId().isTemporary());
+        assertEquals(a2.getObjectId(), a1.getObjectId());
+    }
+
+    public void testPeerObjectUpdatedSimpleProperty() throws Exception {
+        ClientMtTable1 a = clientContext.newObject(ClientMtTable1.class);
+        a.setGlobalAttribute1("X");
+        clientContext.commitChanges();
+
+        ObjectContext peer1 = runtime.newContext(clientContext);
+        ClientMtTable1 a1 = peer1.localObject(a);
+
+        ObjectContext peer2 = runtime.newContext(clientContext);
+        ClientMtTable1 a2 = peer2.localObject(a);
+
+        a1.setGlobalAttribute1("Y");
+        assertEquals("X", a2.getGlobalAttribute1());
+        peer1.commitChangesToParent();
+        assertEquals("Y", a2.getGlobalAttribute1());
+
+        assertFalse(
+                "Peer data context became dirty on event processing",
+                peer2.hasChanges());
+    }
+
+    public void testPeerObjectUpdatedToOneRelationship() throws Exception {
+        ClientMtTable1 a = clientContext.newObject(ClientMtTable1.class);
+        ClientMtTable1 altA = clientContext.newObject(ClientMtTable1.class);
+
+        ClientMtTable2 p = clientContext.newObject(ClientMtTable2.class);
+        p.setTable1(a);
+        p.setGlobalAttribute("PPP");
+        a.setGlobalAttribute1("X");
+        altA.setGlobalAttribute1("Y");
+        clientContext.commitChanges();
+
+        ObjectContext peer1 = runtime.newContext(clientContext);
+        ClientMtTable2 p1 = peer1.localObject(p);
+        ClientMtTable1 altA1 = peer1.localObject(altA);
+
+        ObjectContext peer2 = runtime.newContext(clientContext);
+        ClientMtTable2 p2 = peer2.localObject(p);
+        ClientMtTable1 altA2 = peer2.localObject(altA);
+        ClientMtTable1 a2 = peer2.localObject(a);
+
+        p1.setTable1(altA1);
+        assertSame(a2, p2.getTable1());
+        peer1.commitChangesToParent();
+        assertEquals(altA2, p2.getTable1());
+
+        assertFalse(
+                "Peer data context became dirty on event processing",
+                peer2.hasChanges());
+    }
+
+    public void testPeerObjectUpdatedToManyRelationship() throws Exception {
+        ClientMtTable1 a = clientContext.newObject(ClientMtTable1.class);
+        a.setGlobalAttribute1("X");
+
+        ClientMtTable2 px = clientContext.newObject(ClientMtTable2.class);
+        px.setTable1(a);
+        px.setGlobalAttribute("PX");
+
+        ClientMtTable2 py = clientContext.newObject(ClientMtTable2.class);
+        py.setGlobalAttribute("PY");
+
+        clientContext.commitChanges();
+
+        ObjectContext peer1 = runtime.newContext(clientContext);
+        ClientMtTable2 py1 = peer1.localObject(py);
+        ClientMtTable1 a1 = peer1.localObject(a);
+
+        ObjectContext peer2 = runtime.newContext(clientContext);
+        ClientMtTable2 py2 = peer2.localObject(py);
+        ClientMtTable1 a2 = peer2.localObject(a);
+
+        a1.addToTable2Array(py1);
+        assertEquals(1, a2.getTable2Array().size());
+        assertFalse(a2.getTable2Array().contains(py2));
+        peer1.commitChangesToParent();
+        assertEquals(2, a2.getTable2Array().size());
+        assertTrue(a2.getTable2Array().contains(py2));
+
+        assertFalse(
+                "Peer data context became dirty on event processing",
+                peer2.hasChanges());
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextPeerEventsTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextPeerEventsTest.java b/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextPeerEventsTest.java
deleted file mode 100644
index fbb0e52..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextPeerEventsTest.java
+++ /dev/null
@@ -1,149 +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.ObjectContext;
-import org.apache.cayenne.ObjectId;
-import org.apache.cayenne.configuration.rop.client.ClientRuntime;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.test.jdbc.DBHelper;
-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 NestedObjectContextPeerEventsTest extends RemoteCayenneCase {
-
-    @Inject
-    private ClientRuntime runtime;
-    
-    @Inject
-    private DBHelper dbHelper;
-
-    @Override
-    public void setUpAfterInjection() throws Exception {
-        super.setUpAfterInjection();
-
-        dbHelper.deleteAll("MT_TABLE2");
-        dbHelper.deleteAll("MT_TABLE1");
-    }
-
-    public void testPeerObjectUpdatedTempOID() throws Exception {
-        ObjectContext peer1 = runtime.newContext(clientContext);
-        ClientMtTable1 a1 = peer1.newObject(ClientMtTable1.class);
-        a1.setGlobalAttribute1("Y");
-        ObjectId a1TempId = a1.getObjectId();
-
-        ObjectContext peer2 = runtime.newContext(clientContext);
-        ClientMtTable1 a2 = peer2.localObject(a1);
-
-        assertEquals(a1TempId, a2.getObjectId());
-
-        peer1.commitChanges();
-        assertFalse(a1.getObjectId().isTemporary());
-        assertFalse(a2.getObjectId().isTemporary());
-        assertEquals(a2.getObjectId(), a1.getObjectId());
-    }
-
-    public void testPeerObjectUpdatedSimpleProperty() throws Exception {
-        ClientMtTable1 a = clientContext.newObject(ClientMtTable1.class);
-        a.setGlobalAttribute1("X");
-        clientContext.commitChanges();
-
-        ObjectContext peer1 = runtime.newContext(clientContext);
-        ClientMtTable1 a1 = peer1.localObject(a);
-
-        ObjectContext peer2 = runtime.newContext(clientContext);
-        ClientMtTable1 a2 = peer2.localObject(a);
-
-        a1.setGlobalAttribute1("Y");
-        assertEquals("X", a2.getGlobalAttribute1());
-        peer1.commitChangesToParent();
-        assertEquals("Y", a2.getGlobalAttribute1());
-
-        assertFalse(
-                "Peer data context became dirty on event processing",
-                peer2.hasChanges());
-    }
-
-    public void testPeerObjectUpdatedToOneRelationship() throws Exception {
-        ClientMtTable1 a = clientContext.newObject(ClientMtTable1.class);
-        ClientMtTable1 altA = clientContext.newObject(ClientMtTable1.class);
-
-        ClientMtTable2 p = clientContext.newObject(ClientMtTable2.class);
-        p.setTable1(a);
-        p.setGlobalAttribute("PPP");
-        a.setGlobalAttribute1("X");
-        altA.setGlobalAttribute1("Y");
-        clientContext.commitChanges();
-
-        ObjectContext peer1 = runtime.newContext(clientContext);
-        ClientMtTable2 p1 = peer1.localObject(p);
-        ClientMtTable1 altA1 = peer1.localObject(altA);
-
-        ObjectContext peer2 = runtime.newContext(clientContext);
-        ClientMtTable2 p2 = peer2.localObject(p);
-        ClientMtTable1 altA2 = peer2.localObject(altA);
-        ClientMtTable1 a2 = peer2.localObject(a);
-
-        p1.setTable1(altA1);
-        assertSame(a2, p2.getTable1());
-        peer1.commitChangesToParent();
-        assertEquals(altA2, p2.getTable1());
-
-        assertFalse(
-                "Peer data context became dirty on event processing",
-                peer2.hasChanges());
-    }
-
-    public void testPeerObjectUpdatedToManyRelationship() throws Exception {
-        ClientMtTable1 a = clientContext.newObject(ClientMtTable1.class);
-        a.setGlobalAttribute1("X");
-
-        ClientMtTable2 px = clientContext.newObject(ClientMtTable2.class);
-        px.setTable1(a);
-        px.setGlobalAttribute("PX");
-
-        ClientMtTable2 py = clientContext.newObject(ClientMtTable2.class);
-        py.setGlobalAttribute("PY");
-
-        clientContext.commitChanges();
-
-        ObjectContext peer1 = runtime.newContext(clientContext);
-        ClientMtTable2 py1 = peer1.localObject(py);
-        ClientMtTable1 a1 = peer1.localObject(a);
-
-        ObjectContext peer2 = runtime.newContext(clientContext);
-        ClientMtTable2 py2 = peer2.localObject(py);
-        ClientMtTable1 a2 = peer2.localObject(a);
-
-        a1.addToTable2Array(py1);
-        assertEquals(1, a2.getTable2Array().size());
-        assertFalse(a2.getTable2Array().contains(py2));
-        peer1.commitChangesToParent();
-        assertEquals(2, a2.getTable2Array().size());
-        assertTrue(a2.getTable2Array().contains(py2));
-
-        assertFalse(
-                "Peer data context became dirty on event processing",
-                peer2.hasChanges());
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextRollbackIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextRollbackIT.java b/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextRollbackIT.java
new file mode 100644
index 0000000..3fef10c
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextRollbackIT.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.remote;
+
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.configuration.rop.client.ClientRuntime;
+import org.apache.cayenne.di.Inject;
+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 NestedObjectContextRollbackIT extends RemoteCayenneCase {
+    
+    @Inject
+    private ClientRuntime runtime;
+
+    public void testRollbackChanges() {
+        ObjectContext child1 = runtime.newContext(clientContext);
+        
+        assertFalse(clientContext.hasChanges());
+        assertFalse(child1.hasChanges());
+        
+        clientContext.newObject(ClientMtTable1.class);
+        child1.newObject(ClientMtTable1.class);
+        
+        assertTrue(clientContext.hasChanges());
+        assertTrue(child1.hasChanges());
+        
+        child1.rollbackChanges();
+        assertFalse(clientContext.hasChanges());
+        assertFalse(child1.hasChanges());
+        
+        clientContext.rollbackChanges();
+    }
+    
+    public void testRollbackChangesLocally() {
+        ObjectContext child1 = runtime.newContext(clientContext);
+        
+        assertFalse(clientContext.hasChanges());
+        assertFalse(child1.hasChanges());
+        
+        clientContext.newObject(ClientMtTable1.class);
+        child1.newObject(ClientMtTable1.class);
+        
+        assertTrue(clientContext.hasChanges());
+        assertTrue(child1.hasChanges());
+        
+        child1.rollbackChangesLocally();
+        assertTrue(clientContext.hasChanges());
+        assertFalse(child1.hasChanges());
+        
+        clientContext.rollbackChanges();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextRollbackTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextRollbackTest.java b/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextRollbackTest.java
deleted file mode 100644
index fdf7c5d..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/remote/NestedObjectContextRollbackTest.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.remote;
-
-import org.apache.cayenne.ObjectContext;
-import org.apache.cayenne.configuration.rop.client.ClientRuntime;
-import org.apache.cayenne.di.Inject;
-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 NestedObjectContextRollbackTest extends RemoteCayenneCase {
-    
-    @Inject
-    private ClientRuntime runtime;
-
-    public void testRollbackChanges() {
-        ObjectContext child1 = runtime.newContext(clientContext);
-        
-        assertFalse(clientContext.hasChanges());
-        assertFalse(child1.hasChanges());
-        
-        clientContext.newObject(ClientMtTable1.class);
-        child1.newObject(ClientMtTable1.class);
-        
-        assertTrue(clientContext.hasChanges());
-        assertTrue(child1.hasChanges());
-        
-        child1.rollbackChanges();
-        assertFalse(clientContext.hasChanges());
-        assertFalse(child1.hasChanges());
-        
-        clientContext.rollbackChanges();
-    }
-    
-    public void testRollbackChangesLocally() {
-        ObjectContext child1 = runtime.newContext(clientContext);
-        
-        assertFalse(clientContext.hasChanges());
-        assertFalse(child1.hasChanges());
-        
-        clientContext.newObject(ClientMtTable1.class);
-        child1.newObject(ClientMtTable1.class);
-        
-        assertTrue(clientContext.hasChanges());
-        assertTrue(child1.hasChanges());
-        
-        child1.rollbackChangesLocally();
-        assertTrue(clientContext.hasChanges());
-        assertFalse(child1.hasChanges());
-        
-        clientContext.rollbackChanges();
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/remote/ROPPrefetchToManyMapIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/remote/ROPPrefetchToManyMapIT.java b/cayenne-client/src/test/java/org/apache/cayenne/remote/ROPPrefetchToManyMapIT.java
new file mode 100644
index 0000000..b6b6875
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/remote/ROPPrefetchToManyMapIT.java
@@ -0,0 +1,70 @@
+/*****************************************************************
+ *   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.Cayenne;
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.query.RefreshQuery;
+import org.apache.cayenne.query.SelectQuery;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.testdo.mt.ClientMtMapToMany;
+import org.apache.cayenne.testdo.mt.ClientMtMapToManyTarget;
+import org.apache.cayenne.unit.di.DataChannelInterceptor;
+import org.apache.cayenne.unit.di.UnitTestClosure;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+@UseServerRuntime("cayenne-multi-tier.xml")
+public class ROPPrefetchToManyMapIT extends RemoteCayenneCase {
+    
+    @Inject
+    private DBHelper dbHelper;
+    
+    @Inject
+    private DataChannelInterceptor queryInterceptor;
+    
+    @Override
+    public void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("MT_MAP_TO_MANY_TARGET");
+        dbHelper.deleteAll("MT_MAP_TO_MANY");        
+    }
+    
+    public void test() throws Exception {
+        ObjectContext context = createROPContext();
+        
+        ClientMtMapToMany map = context.newObject(ClientMtMapToMany.class);
+        ClientMtMapToManyTarget target = context.newObject(ClientMtMapToManyTarget.class);
+        target.setMapToMany(map);
+        context.commitChanges();
+        
+        context.performQuery(new RefreshQuery());
+        
+        SelectQuery query = new SelectQuery(ClientMtMapToMany.class);
+        query.addPrefetch("targets");
+        
+        final ClientMtMapToMany mapToMany = (ClientMtMapToMany) Cayenne.objectForQuery(context, query);
+        
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+            
+            public void execute() {
+                assertEquals(mapToMany.getTargets().size(), 1);
+            }
+        });
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/remote/ROPPrefetchToManyMapTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/remote/ROPPrefetchToManyMapTest.java b/cayenne-client/src/test/java/org/apache/cayenne/remote/ROPPrefetchToManyMapTest.java
deleted file mode 100644
index 1951f41..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/remote/ROPPrefetchToManyMapTest.java
+++ /dev/null
@@ -1,70 +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.Cayenne;
-import org.apache.cayenne.ObjectContext;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.query.RefreshQuery;
-import org.apache.cayenne.query.SelectQuery;
-import org.apache.cayenne.test.jdbc.DBHelper;
-import org.apache.cayenne.testdo.mt.ClientMtMapToMany;
-import org.apache.cayenne.testdo.mt.ClientMtMapToManyTarget;
-import org.apache.cayenne.unit.di.DataChannelInterceptor;
-import org.apache.cayenne.unit.di.UnitTestClosure;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime("cayenne-multi-tier.xml")
-public class ROPPrefetchToManyMapTest extends RemoteCayenneCase {
-    
-    @Inject
-    private DBHelper dbHelper;
-    
-    @Inject
-    private DataChannelInterceptor queryInterceptor;
-    
-    @Override
-    public void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("MT_MAP_TO_MANY_TARGET");
-        dbHelper.deleteAll("MT_MAP_TO_MANY");        
-    }
-    
-    public void test() throws Exception {
-        ObjectContext context = createROPContext();
-        
-        ClientMtMapToMany map = context.newObject(ClientMtMapToMany.class);
-        ClientMtMapToManyTarget target = context.newObject(ClientMtMapToManyTarget.class);
-        target.setMapToMany(map);
-        context.commitChanges();
-        
-        context.performQuery(new RefreshQuery());
-        
-        SelectQuery query = new SelectQuery(ClientMtMapToMany.class);
-        query.addPrefetch("targets");
-        
-        final ClientMtMapToMany mapToMany = (ClientMtMapToMany) Cayenne.objectForQuery(context, query);
-        
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-            
-            public void execute() {
-                assertEquals(mapToMany.getTargets().size(), 1);
-            }
-        });
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/remote/RelationshipChangeIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/remote/RelationshipChangeIT.java b/cayenne-client/src/test/java/org/apache/cayenne/remote/RelationshipChangeIT.java
new file mode 100644
index 0000000..b488d80
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/remote/RelationshipChangeIT.java
@@ -0,0 +1,60 @@
+/*****************************************************************
+ *   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.testdo.mt.ClientMtTable2;
+import org.apache.cayenne.unit.di.client.ClientCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+/**
+ * This is a test primarily for CAY-1118
+ */
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class RelationshipChangeIT extends RemoteCayenneCase {
+
+    public void testNullify() {
+        ClientMtTable1 o1 = clientContext.newObject(ClientMtTable1.class);
+        ClientMtTable2 o2 = clientContext.newObject(ClientMtTable2.class);
+        
+        o2.setTable1(o1);
+
+        assertEquals(1, o1.getTable2Array().size());
+        clientContext.commitChanges();
+
+        o2.setTable1(null);
+        assertEquals(0, o1.getTable2Array().size());
+    }
+    
+    public void testChange() {
+        ClientMtTable1 o1 = clientContext.newObject(ClientMtTable1.class);
+        ClientMtTable2 o2 = clientContext.newObject(ClientMtTable2.class);
+        
+        ClientMtTable1 o3 = clientContext.newObject(ClientMtTable1.class);
+        
+        o2.setTable1(o1);
+
+        assertEquals(1, o1.getTable2Array().size());
+        clientContext.commitChanges();
+
+        o2.setTable1(o3);
+        assertEquals(0, o1.getTable2Array().size());
+        assertEquals(1, o3.getTable2Array().size());
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/remote/RelationshipChangeTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/remote/RelationshipChangeTest.java b/cayenne-client/src/test/java/org/apache/cayenne/remote/RelationshipChangeTest.java
deleted file mode 100644
index 463e299..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/remote/RelationshipChangeTest.java
+++ /dev/null
@@ -1,60 +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.testdo.mt.ClientMtTable2;
-import org.apache.cayenne.unit.di.client.ClientCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-/**
- * This is a test primarily for CAY-1118
- */
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class RelationshipChangeTest extends RemoteCayenneCase {
-
-    public void testNullify() {
-        ClientMtTable1 o1 = clientContext.newObject(ClientMtTable1.class);
-        ClientMtTable2 o2 = clientContext.newObject(ClientMtTable2.class);
-        
-        o2.setTable1(o1);
-
-        assertEquals(1, o1.getTable2Array().size());
-        clientContext.commitChanges();
-
-        o2.setTable1(null);
-        assertEquals(0, o1.getTable2Array().size());
-    }
-    
-    public void testChange() {
-        ClientMtTable1 o1 = clientContext.newObject(ClientMtTable1.class);
-        ClientMtTable2 o2 = clientContext.newObject(ClientMtTable2.class);
-        
-        ClientMtTable1 o3 = clientContext.newObject(ClientMtTable1.class);
-        
-        o2.setTable1(o1);
-
-        assertEquals(1, o1.getTable2Array().size());
-        clientContext.commitChanges();
-
-        o2.setTable1(o3);
-        assertEquals(0, o1.getTable2Array().size());
-        assertEquals(1, o3.getTable2Array().size());
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/remote/RemoteCallbacksIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/remote/RemoteCallbacksIT.java b/cayenne-client/src/test/java/org/apache/cayenne/remote/RemoteCallbacksIT.java
new file mode 100644
index 0000000..156b267
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/remote/RemoteCallbacksIT.java
@@ -0,0 +1,118 @@
+/*****************************************************************
+ *   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.LifecycleListener;
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.testdo.mt.ClientMtLifecycles;
+import org.apache.cayenne.unit.di.client.ClientCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class RemoteCallbacksIT extends RemoteCayenneCase implements LifecycleListener {
+    private int added, loaded, prePersisted, postPersisted, preRemoved, postRemoved, preUpdated, postUpdated;
+    
+    @Override
+    public void setUpAfterInjection() throws Exception {
+        super.setUpAfterInjection();
+        
+        added = 0;
+        loaded = 0;
+        prePersisted = 0;
+        postPersisted = 0;
+        preRemoved = 0;
+        postRemoved = 0;
+        preUpdated = 0;
+        postUpdated = 0;
+    }
+    
+    public void testDefault() throws InterruptedException {
+        ObjectContext context = createROPContext();
+        context.getEntityResolver().getCallbackRegistry().addListener(ClientMtLifecycles.class, this);
+        
+        assertAll(0, 0, 0, 0, 0, 0, 0, 0);
+        ClientMtLifecycles l1 = context.newObject(ClientMtLifecycles.class);
+        
+        assertAll(1, 0, 0, 0, 0, 0, 0, 0);
+        l1.setName("x");
+        assertAll(1, 0, 0, 0, 0, 0, 0, 0);
+        
+        context.commitChanges();
+        Thread.sleep(5); //until commit
+        assertAll(1, 0, 1, 1, 0, 0, 0, 0);
+        
+        l1.setName("x2");
+        assertAll(1, 0, 1, 1, 0, 0, 0, 0);
+        
+        context.commitChanges();
+        Thread.sleep(5); //until commit
+        assertAll(1, 0, 1, 1, 1, 1, 0, 0);
+        
+        context.deleteObjects(l1);
+        assertAll(1, 0, 1, 1, 1, 1, 1, 0);
+        
+        context.commitChanges();
+        Thread.sleep(5); //until commit
+        assertAll(1, 0, 1, 1, 1, 1, 1, 1);
+    }
+    
+    private void assertAll(int added, int loaded, int prePersisted, int postPersisted,
+            int preUpdated, int postUpdated, int preRemoved, int postRemoved) {
+        assertEquals(this.added, added);
+        assertEquals(this.loaded, loaded);
+        assertEquals(this.prePersisted, prePersisted);
+        assertEquals(this.postPersisted, postPersisted);
+        assertEquals(this.preRemoved, preRemoved);
+        assertEquals(this.postRemoved, postRemoved);
+        assertEquals(this.preUpdated, preUpdated);
+        assertEquals(this.postUpdated, postUpdated);
+    }
+
+    public void postAdd(Object entity) {
+        added++;
+    }
+
+    public void postLoad(Object entity) {
+        loaded++;
+    }
+
+    public void postPersist(Object entity) {
+        postPersisted++;
+    }
+
+    public void postRemove(Object entity) {
+        postRemoved++;
+    }
+
+    public void postUpdate(Object entity) {
+        postUpdated++;
+    }
+
+    public void prePersist(Object entity) {
+        prePersisted++;
+    }
+
+    public void preRemove(Object entity) {
+        preRemoved++;
+    }
+
+    public void preUpdate(Object entity) {
+        preUpdated++;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/remote/RemoteCallbacksTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/remote/RemoteCallbacksTest.java b/cayenne-client/src/test/java/org/apache/cayenne/remote/RemoteCallbacksTest.java
deleted file mode 100644
index efecb70..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/remote/RemoteCallbacksTest.java
+++ /dev/null
@@ -1,118 +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.LifecycleListener;
-import org.apache.cayenne.ObjectContext;
-import org.apache.cayenne.testdo.mt.ClientMtLifecycles;
-import org.apache.cayenne.unit.di.client.ClientCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class RemoteCallbacksTest extends RemoteCayenneCase implements LifecycleListener {
-    private int added, loaded, prePersisted, postPersisted, preRemoved, postRemoved, preUpdated, postUpdated;
-    
-    @Override
-    public void setUpAfterInjection() throws Exception {
-        super.setUpAfterInjection();
-        
-        added = 0;
-        loaded = 0;
-        prePersisted = 0;
-        postPersisted = 0;
-        preRemoved = 0;
-        postRemoved = 0;
-        preUpdated = 0;
-        postUpdated = 0;
-    }
-    
-    public void testDefault() throws InterruptedException {
-        ObjectContext context = createROPContext();
-        context.getEntityResolver().getCallbackRegistry().addListener(ClientMtLifecycles.class, this);
-        
-        assertAll(0, 0, 0, 0, 0, 0, 0, 0);
-        ClientMtLifecycles l1 = context.newObject(ClientMtLifecycles.class);
-        
-        assertAll(1, 0, 0, 0, 0, 0, 0, 0);
-        l1.setName("x");
-        assertAll(1, 0, 0, 0, 0, 0, 0, 0);
-        
-        context.commitChanges();
-        Thread.sleep(5); //until commit
-        assertAll(1, 0, 1, 1, 0, 0, 0, 0);
-        
-        l1.setName("x2");
-        assertAll(1, 0, 1, 1, 0, 0, 0, 0);
-        
-        context.commitChanges();
-        Thread.sleep(5); //until commit
-        assertAll(1, 0, 1, 1, 1, 1, 0, 0);
-        
-        context.deleteObjects(l1);
-        assertAll(1, 0, 1, 1, 1, 1, 1, 0);
-        
-        context.commitChanges();
-        Thread.sleep(5); //until commit
-        assertAll(1, 0, 1, 1, 1, 1, 1, 1);
-    }
-    
-    private void assertAll(int added, int loaded, int prePersisted, int postPersisted,
-            int preUpdated, int postUpdated, int preRemoved, int postRemoved) {
-        assertEquals(this.added, added);
-        assertEquals(this.loaded, loaded);
-        assertEquals(this.prePersisted, prePersisted);
-        assertEquals(this.postPersisted, postPersisted);
-        assertEquals(this.preRemoved, preRemoved);
-        assertEquals(this.postRemoved, postRemoved);
-        assertEquals(this.preUpdated, preUpdated);
-        assertEquals(this.postUpdated, postUpdated);
-    }
-
-    public void postAdd(Object entity) {
-        added++;
-    }
-
-    public void postLoad(Object entity) {
-        loaded++;
-    }
-
-    public void postPersist(Object entity) {
-        postPersisted++;
-    }
-
-    public void postRemove(Object entity) {
-        postRemoved++;
-    }
-
-    public void postUpdate(Object entity) {
-        postUpdated++;
-    }
-
-    public void prePersist(Object entity) {
-        prePersisted++;
-    }
-
-    public void preRemove(Object entity) {
-        preRemoved++;
-    }
-
-    public void preUpdate(Object entity) {
-        preUpdated++;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/remote/RemoteIncrementalFaultListIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/remote/RemoteIncrementalFaultListIT.java b/cayenne-client/src/test/java/org/apache/cayenne/remote/RemoteIncrementalFaultListIT.java
new file mode 100644
index 0000000..82fe796
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/remote/RemoteIncrementalFaultListIT.java
@@ -0,0 +1,266 @@
+/*****************************************************************
+ *   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.Persistent;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.ExpressionFactory;
+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.MtTable1;
+import org.apache.cayenne.unit.di.client.ClientCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class RemoteIncrementalFaultListIT extends ClientCase {
+
+    private static final int COUNT = 25;
+
+    @Inject
+    private CayenneContext clientContext;
+
+    @Inject
+    private DBHelper dbHelper;
+
+    private TableHelper tMTTable;
+
+    private RemoteIncrementalFaultList list;
+    private SelectQuery query;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("MT_TABLE2");
+        dbHelper.deleteAll("MT_TABLE1");
+
+        tMTTable = new TableHelper(dbHelper, "MT_TABLE1");
+        tMTTable.setColumns("TABLE1_ID", "GLOBAL_ATTRIBUTE1", "SERVER_ATTRIBUTE1");
+    }
+
+    protected void createObjectsDataSet() throws Exception {
+        tMTTable.insert(1, "g1", "s1");
+        tMTTable.insert(2, "g2", "s2");
+        tMTTable.insert(3, "g3", "s3");
+        tMTTable.insert(4, "g4", "s4");
+        tMTTable.insert(5, "g5", "s5");
+        tMTTable.insert(6, "g6", "s6");
+        tMTTable.insert(7, "g7", "s7");
+        tMTTable.insert(8, "g8", "s8");
+        tMTTable.insert(9, "g9", "s9");
+        tMTTable.insert(10, "g10", "s10");
+        tMTTable.insert(11, "g11", "s11");
+        tMTTable.insert(12, "g12", "s12");
+        tMTTable.insert(13, "g13", "s13");
+        tMTTable.insert(14, "g14", "s14");
+        tMTTable.insert(15, "g15", "s15");
+        tMTTable.insert(16, "g16", "s16");
+        tMTTable.insert(17, "g17", "s17");
+        tMTTable.insert(18, "g18", "s18");
+        tMTTable.insert(19, "g19", "s19");
+        tMTTable.insert(20, "g20", "s20");
+        tMTTable.insert(21, "g21", "s21");
+        tMTTable.insert(22, "g22", "s22");
+        tMTTable.insert(23, "g23", "s23");
+        tMTTable.insert(24, "g24", "s24");
+        tMTTable.insert(25, "g25", "s25");
+    }
+
+    private void prepareList(int pageSize) throws Exception {
+
+        createObjectsDataSet();
+
+        query = new SelectQuery(ClientMtTable1.class);
+
+        // make sure total number of objects is not divisable
+        // by the page size, to test the last smaller page
+        query.setPageSize(pageSize);
+        query.addOrdering("db:" + MtTable1.TABLE1_ID_PK_COLUMN, SortOrder.ASCENDING);
+
+        list = new RemoteIncrementalFaultList(clientContext, query);
+    }
+
+    public void testSize() throws Exception {
+        prepareList(6);
+        assertEquals(COUNT, list.size());
+    }
+
+    public void testIteratorPageSize1() throws Exception {
+        doTestIterator(1);
+    }
+
+    public void testIteratorPageSize5() throws Exception {
+        // size divisiable by page size
+        doTestIterator(5);
+    }
+
+    public void testIteratorPageSize6() throws Exception {
+        // size not divisable by page size
+        doTestIterator(6);
+    }
+
+    public void testIteratorPageSize25() throws Exception {
+        // size equals to page size
+        doTestIterator(COUNT);
+    }
+
+    public void testIteratorPageSize26() throws Exception {
+        // size exceeding page size
+        doTestIterator(COUNT + 1);
+    }
+
+    public void testListIterator() throws Exception {
+        prepareList(6);
+        ListIterator<?> it = list.listIterator();
+
+        assertTrue(it.hasNext());
+
+        int counter = 0;
+        while (it.hasNext()) {
+            Object obj = it.next();
+            assertNotNull(obj);
+            assertTrue(obj instanceof Persistent);
+
+            // iterator must be resolved page by page
+            int expectedResolved = list.pageIndex(counter)
+                    * list.getPageSize()
+                    + list.getPageSize();
+            if (expectedResolved > list.size()) {
+                expectedResolved = list.size();
+            }
+
+            assertEquals(list.size() - expectedResolved, list.getUnfetchedObjects());
+
+            counter++;
+        }
+    }
+
+    public void testUnfetchedObjects() throws Exception {
+        prepareList(6);
+        assertEquals(COUNT - 6, list.getUnfetchedObjects());
+        list.get(7);
+        assertEquals(COUNT - 12, list.getUnfetchedObjects());
+        list.resolveAll();
+        assertEquals(0, list.getUnfetchedObjects());
+    }
+
+    public void testPageIndex() throws Exception {
+        prepareList(6);
+        assertEquals(0, list.pageIndex(0));
+        assertEquals(0, list.pageIndex(1));
+        assertEquals(1, list.pageIndex(6));
+
+        try {
+            assertEquals(13, list.pageIndex(82));
+            fail("Element index beyound array size must throw an IndexOutOfBoundsException.");
+        }
+        catch (IndexOutOfBoundsException ex) {
+            // exception expercted
+        }
+    }
+
+    public void testPagesRead1() throws Exception {
+        prepareList(6);
+        assertTrue(list.elements.get(0) instanceof ClientMtTable1);
+        assertSame(RemoteIncrementalFaultList.PLACEHOLDER, list.elements.get(8));
+
+        list.resolveInterval(5, 10);
+        assertTrue(list.elements.get(7) instanceof ClientMtTable1);
+
+        list.resolveAll();
+        assertTrue((list.elements.get(list.size() - 1)) instanceof ClientMtTable1);
+    }
+
+    public void testGet1() throws Exception {
+        prepareList(6);
+        assertTrue(list.elements.get(0) instanceof ClientMtTable1);
+        assertSame(RemoteIncrementalFaultList.PLACEHOLDER, list.elements.get(8));
+
+        Object a = list.get(8);
+
+        assertNotNull(a);
+        assertTrue(a instanceof ClientMtTable1);
+        assertTrue(list.elements.get(8) instanceof ClientMtTable1);
+    }
+
+    public void testIndexOf() throws Exception {
+        prepareList(6);
+
+        Expression qual = ExpressionFactory.matchExp(
+                ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY,
+                "g20");
+        SelectQuery query = new SelectQuery(ClientMtTable1.class, qual);
+        List<?> artists = list.context.performQuery(query);
+
+        assertEquals(1, artists.size());
+
+        ClientMtTable1 row = (ClientMtTable1) artists.get(0);
+        assertEquals(19, list.indexOf(row));
+        assertEquals(-1, list.indexOf(list.context.newObject(ClientMtTable1.class)));
+    }
+
+    public void testLastIndexOf() throws Exception {
+        prepareList(6);
+        Expression qual = ExpressionFactory.matchExp(
+                ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY,
+                "g20");
+        SelectQuery query = new SelectQuery(ClientMtTable1.class, qual);
+        List<?> objects = list.context.performQuery(query);
+
+        assertEquals(1, objects.size());
+
+        ClientMtTable1 row = (ClientMtTable1) objects.get(0);
+        assertEquals(19, list.lastIndexOf(row));
+        assertEquals(-1, list.lastIndexOf(list.context.newObject(ClientMtTable1.class)));
+    }
+
+    private void doTestIterator(int size) throws Exception {
+        prepareList(size);
+        Iterator<?> it = list.iterator();
+
+        assertTrue(it.hasNext());
+
+        int counter = 0;
+        while (it.hasNext()) {
+            Object obj = it.next();
+            assertNotNull(obj);
+            assertTrue(obj instanceof Persistent);
+
+            // iterator must be resolved page by page
+            int expectedResolved = list.pageIndex(counter)
+                    * list.getPageSize()
+                    + list.getPageSize();
+            if (expectedResolved > list.size()) {
+                expectedResolved = list.size();
+            }
+
+            assertEquals(list.size() - expectedResolved, list.getUnfetchedObjects());
+
+            counter++;
+        }
+    }
+}


[3/8] Rename Integration Tests in cayenne-client (*IT.java instead of *Test.java)

Posted by aa...@apache.org.
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;
+        }
+    }
+}


[7/8] git commit: Rename Integration Tests in cayenne-client (*IT.java instead of *Test.java)

Posted by aa...@apache.org.
Rename Integration Tests in cayenne-client (*IT.java instead of *Test.java)


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

Branch: refs/heads/master
Commit: fcb1d5364154294525f1c2087f280cc5d38879f3
Parents: ec5c3cf
Author: Savva Kolbechev <s....@gmail.com>
Authored: Wed Oct 29 16:53:38 2014 +0300
Committer: Savva Kolbechev <s....@gmail.com>
Committed: Thu Oct 30 16:41:59 2014 +0300

----------------------------------------------------------------------
 .../apache/cayenne/CayenneContextCayenneIT.java |  55 ++
 .../cayenne/CayenneContextCayenneTest.java      |  55 --
 .../CayenneContextClientChannelEventsIT.java    | 345 ++++++++
 .../CayenneContextClientChannelEventsTest.java  | 345 --------
 .../cayenne/CayenneContextDeleteRulesIT.java    | 111 +++
 .../cayenne/CayenneContextDeleteRulesTest.java  | 111 ---
 .../apache/cayenne/CayenneContextEJBQLIT.java   |  87 ++
 .../apache/cayenne/CayenneContextEJBQLTest.java |  87 --
 .../CayenneContextGraphDiffCompressorIT.java    |  96 +++
 .../CayenneContextGraphDiffCompressorTest.java  |  96 ---
 .../org/apache/cayenne/CayenneContextIT.java    | 351 ++++++++
 .../cayenne/CayenneContextInheritanceIT.java    | 151 ++++
 .../cayenne/CayenneContextInheritanceTest.java  | 151 ----
 .../CayenneContextMapRelationshipIT.java        | 112 +++
 .../CayenneContextMapRelationshipTest.java      | 112 ---
 .../cayenne/CayenneContextMergeHandlerIT.java   |  90 ++
 .../cayenne/CayenneContextMergeHandlerTest.java |  90 --
 .../CayenneContextNamedQueryCachingIT.java      | 133 +++
 .../CayenneContextNamedQueryCachingTest.java    | 133 ---
 .../CayenneContextPaginatedListCachingIT.java   |  75 ++
 .../CayenneContextPaginatedListCachingTest.java |  75 --
 .../cayenne/CayenneContextPrimitiveIT.java      | 100 +++
 .../cayenne/CayenneContextPrimitiveTest.java    | 100 ---
 .../cayenne/CayenneContextRefreshQueryIT.java   |  76 ++
 .../cayenne/CayenneContextRefreshQueryTest.java |  76 --
 .../cayenne/CayenneContextRelationshipsIT.java  | 100 +++
 .../CayenneContextRelationshipsTest.java        | 100 ---
 .../cayenne/CayenneContextSQLTemplateIT.java    |  54 ++
 .../cayenne/CayenneContextSQLTemplateTest.java  |  54 --
 .../cayenne/CayenneContextServerDiffsIT.java    | 153 ++++
 .../cayenne/CayenneContextServerDiffsTest.java  | 153 ----
 .../org/apache/cayenne/CayenneContextTest.java  | 351 --------
 .../cayenne/CayenneContextValidationIT.java     |  89 ++
 .../cayenne/CayenneContextValidationTest.java   |  89 --
 .../CayenneContextWithDataContextIT.java        | 570 ++++++++++++
 .../CayenneContextWithDataContextTest.java      | 570 ------------
 .../apache/cayenne/NestedCayenneContextIT.java  | 864 +++++++++++++++++++
 .../cayenne/NestedCayenneContextTest.java       | 864 -------------------
 .../cayenne/PersistentObjectInContextIT.java    | 142 +++
 .../cayenne/PersistentObjectInContextTest.java  | 142 ---
 .../cayenne/access/ClientServerChannelIT.java   | 260 ++++++
 .../access/ClientServerChannelQueryIT.java      | 239 +++++
 .../access/ClientServerChannelQueryTest.java    | 239 -----
 .../cayenne/access/ClientServerChannelTest.java | 260 ------
 .../cayenne/map/ClientEntityResolverIT.java     |  62 ++
 .../cayenne/map/ClientEntityResolverTest.java   |  62 --
 .../cayenne/query/ClientExpressionIT.java       | 319 +++++++
 .../cayenne/query/ClientExpressionTest.java     | 319 -------
 .../query/ClientSelectQueryExpressionIT.java    |  71 ++
 .../query/ClientSelectQueryExpressionTest.java  |  71 --
 .../remote/CayenneContextDeletionIT.java        |  38 +
 .../remote/CayenneContextDeletionTest.java      |  38 -
 .../remote/ClientChannelServerDiffsIT.java      | 263 ++++++
 .../remote/ClientChannelServerDiffsTest.java    | 263 ------
 .../cayenne/remote/LightSuperClassIT.java       |  95 ++
 .../cayenne/remote/LightSuperClassTest.java     |  95 --
 .../remote/NestedObjectContextLocalIT.java      |  58 ++
 .../remote/NestedObjectContextLocalTest.java    |  58 --
 .../NestedObjectContextParentEventsIT.java      |  64 ++
 .../NestedObjectContextParentEventsTest.java    |  64 --
 .../remote/NestedObjectContextPeerEventsIT.java | 149 ++++
 .../NestedObjectContextPeerEventsTest.java      | 149 ----
 .../remote/NestedObjectContextRollbackIT.java   |  71 ++
 .../remote/NestedObjectContextRollbackTest.java |  71 --
 .../cayenne/remote/ROPPrefetchToManyMapIT.java  |  70 ++
 .../remote/ROPPrefetchToManyMapTest.java        |  70 --
 .../cayenne/remote/RelationshipChangeIT.java    |  60 ++
 .../cayenne/remote/RelationshipChangeTest.java  |  60 --
 .../cayenne/remote/RemoteCallbacksIT.java       | 118 +++
 .../cayenne/remote/RemoteCallbacksTest.java     | 118 ---
 .../remote/RemoteIncrementalFaultListIT.java    | 266 ++++++
 .../remote/RemoteIncrementalFaultListTest.java  | 266 ------
 .../apache/cayenne/remote/RemoteRollbackIT.java | 147 ++++
 .../cayenne/remote/RemoteRollbackTest.java      | 147 ----
 .../apache/cayenne/remote/ValueInjectorIT.java  |  73 ++
 .../cayenne/remote/ValueInjectorTest.java       |  73 --
 .../unit/di/client/ClientCaseSelfIT.java        |  46 +
 .../unit/di/client/ClientCaseSelfTest.java      |  46 -
 .../cayenne/util/ObjectDetachOperationIT.java   | 112 +++
 .../cayenne/util/ObjectDetachOperationTest.java | 112 ---
 .../util/ShallowMergeOperation_ClientIT.java    | 210 +++++
 .../util/ShallowMergeOperation_ClientTest.java  | 210 -----
 82 files changed, 6545 insertions(+), 6545 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextCayenneIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextCayenneIT.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextCayenneIT.java
new file mode 100644
index 0000000..31c9d97
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextCayenneIT.java
@@ -0,0 +1,55 @@
+/*****************************************************************
+ *   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;
+
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.query.SQLTemplate;
+import org.apache.cayenne.test.jdbc.DBHelper;
+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 CayenneContextCayenneIT extends ClientCase {
+
+    @Inject
+    private DBHelper dbHelper;
+
+    @Inject
+    private CayenneContext context;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("MT_TABLE2");
+        dbHelper.deleteAll("MT_TABLE1");
+    }
+
+    public void testObjectForPK() throws Exception {
+
+        context.performGenericQuery(new SQLTemplate(
+                ClientMtTable1.class,
+                "insert into MT_TABLE1 "
+                        + "(TABLE1_ID, GLOBAL_ATTRIBUTE1, SERVER_ATTRIBUTE1) "
+                        + "values (1, 'g1', 's1')"));
+
+        ClientMtTable1 o = Cayenne.objectForPK(context, ClientMtTable1.class, 1);
+        assertNotNull(o);
+        assertEquals("g1", o.getGlobalAttribute1());
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextCayenneTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextCayenneTest.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextCayenneTest.java
deleted file mode 100644
index b3d8c89..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextCayenneTest.java
+++ /dev/null
@@ -1,55 +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;
-
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.query.SQLTemplate;
-import org.apache.cayenne.test.jdbc.DBHelper;
-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 CayenneContextCayenneTest extends ClientCase {
-
-    @Inject
-    private DBHelper dbHelper;
-
-    @Inject
-    private CayenneContext context;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("MT_TABLE2");
-        dbHelper.deleteAll("MT_TABLE1");
-    }
-
-    public void testObjectForPK() throws Exception {
-
-        context.performGenericQuery(new SQLTemplate(
-                ClientMtTable1.class,
-                "insert into MT_TABLE1 "
-                        + "(TABLE1_ID, GLOBAL_ATTRIBUTE1, SERVER_ATTRIBUTE1) "
-                        + "values (1, 'g1', 's1')"));
-
-        ClientMtTable1 o = Cayenne.objectForPK(context, ClientMtTable1.class, 1);
-        assertNotNull(o);
-        assertEquals("g1", o.getGlobalAttribute1());
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextClientChannelEventsIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextClientChannelEventsIT.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextClientChannelEventsIT.java
new file mode 100644
index 0000000..c4af230
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextClientChannelEventsIT.java
@@ -0,0 +1,345 @@
+/*****************************************************************
+ *   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;
+
+import org.apache.cayenne.configuration.Constants;
+import org.apache.cayenne.configuration.rop.client.ClientRuntime;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.query.ObjectIdQuery;
+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.testdo.mt.ClientMtTable4;
+import org.apache.cayenne.testdo.mt.ClientMtTable5;
+import org.apache.cayenne.unit.di.client.ClientCase;
+import org.apache.cayenne.unit.di.client.ClientRuntimeProperty;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+/**
+ * Tests peer context synchronization via ClientChannel events.
+ */
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+@ClientRuntimeProperty({
+        Constants.ROP_CHANNEL_EVENTS_PROPERTY, "true"
+})
+public class CayenneContextClientChannelEventsIT extends ClientCase {
+
+    @Inject
+    private DBHelper dbHelper;
+
+    @Inject
+    private ClientRuntime runtime;
+
+    private TableHelper tMtTable1;
+    private TableHelper tMtTable2;
+    private TableHelper tMtTable4;
+    private TableHelper tMtTable5;
+    private TableHelper tMtJoin45;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("MT_TABLE2");
+        dbHelper.deleteAll("MT_TABLE1");
+        dbHelper.deleteAll("MT_JOIN45");
+        dbHelper.deleteAll("MT_TABLE4");
+        dbHelper.deleteAll("MT_TABLE5");
+
+        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");
+
+        tMtTable4 = new TableHelper(dbHelper, "MT_TABLE4");
+        tMtTable4.setColumns("ID");
+
+        tMtTable5 = new TableHelper(dbHelper, "MT_TABLE5");
+        tMtTable5.setColumns("ID");
+
+        tMtJoin45 = new TableHelper(dbHelper, "MT_JOIN45");
+        tMtJoin45.setColumns("TABLE4_ID", "TABLE5_ID");
+    }
+
+    public void testSyncNewObject() throws Exception {
+
+        CayenneContext c1 = (CayenneContext) runtime.newContext();
+        CayenneContext c2 = (CayenneContext) runtime.newContext();
+        assertNotSame(c1, c2);
+
+        ClientMtTable1 o1 = c1.newObject(ClientMtTable1.class);
+        o1.setGlobalAttribute1("X");
+        c1.commitChanges();
+
+        ClientMtTable1 o2 = (ClientMtTable1) c2.getGraphManager().getNode(
+                o1.getObjectId());
+
+        assertNull(o2);
+        // now fetch it fresh
+
+        o2 = (ClientMtTable1) c2.performQuery(new ObjectIdQuery(o1.getObjectId())).get(0);
+        assertNotNull(o2);
+
+        assertEquals("X", o2.getGlobalAttribute1());
+        assertEquals(PersistenceState.COMMITTED, o2.getPersistenceState());
+        assertFalse(c1.internalGraphManager().hasChanges());
+        assertFalse(c2.internalGraphManager().hasChanges());
+    }
+
+    public void testSyncNewDeletedObject() throws Exception {
+
+        CayenneContext c1 = (CayenneContext) runtime.newContext();
+        CayenneContext c2 = (CayenneContext) runtime.newContext();
+        assertNotSame(c1, c2);
+
+        // insert, then delete - this shouldn't propagate via an event.
+        ClientMtTable1 o1 = c1.newObject(ClientMtTable1.class);
+        o1.setGlobalAttribute1("X");
+        c1.deleteObjects(o1);
+
+        // introduce some other change so that commit can go ahead...
+        ClientMtTable1 o1x = c1.newObject(ClientMtTable1.class);
+        o1x.setGlobalAttribute1("Y");
+        c1.commitChanges();
+
+        ClientMtTable1 o2 = (ClientMtTable1) c2.getGraphManager().getNode(
+                o1.getObjectId());
+
+        assertNull(o2);
+
+        assertFalse(c1.internalGraphManager().hasChanges());
+        assertFalse(c2.internalGraphManager().hasChanges());
+    }
+
+    public void testSyncNewObjectIntoDirtyContext() throws Exception {
+
+        CayenneContext c1 = (CayenneContext) runtime.newContext();
+        CayenneContext c2 = (CayenneContext) runtime.newContext();
+        assertNotSame(c1, c2);
+
+        // make sure c2 has uncommitted changes
+        c2.newObject(ClientMtTable1.class);
+
+        ClientMtTable1 o1 = c1.newObject(ClientMtTable1.class);
+        o1.setGlobalAttribute1("X");
+        c1.commitChanges();
+
+        ClientMtTable1 o2 = (ClientMtTable1) c2.getGraphManager().getNode(
+                o1.getObjectId());
+        assertNull(o2);
+
+        // now fetch it fresh
+
+        o2 = (ClientMtTable1) c2.performQuery(new ObjectIdQuery(o1.getObjectId())).get(0);
+        assertNotNull(o2);
+        assertEquals("X", o2.getGlobalAttribute1());
+        assertEquals(PersistenceState.COMMITTED, o2.getPersistenceState());
+        assertFalse(c1.internalGraphManager().hasChanges());
+        assertTrue(c2.internalGraphManager().hasChanges());
+    }
+
+    public void testSyncSimpleProperty() throws Exception {
+
+        tMtTable1.insert(1, "g1", "s1");
+
+        CayenneContext c1 = (CayenneContext) runtime.newContext();
+        CayenneContext c2 = (CayenneContext) runtime.newContext();
+        assertNotSame(c1, c2);
+
+        ClientMtTable1 o1 = (ClientMtTable1) Cayenne.objectForQuery(
+                c1,
+                new ObjectIdQuery(new ObjectId("MtTable1", "TABLE1_ID", 1)));
+
+        ClientMtTable1 o2 = (ClientMtTable1) Cayenne.objectForQuery(
+                c2,
+                new ObjectIdQuery(new ObjectId("MtTable1", "TABLE1_ID", 1)));
+
+        assertEquals("g1", o1.getGlobalAttribute1());
+        assertEquals("g1", o2.getGlobalAttribute1());
+
+        o1.setGlobalAttribute1("X");
+        c1.commitChanges();
+        
+        // let the events propagate to peers
+        Thread.sleep(500);
+
+        assertEquals("X", o2.getGlobalAttribute1());
+        assertFalse(c1.internalGraphManager().hasChanges());
+        assertFalse(c2.internalGraphManager().hasChanges());
+    }
+
+    public void testSyncToOneRelationship() throws Exception {
+
+        tMtTable1.insert(1, "g1", "s1");
+        tMtTable1.insert(2, "g2", "s2");
+        tMtTable2.insert(1, 1, "g1");
+
+        CayenneContext c1 = (CayenneContext) runtime.newContext();
+        CayenneContext c2 = (CayenneContext) runtime.newContext();
+
+        ClientMtTable2 o1 = (ClientMtTable2) Cayenne.objectForQuery(
+                c1,
+                new ObjectIdQuery(new ObjectId("MtTable2", "TABLE2_ID", 1)));
+
+        ClientMtTable2 o2 = (ClientMtTable2) Cayenne.objectForQuery(
+                c2,
+                new ObjectIdQuery(new ObjectId("MtTable2", "TABLE2_ID", 1)));
+
+        assertEquals("g1", o1.getTable1().getGlobalAttribute1());
+        assertEquals("g1", o2.getTable1().getGlobalAttribute1());
+
+        ClientMtTable1 o1r = (ClientMtTable1) Cayenne.objectForQuery(
+                c1,
+                new ObjectIdQuery(new ObjectId("MtTable1", "TABLE1_ID", 2)));
+        o1.setTable1(o1r);
+        c1.commitChanges();
+        
+        // let the events propagate to peers
+        Thread.sleep(500);
+
+        assertEquals("g2", o2.getTable1().getGlobalAttribute1());
+        assertEquals(o1r.getObjectId(), o2.getTable1().getObjectId());
+        assertFalse(c1.internalGraphManager().hasChanges());
+        assertFalse(c2.internalGraphManager().hasChanges());
+    }
+
+    public void testSyncToManyRelationship() throws Exception {
+        tMtTable1.insert(1, "g1", "s1");
+        tMtTable2.insert(1, 1, "g1");
+
+        CayenneContext c1 = (CayenneContext) runtime.newContext();
+        CayenneContext c2 = (CayenneContext) runtime.newContext();
+
+        ClientMtTable1 o1 = (ClientMtTable1) Cayenne.objectForQuery(
+                c1,
+                new ObjectIdQuery(new ObjectId("MtTable1", "TABLE1_ID", 1)));
+
+        ClientMtTable1 o2 = (ClientMtTable1) Cayenne.objectForQuery(
+                c2,
+                new ObjectIdQuery(new ObjectId("MtTable1", "TABLE1_ID", 1)));
+
+        assertEquals(1, o1.getTable2Array().size());
+        assertEquals(1, o2.getTable2Array().size());
+
+        ClientMtTable2 o1r = c1.newObject(ClientMtTable2.class);
+        o1r.setGlobalAttribute("X");
+        o1.addToTable2Array(o1r);
+
+        c1.commitChanges();
+        
+        // let the events propagate to peers
+        Thread.sleep(500);
+
+        assertEquals(2, o1.getTable2Array().size());
+        assertEquals(2, o2.getTable2Array().size());
+        assertFalse(c1.internalGraphManager().hasChanges());
+        assertFalse(c2.internalGraphManager().hasChanges());
+    }
+
+    public void testSyncToManyRelationship1() throws Exception {
+        tMtTable1.insert(1, "g1", "s1");
+        tMtTable2.insert(1, 1, "g1");
+
+        CayenneContext c1 = (CayenneContext) runtime.newContext();
+        CayenneContext c2 = (CayenneContext) runtime.newContext();
+
+        ClientMtTable1 o1 = (ClientMtTable1) Cayenne.objectForQuery(
+                c1,
+                new ObjectIdQuery(new ObjectId("MtTable1", "TABLE1_ID", 1)));
+
+        // do not resolve objects in question in the second context and see if the merge
+        // causes any issues...
+
+        assertEquals(1, o1.getTable2Array().size());
+
+        ClientMtTable2 o1r = c1.newObject(ClientMtTable2.class);
+        o1r.setGlobalAttribute("X");
+        o1.addToTable2Array(o1r);
+
+        c1.commitChanges();
+
+        assertEquals(2, o1.getTable2Array().size());
+
+        assertFalse(c1.internalGraphManager().hasChanges());
+        assertFalse(c2.internalGraphManager().hasChanges());
+
+        ClientMtTable1 o2 = (ClientMtTable1) Cayenne.objectForQuery(
+                c2,
+                new ObjectIdQuery(new ObjectId("MtTable1", "TABLE1_ID", 1)));
+        assertEquals(2, o2.getTable2Array().size());
+    }
+
+    public void testSyncManyToManyRelationship() throws Exception {
+        tMtTable4.insert(1);
+        tMtTable5.insert(1);
+        tMtTable5.insert(2);
+        tMtJoin45.insert(1, 1);
+        tMtJoin45.insert(1, 2);
+
+        CayenneContext c1 = (CayenneContext) runtime.newContext();
+        CayenneContext c2 = (CayenneContext) runtime.newContext();
+
+        ClientMtTable4 o1 = (ClientMtTable4) Cayenne.objectForQuery(
+                c1,
+                new ObjectIdQuery(new ObjectId("MtTable4", "ID", 1)));
+
+        ClientMtTable4 o2 = (ClientMtTable4) Cayenne.objectForQuery(
+                c2,
+                new ObjectIdQuery(new ObjectId("MtTable4", "ID", 1)));
+
+        assertEquals(2, o1.getTable5s().size());
+        assertEquals(2, o2.getTable5s().size());
+
+        ClientMtTable5 o1r = (ClientMtTable5) Cayenne.objectForQuery(
+                c1,
+                new ObjectIdQuery(new ObjectId("MtTable5", "ID", 1)));
+        o1.removeFromTable5s(o1r);
+
+        c1.commitChanges();
+        // let the events propagate to peers
+        Thread.sleep(500);
+
+        assertEquals(1, o1.getTable5s().size());
+        assertEquals(1, o2.getTable5s().size());
+        assertFalse(c1.internalGraphManager().hasChanges());
+        assertFalse(c2.internalGraphManager().hasChanges());
+    }
+
+    public void testSyncManyToManyRelationship1() throws Exception {
+
+        CayenneContext c1 = (CayenneContext) runtime.newContext();
+        CayenneContext c2 = (CayenneContext) runtime.newContext();
+
+        ClientMtTable4 o1 = c1.newObject(ClientMtTable4.class);
+        ClientMtTable5 o1r = c1.newObject(ClientMtTable5.class);
+        c1.commitChanges();
+
+        ClientMtTable4 o2 = c2.localObject(o1);
+        ClientMtTable5 o2r = c2.localObject(o1r);
+
+        o2.addToTable5s(o2r);
+        c2.commitChanges();
+
+        assertEquals(1, o1.getTable5s().size());
+        assertEquals(1, o2.getTable5s().size());
+        assertFalse(c1.internalGraphManager().hasChanges());
+        assertFalse(c2.internalGraphManager().hasChanges());
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextClientChannelEventsTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextClientChannelEventsTest.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextClientChannelEventsTest.java
deleted file mode 100644
index 6b4238e..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextClientChannelEventsTest.java
+++ /dev/null
@@ -1,345 +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;
-
-import org.apache.cayenne.configuration.Constants;
-import org.apache.cayenne.configuration.rop.client.ClientRuntime;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.query.ObjectIdQuery;
-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.testdo.mt.ClientMtTable4;
-import org.apache.cayenne.testdo.mt.ClientMtTable5;
-import org.apache.cayenne.unit.di.client.ClientCase;
-import org.apache.cayenne.unit.di.client.ClientRuntimeProperty;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-/**
- * Tests peer context synchronization via ClientChannel events.
- */
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-@ClientRuntimeProperty({
-        Constants.ROP_CHANNEL_EVENTS_PROPERTY, "true"
-})
-public class CayenneContextClientChannelEventsTest extends ClientCase {
-
-    @Inject
-    private DBHelper dbHelper;
-
-    @Inject
-    private ClientRuntime runtime;
-
-    private TableHelper tMtTable1;
-    private TableHelper tMtTable2;
-    private TableHelper tMtTable4;
-    private TableHelper tMtTable5;
-    private TableHelper tMtJoin45;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("MT_TABLE2");
-        dbHelper.deleteAll("MT_TABLE1");
-        dbHelper.deleteAll("MT_JOIN45");
-        dbHelper.deleteAll("MT_TABLE4");
-        dbHelper.deleteAll("MT_TABLE5");
-
-        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");
-
-        tMtTable4 = new TableHelper(dbHelper, "MT_TABLE4");
-        tMtTable4.setColumns("ID");
-
-        tMtTable5 = new TableHelper(dbHelper, "MT_TABLE5");
-        tMtTable5.setColumns("ID");
-
-        tMtJoin45 = new TableHelper(dbHelper, "MT_JOIN45");
-        tMtJoin45.setColumns("TABLE4_ID", "TABLE5_ID");
-    }
-
-    public void testSyncNewObject() throws Exception {
-
-        CayenneContext c1 = (CayenneContext) runtime.newContext();
-        CayenneContext c2 = (CayenneContext) runtime.newContext();
-        assertNotSame(c1, c2);
-
-        ClientMtTable1 o1 = c1.newObject(ClientMtTable1.class);
-        o1.setGlobalAttribute1("X");
-        c1.commitChanges();
-
-        ClientMtTable1 o2 = (ClientMtTable1) c2.getGraphManager().getNode(
-                o1.getObjectId());
-
-        assertNull(o2);
-        // now fetch it fresh
-
-        o2 = (ClientMtTable1) c2.performQuery(new ObjectIdQuery(o1.getObjectId())).get(0);
-        assertNotNull(o2);
-
-        assertEquals("X", o2.getGlobalAttribute1());
-        assertEquals(PersistenceState.COMMITTED, o2.getPersistenceState());
-        assertFalse(c1.internalGraphManager().hasChanges());
-        assertFalse(c2.internalGraphManager().hasChanges());
-    }
-
-    public void testSyncNewDeletedObject() throws Exception {
-
-        CayenneContext c1 = (CayenneContext) runtime.newContext();
-        CayenneContext c2 = (CayenneContext) runtime.newContext();
-        assertNotSame(c1, c2);
-
-        // insert, then delete - this shouldn't propagate via an event.
-        ClientMtTable1 o1 = c1.newObject(ClientMtTable1.class);
-        o1.setGlobalAttribute1("X");
-        c1.deleteObjects(o1);
-
-        // introduce some other change so that commit can go ahead...
-        ClientMtTable1 o1x = c1.newObject(ClientMtTable1.class);
-        o1x.setGlobalAttribute1("Y");
-        c1.commitChanges();
-
-        ClientMtTable1 o2 = (ClientMtTable1) c2.getGraphManager().getNode(
-                o1.getObjectId());
-
-        assertNull(o2);
-
-        assertFalse(c1.internalGraphManager().hasChanges());
-        assertFalse(c2.internalGraphManager().hasChanges());
-    }
-
-    public void testSyncNewObjectIntoDirtyContext() throws Exception {
-
-        CayenneContext c1 = (CayenneContext) runtime.newContext();
-        CayenneContext c2 = (CayenneContext) runtime.newContext();
-        assertNotSame(c1, c2);
-
-        // make sure c2 has uncommitted changes
-        c2.newObject(ClientMtTable1.class);
-
-        ClientMtTable1 o1 = c1.newObject(ClientMtTable1.class);
-        o1.setGlobalAttribute1("X");
-        c1.commitChanges();
-
-        ClientMtTable1 o2 = (ClientMtTable1) c2.getGraphManager().getNode(
-                o1.getObjectId());
-        assertNull(o2);
-
-        // now fetch it fresh
-
-        o2 = (ClientMtTable1) c2.performQuery(new ObjectIdQuery(o1.getObjectId())).get(0);
-        assertNotNull(o2);
-        assertEquals("X", o2.getGlobalAttribute1());
-        assertEquals(PersistenceState.COMMITTED, o2.getPersistenceState());
-        assertFalse(c1.internalGraphManager().hasChanges());
-        assertTrue(c2.internalGraphManager().hasChanges());
-    }
-
-    public void testSyncSimpleProperty() throws Exception {
-
-        tMtTable1.insert(1, "g1", "s1");
-
-        CayenneContext c1 = (CayenneContext) runtime.newContext();
-        CayenneContext c2 = (CayenneContext) runtime.newContext();
-        assertNotSame(c1, c2);
-
-        ClientMtTable1 o1 = (ClientMtTable1) Cayenne.objectForQuery(
-                c1,
-                new ObjectIdQuery(new ObjectId("MtTable1", "TABLE1_ID", 1)));
-
-        ClientMtTable1 o2 = (ClientMtTable1) Cayenne.objectForQuery(
-                c2,
-                new ObjectIdQuery(new ObjectId("MtTable1", "TABLE1_ID", 1)));
-
-        assertEquals("g1", o1.getGlobalAttribute1());
-        assertEquals("g1", o2.getGlobalAttribute1());
-
-        o1.setGlobalAttribute1("X");
-        c1.commitChanges();
-        
-        // let the events propagate to peers
-        Thread.sleep(500);
-
-        assertEquals("X", o2.getGlobalAttribute1());
-        assertFalse(c1.internalGraphManager().hasChanges());
-        assertFalse(c2.internalGraphManager().hasChanges());
-    }
-
-    public void testSyncToOneRelationship() throws Exception {
-
-        tMtTable1.insert(1, "g1", "s1");
-        tMtTable1.insert(2, "g2", "s2");
-        tMtTable2.insert(1, 1, "g1");
-
-        CayenneContext c1 = (CayenneContext) runtime.newContext();
-        CayenneContext c2 = (CayenneContext) runtime.newContext();
-
-        ClientMtTable2 o1 = (ClientMtTable2) Cayenne.objectForQuery(
-                c1,
-                new ObjectIdQuery(new ObjectId("MtTable2", "TABLE2_ID", 1)));
-
-        ClientMtTable2 o2 = (ClientMtTable2) Cayenne.objectForQuery(
-                c2,
-                new ObjectIdQuery(new ObjectId("MtTable2", "TABLE2_ID", 1)));
-
-        assertEquals("g1", o1.getTable1().getGlobalAttribute1());
-        assertEquals("g1", o2.getTable1().getGlobalAttribute1());
-
-        ClientMtTable1 o1r = (ClientMtTable1) Cayenne.objectForQuery(
-                c1,
-                new ObjectIdQuery(new ObjectId("MtTable1", "TABLE1_ID", 2)));
-        o1.setTable1(o1r);
-        c1.commitChanges();
-        
-        // let the events propagate to peers
-        Thread.sleep(500);
-
-        assertEquals("g2", o2.getTable1().getGlobalAttribute1());
-        assertEquals(o1r.getObjectId(), o2.getTable1().getObjectId());
-        assertFalse(c1.internalGraphManager().hasChanges());
-        assertFalse(c2.internalGraphManager().hasChanges());
-    }
-
-    public void testSyncToManyRelationship() throws Exception {
-        tMtTable1.insert(1, "g1", "s1");
-        tMtTable2.insert(1, 1, "g1");
-
-        CayenneContext c1 = (CayenneContext) runtime.newContext();
-        CayenneContext c2 = (CayenneContext) runtime.newContext();
-
-        ClientMtTable1 o1 = (ClientMtTable1) Cayenne.objectForQuery(
-                c1,
-                new ObjectIdQuery(new ObjectId("MtTable1", "TABLE1_ID", 1)));
-
-        ClientMtTable1 o2 = (ClientMtTable1) Cayenne.objectForQuery(
-                c2,
-                new ObjectIdQuery(new ObjectId("MtTable1", "TABLE1_ID", 1)));
-
-        assertEquals(1, o1.getTable2Array().size());
-        assertEquals(1, o2.getTable2Array().size());
-
-        ClientMtTable2 o1r = c1.newObject(ClientMtTable2.class);
-        o1r.setGlobalAttribute("X");
-        o1.addToTable2Array(o1r);
-
-        c1.commitChanges();
-        
-        // let the events propagate to peers
-        Thread.sleep(500);
-
-        assertEquals(2, o1.getTable2Array().size());
-        assertEquals(2, o2.getTable2Array().size());
-        assertFalse(c1.internalGraphManager().hasChanges());
-        assertFalse(c2.internalGraphManager().hasChanges());
-    }
-
-    public void testSyncToManyRelationship1() throws Exception {
-        tMtTable1.insert(1, "g1", "s1");
-        tMtTable2.insert(1, 1, "g1");
-
-        CayenneContext c1 = (CayenneContext) runtime.newContext();
-        CayenneContext c2 = (CayenneContext) runtime.newContext();
-
-        ClientMtTable1 o1 = (ClientMtTable1) Cayenne.objectForQuery(
-                c1,
-                new ObjectIdQuery(new ObjectId("MtTable1", "TABLE1_ID", 1)));
-
-        // do not resolve objects in question in the second context and see if the merge
-        // causes any issues...
-
-        assertEquals(1, o1.getTable2Array().size());
-
-        ClientMtTable2 o1r = c1.newObject(ClientMtTable2.class);
-        o1r.setGlobalAttribute("X");
-        o1.addToTable2Array(o1r);
-
-        c1.commitChanges();
-
-        assertEquals(2, o1.getTable2Array().size());
-
-        assertFalse(c1.internalGraphManager().hasChanges());
-        assertFalse(c2.internalGraphManager().hasChanges());
-
-        ClientMtTable1 o2 = (ClientMtTable1) Cayenne.objectForQuery(
-                c2,
-                new ObjectIdQuery(new ObjectId("MtTable1", "TABLE1_ID", 1)));
-        assertEquals(2, o2.getTable2Array().size());
-    }
-
-    public void testSyncManyToManyRelationship() throws Exception {
-        tMtTable4.insert(1);
-        tMtTable5.insert(1);
-        tMtTable5.insert(2);
-        tMtJoin45.insert(1, 1);
-        tMtJoin45.insert(1, 2);
-
-        CayenneContext c1 = (CayenneContext) runtime.newContext();
-        CayenneContext c2 = (CayenneContext) runtime.newContext();
-
-        ClientMtTable4 o1 = (ClientMtTable4) Cayenne.objectForQuery(
-                c1,
-                new ObjectIdQuery(new ObjectId("MtTable4", "ID", 1)));
-
-        ClientMtTable4 o2 = (ClientMtTable4) Cayenne.objectForQuery(
-                c2,
-                new ObjectIdQuery(new ObjectId("MtTable4", "ID", 1)));
-
-        assertEquals(2, o1.getTable5s().size());
-        assertEquals(2, o2.getTable5s().size());
-
-        ClientMtTable5 o1r = (ClientMtTable5) Cayenne.objectForQuery(
-                c1,
-                new ObjectIdQuery(new ObjectId("MtTable5", "ID", 1)));
-        o1.removeFromTable5s(o1r);
-
-        c1.commitChanges();
-        // let the events propagate to peers
-        Thread.sleep(500);
-
-        assertEquals(1, o1.getTable5s().size());
-        assertEquals(1, o2.getTable5s().size());
-        assertFalse(c1.internalGraphManager().hasChanges());
-        assertFalse(c2.internalGraphManager().hasChanges());
-    }
-
-    public void testSyncManyToManyRelationship1() throws Exception {
-
-        CayenneContext c1 = (CayenneContext) runtime.newContext();
-        CayenneContext c2 = (CayenneContext) runtime.newContext();
-
-        ClientMtTable4 o1 = c1.newObject(ClientMtTable4.class);
-        ClientMtTable5 o1r = c1.newObject(ClientMtTable5.class);
-        c1.commitChanges();
-
-        ClientMtTable4 o2 = c2.localObject(o1);
-        ClientMtTable5 o2r = c2.localObject(o1r);
-
-        o2.addToTable5s(o2r);
-        c2.commitChanges();
-
-        assertEquals(1, o1.getTable5s().size());
-        assertEquals(1, o2.getTable5s().size());
-        assertFalse(c1.internalGraphManager().hasChanges());
-        assertFalse(c2.internalGraphManager().hasChanges());
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextDeleteRulesIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextDeleteRulesIT.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextDeleteRulesIT.java
new file mode 100644
index 0000000..f9af40f
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextDeleteRulesIT.java
@@ -0,0 +1,111 @@
+/*****************************************************************
+ *   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;
+
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.testdo.mt.ClientMtDeleteCascade;
+import org.apache.cayenne.testdo.mt.ClientMtDeleteDeny;
+import org.apache.cayenne.testdo.mt.ClientMtDeleteNullify;
+import org.apache.cayenne.testdo.mt.ClientMtDeleteRule;
+import org.apache.cayenne.unit.di.client.ClientCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class CayenneContextDeleteRulesIT extends ClientCase {
+
+    @Inject
+    private CayenneContext context;
+
+    public void testNullifyToOne() {
+
+        ClientMtDeleteNullify object = context.newObject(ClientMtDeleteNullify.class);
+        object.setName("object");
+
+        ClientMtDeleteRule related = context.newObject(ClientMtDeleteRule.class);
+        object.setName("related");
+
+        object.setNullify(related);
+        context.commitChanges();
+
+        context.deleteObjects(object);
+        assertFalse(related.getFromNullify().contains(object));
+        assertNull(object.getNullify());
+
+        // And be sure that the commit works afterwards, just for sanity
+        context.commitChanges();
+    }
+
+    public void testDenyToOne() {
+
+        ClientMtDeleteDeny object = context.newObject(ClientMtDeleteDeny.class);
+        ClientMtDeleteRule related = context.newObject(ClientMtDeleteRule.class);
+        object.setDeny(related);
+        context.commitChanges();
+
+        try {
+            context.deleteObjects(object);
+            fail("Should have thrown an exception");
+        }
+        catch (DeleteDenyException e) {
+            // expected
+        }
+
+        object.setDeny(null);
+        context.deleteObjects(object);
+        context.commitChanges();
+    }
+
+    public void testCascadeToOne() {
+
+        ClientMtDeleteCascade object = context.newObject(ClientMtDeleteCascade.class);
+        object.setName("object");
+
+        ClientMtDeleteRule related = context.newObject(ClientMtDeleteRule.class);
+        object.setName("related");
+
+        object.setCascade(related);
+        context.commitChanges();
+
+        context.deleteObjects(object);
+        assertEquals(PersistenceState.DELETED, related.getPersistenceState());
+        assertTrue(context.deletedObjects().contains(related));
+
+        // And be sure that the commit works afterwards, just for sanity
+        context.commitChanges();
+    }
+
+    public void testCascadeToOneNewObject() {
+
+        ClientMtDeleteRule related = context.newObject(ClientMtDeleteRule.class);
+        context.commitChanges();
+
+        ClientMtDeleteCascade object = context.newObject(ClientMtDeleteCascade.class);
+        object.setName("object");
+        object.setCascade(related);
+
+        context.deleteObjects(object);
+        assertEquals(PersistenceState.TRANSIENT, object.getPersistenceState());
+        assertEquals(PersistenceState.DELETED, related.getPersistenceState());
+        assertFalse(context.deletedObjects().contains(object));
+        assertTrue(context.deletedObjects().contains(related));
+
+        context.commitChanges();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextDeleteRulesTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextDeleteRulesTest.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextDeleteRulesTest.java
deleted file mode 100644
index 6d9cf99..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextDeleteRulesTest.java
+++ /dev/null
@@ -1,111 +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;
-
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.testdo.mt.ClientMtDeleteCascade;
-import org.apache.cayenne.testdo.mt.ClientMtDeleteDeny;
-import org.apache.cayenne.testdo.mt.ClientMtDeleteNullify;
-import org.apache.cayenne.testdo.mt.ClientMtDeleteRule;
-import org.apache.cayenne.unit.di.client.ClientCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class CayenneContextDeleteRulesTest extends ClientCase {
-
-    @Inject
-    private CayenneContext context;
-
-    public void testNullifyToOne() {
-
-        ClientMtDeleteNullify object = context.newObject(ClientMtDeleteNullify.class);
-        object.setName("object");
-
-        ClientMtDeleteRule related = context.newObject(ClientMtDeleteRule.class);
-        object.setName("related");
-
-        object.setNullify(related);
-        context.commitChanges();
-
-        context.deleteObjects(object);
-        assertFalse(related.getFromNullify().contains(object));
-        assertNull(object.getNullify());
-
-        // And be sure that the commit works afterwards, just for sanity
-        context.commitChanges();
-    }
-
-    public void testDenyToOne() {
-
-        ClientMtDeleteDeny object = context.newObject(ClientMtDeleteDeny.class);
-        ClientMtDeleteRule related = context.newObject(ClientMtDeleteRule.class);
-        object.setDeny(related);
-        context.commitChanges();
-
-        try {
-            context.deleteObjects(object);
-            fail("Should have thrown an exception");
-        }
-        catch (DeleteDenyException e) {
-            // expected
-        }
-
-        object.setDeny(null);
-        context.deleteObjects(object);
-        context.commitChanges();
-    }
-
-    public void testCascadeToOne() {
-
-        ClientMtDeleteCascade object = context.newObject(ClientMtDeleteCascade.class);
-        object.setName("object");
-
-        ClientMtDeleteRule related = context.newObject(ClientMtDeleteRule.class);
-        object.setName("related");
-
-        object.setCascade(related);
-        context.commitChanges();
-
-        context.deleteObjects(object);
-        assertEquals(PersistenceState.DELETED, related.getPersistenceState());
-        assertTrue(context.deletedObjects().contains(related));
-
-        // And be sure that the commit works afterwards, just for sanity
-        context.commitChanges();
-    }
-
-    public void testCascadeToOneNewObject() {
-
-        ClientMtDeleteRule related = context.newObject(ClientMtDeleteRule.class);
-        context.commitChanges();
-
-        ClientMtDeleteCascade object = context.newObject(ClientMtDeleteCascade.class);
-        object.setName("object");
-        object.setCascade(related);
-
-        context.deleteObjects(object);
-        assertEquals(PersistenceState.TRANSIENT, object.getPersistenceState());
-        assertEquals(PersistenceState.DELETED, related.getPersistenceState());
-        assertFalse(context.deletedObjects().contains(object));
-        assertTrue(context.deletedObjects().contains(related));
-
-        context.commitChanges();
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextEJBQLIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextEJBQLIT.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextEJBQLIT.java
new file mode 100644
index 0000000..f9805fa
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextEJBQLIT.java
@@ -0,0 +1,87 @@
+/*****************************************************************
+ *   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;
+
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.query.EJBQLQuery;
+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 CayenneContextEJBQLIT extends ClientCase {
+
+    @Inject
+    private DBHelper dbHelper;
+
+    @Inject
+    private CayenneContext context;
+
+    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");
+    }
+
+    private void createTwoRecords() throws Exception {
+        tMtTable1.insert(1, "g1", "s1");
+        tMtTable1.insert(2, "g2", "s2");
+    }
+
+    public void testEJBQLSelect() throws Exception {
+        createTwoRecords();
+
+        EJBQLQuery query = new EJBQLQuery("SELECT a FROM MtTable1 a");
+        List<ClientMtTable1> results = context.performQuery(query);
+
+        assertEquals(2, results.size());
+    }
+
+    public void testEJBQLSelectScalar() throws Exception {
+        createTwoRecords();
+
+        EJBQLQuery query = new EJBQLQuery("SELECT COUNT(a) FROM MtTable1 a");
+
+        List<Long> results = context.performQuery(query);
+        assertEquals(Long.valueOf(2), results.get(0));
+    }
+
+    public void testEJBQLSelectMixed() throws Exception {
+        createTwoRecords();
+
+        EJBQLQuery query = new EJBQLQuery(
+                "SELECT COUNT(a), a, a.serverAttribute1 FROM MtTable1 a Group By a ORDER BY a.serverAttribute1");
+
+        List<Object[]> results = context.performQuery(query);
+
+        assertEquals(2, results.size());
+        assertEquals(Long.valueOf(1), results.get(0)[0]);
+        assertTrue(results.get(0)[1] instanceof ClientMtTable1);
+        assertEquals("s1", results.get(0)[2]);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextEJBQLTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextEJBQLTest.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextEJBQLTest.java
deleted file mode 100644
index f9226b8..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextEJBQLTest.java
+++ /dev/null
@@ -1,87 +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;
-
-import java.util.List;
-
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.query.EJBQLQuery;
-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 CayenneContextEJBQLTest extends ClientCase {
-
-    @Inject
-    private DBHelper dbHelper;
-
-    @Inject
-    private CayenneContext context;
-
-    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");
-    }
-
-    private void createTwoRecords() throws Exception {
-        tMtTable1.insert(1, "g1", "s1");
-        tMtTable1.insert(2, "g2", "s2");
-    }
-
-    public void testEJBQLSelect() throws Exception {
-        createTwoRecords();
-
-        EJBQLQuery query = new EJBQLQuery("SELECT a FROM MtTable1 a");
-        List<ClientMtTable1> results = context.performQuery(query);
-
-        assertEquals(2, results.size());
-    }
-
-    public void testEJBQLSelectScalar() throws Exception {
-        createTwoRecords();
-
-        EJBQLQuery query = new EJBQLQuery("SELECT COUNT(a) FROM MtTable1 a");
-
-        List<Long> results = context.performQuery(query);
-        assertEquals(Long.valueOf(2), results.get(0));
-    }
-
-    public void testEJBQLSelectMixed() throws Exception {
-        createTwoRecords();
-
-        EJBQLQuery query = new EJBQLQuery(
-                "SELECT COUNT(a), a, a.serverAttribute1 FROM MtTable1 a Group By a ORDER BY a.serverAttribute1");
-
-        List<Object[]> results = context.performQuery(query);
-
-        assertEquals(2, results.size());
-        assertEquals(Long.valueOf(1), results.get(0)[0]);
-        assertTrue(results.get(0)[1] instanceof ClientMtTable1);
-        assertEquals("s1", results.get(0)[2]);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextGraphDiffCompressorIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextGraphDiffCompressorIT.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextGraphDiffCompressorIT.java
new file mode 100644
index 0000000..1469c8b
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextGraphDiffCompressorIT.java
@@ -0,0 +1,96 @@
+/*****************************************************************
+ *   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;
+
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.testdo.mt.ClientMtTable1;
+import org.apache.cayenne.testdo.mt.ClientMtTable2;
+import org.apache.cayenne.unit.di.DataChannelInterceptor;
+import org.apache.cayenne.unit.di.DataChannelSyncStats;
+import org.apache.cayenne.unit.di.UnitTestClosure;
+import org.apache.cayenne.unit.di.client.ClientCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class CayenneContextGraphDiffCompressorIT extends ClientCase {
+
+    @Inject(ClientCase.ROP_CLIENT_KEY)
+    protected DataChannelInterceptor clientServerInterceptor;
+
+    @Inject
+    protected CayenneContext context;
+
+    public void testMultipleSimpleProperties() {
+
+        ClientMtTable1 o1 = context.newObject(ClientMtTable1.class);
+        o1.setGlobalAttribute1("v1");
+        o1.setGlobalAttribute1("v2");
+
+        DataChannelSyncStats stats = clientServerInterceptor
+                .runWithSyncStatsCollection(new UnitTestClosure() {
+
+                    public void execute() {
+                        context.commitChanges();
+                    }
+                });
+
+        assertEquals(1, stats.nodePropertiesChanged);
+        assertEquals(1, stats.nodesCreated);
+    }
+
+    public void testComplimentaryArcs() {
+
+        ClientMtTable1 o1 = context.newObject(ClientMtTable1.class);
+        ClientMtTable2 o2 = context.newObject(ClientMtTable2.class);
+        o2.setTable1(o1);
+        o2.setTable1(null);
+
+        DataChannelSyncStats stats = clientServerInterceptor
+                .runWithSyncStatsCollection(new UnitTestClosure() {
+
+                    public void execute() {
+                        context.commitChanges();
+                    }
+                });
+
+        assertEquals(0, stats.nodePropertiesChanged);
+        assertEquals(2, stats.nodesCreated);
+        assertEquals(0, stats.arcsCreated);
+        assertEquals(0, stats.arcsDeleted);
+    }
+
+    public void testDelete() {
+
+        ClientMtTable1 o1 = context.newObject(ClientMtTable1.class);
+        o1.setGlobalAttribute1("v1");
+        context.deleteObjects(o1);
+
+        DataChannelSyncStats stats = clientServerInterceptor
+                .runWithSyncStatsCollection(new UnitTestClosure() {
+
+                    public void execute() {
+                        context.commitChanges();
+                    }
+                });
+        assertEquals(0, stats.nodePropertiesChanged);
+        assertEquals(0, stats.nodesCreated);
+        assertEquals(0, stats.nodesRemoved);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextGraphDiffCompressorTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextGraphDiffCompressorTest.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextGraphDiffCompressorTest.java
deleted file mode 100644
index b213e55..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextGraphDiffCompressorTest.java
+++ /dev/null
@@ -1,96 +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;
-
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.testdo.mt.ClientMtTable1;
-import org.apache.cayenne.testdo.mt.ClientMtTable2;
-import org.apache.cayenne.unit.di.DataChannelInterceptor;
-import org.apache.cayenne.unit.di.DataChannelSyncStats;
-import org.apache.cayenne.unit.di.UnitTestClosure;
-import org.apache.cayenne.unit.di.client.ClientCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class CayenneContextGraphDiffCompressorTest extends ClientCase {
-
-    @Inject(ClientCase.ROP_CLIENT_KEY)
-    protected DataChannelInterceptor clientServerInterceptor;
-
-    @Inject
-    protected CayenneContext context;
-
-    public void testMultipleSimpleProperties() {
-
-        ClientMtTable1 o1 = context.newObject(ClientMtTable1.class);
-        o1.setGlobalAttribute1("v1");
-        o1.setGlobalAttribute1("v2");
-
-        DataChannelSyncStats stats = clientServerInterceptor
-                .runWithSyncStatsCollection(new UnitTestClosure() {
-
-                    public void execute() {
-                        context.commitChanges();
-                    }
-                });
-
-        assertEquals(1, stats.nodePropertiesChanged);
-        assertEquals(1, stats.nodesCreated);
-    }
-
-    public void testComplimentaryArcs() {
-
-        ClientMtTable1 o1 = context.newObject(ClientMtTable1.class);
-        ClientMtTable2 o2 = context.newObject(ClientMtTable2.class);
-        o2.setTable1(o1);
-        o2.setTable1(null);
-
-        DataChannelSyncStats stats = clientServerInterceptor
-                .runWithSyncStatsCollection(new UnitTestClosure() {
-
-                    public void execute() {
-                        context.commitChanges();
-                    }
-                });
-
-        assertEquals(0, stats.nodePropertiesChanged);
-        assertEquals(2, stats.nodesCreated);
-        assertEquals(0, stats.arcsCreated);
-        assertEquals(0, stats.arcsDeleted);
-    }
-
-    public void testDelete() {
-
-        ClientMtTable1 o1 = context.newObject(ClientMtTable1.class);
-        o1.setGlobalAttribute1("v1");
-        context.deleteObjects(o1);
-
-        DataChannelSyncStats stats = clientServerInterceptor
-                .runWithSyncStatsCollection(new UnitTestClosure() {
-
-                    public void execute() {
-                        context.commitChanges();
-                    }
-                });
-        assertEquals(0, stats.nodePropertiesChanged);
-        assertEquals(0, stats.nodesCreated);
-        assertEquals(0, stats.nodesRemoved);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextIT.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextIT.java
new file mode 100644
index 0000000..588d56e
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextIT.java
@@ -0,0 +1,351 @@
+/*****************************************************************
+ *   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;
+
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.event.DefaultEventManager;
+import org.apache.cayenne.event.EventManager;
+import org.apache.cayenne.event.MockEventManager;
+import org.apache.cayenne.graph.CompoundDiff;
+import org.apache.cayenne.graph.GraphDiff;
+import org.apache.cayenne.graph.MockGraphDiff;
+import org.apache.cayenne.graph.NodeIdChangeOperation;
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.map.EntityResolver;
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.query.Query;
+import org.apache.cayenne.remote.BootstrapMessage;
+import org.apache.cayenne.remote.ClientChannel;
+import org.apache.cayenne.remote.ClientConnection;
+import org.apache.cayenne.remote.ClientMessage;
+import org.apache.cayenne.testdo.mt.ClientMtTable1;
+import org.apache.cayenne.unit.di.client.ClientCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+import org.apache.cayenne.util.GenericResponse;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class CayenneContextIT extends ClientCase {
+
+    @Inject
+    private ObjectContext serverContext;
+
+    public void testConstructor() {
+
+        CayenneContext context = new CayenneContext();
+
+        // test default property parameters
+        assertNotNull(context.getGraphManager());
+        assertNull(context.channel);
+
+        MockDataChannel channel = new MockDataChannel();
+        context.setChannel(channel);
+        assertSame(channel, context.getChannel());
+    }
+
+    public void testChannel() {
+        MockDataChannel channel = new MockDataChannel();
+        CayenneContext context = new CayenneContext(channel);
+
+        assertSame(channel, context.getChannel());
+    }
+
+    public void testCommitUnchanged() {
+
+        MockDataChannel channel = new MockDataChannel();
+        CayenneContext context = new CayenneContext(channel);
+
+        // no context changes so no connector access is expected
+        context.commitChanges();
+        assertTrue(channel.getRequestObjects().isEmpty());
+    }
+
+    public void testCommitCommandExecuted() {
+
+        MockDataChannel channel = new MockDataChannel(new MockGraphDiff());
+        channel.setEntityResolver(serverContext
+                .getEntityResolver()
+                .getClientEntityResolver());
+        CayenneContext context = new CayenneContext(channel);
+
+        // test that a command is being sent via connector on commit...
+
+        context.internalGraphManager().nodePropertyChanged(
+                new ObjectId("MtTable1"),
+                "x",
+                "y",
+                "z");
+
+        context.commitChanges();
+        assertEquals(1, channel.getRequestObjects().size());
+
+        // expect a sync/commit chain
+        Object mainMessage = channel.getRequestObjects().iterator().next();
+        assertTrue(mainMessage instanceof GraphDiff);
+    }
+
+    public void testCommitChangesNew() {
+        final CompoundDiff diff = new CompoundDiff();
+        final Object newObjectId = new ObjectId("test", "key", "generated");
+        final EventManager eventManager = new DefaultEventManager(0);
+
+        // test that ids that are passed back are actually propagated to the right
+        // objects...
+
+        MockDataChannel channel = new MockDataChannel() {
+
+            @Override
+            public GraphDiff onSync(
+                    ObjectContext originatingContext,
+                    GraphDiff changes,
+                    int syncType) {
+
+                return diff;
+            }
+
+            // must provide a channel with working event manager
+            @Override
+            public EventManager getEventManager() {
+                return eventManager;
+            }
+        };
+
+        CayenneContext context = new CayenneContext(channel);
+        ObjEntity entity = new ObjEntity("test_entity");
+        entity.setClassName(MockPersistentObject.class.getName());
+
+        DataMap dataMap = new DataMap("test");
+        dataMap.addObjEntity(entity);
+        Collection<DataMap> entities = Collections.singleton(dataMap);
+        context.setEntityResolver(new EntityResolver(entities));
+        Persistent object = context.newObject(MockPersistentObject.class);
+
+        // record change here to make it available to the anonymous connector method..
+        diff.add(new NodeIdChangeOperation(object.getObjectId(), newObjectId));
+
+        // check that a generated object ID is assigned back to the object...
+        assertNotSame(newObjectId, object.getObjectId());
+        context.commitChanges();
+        assertSame(newObjectId, object.getObjectId());
+        assertSame(object, context.graphManager.getNode(newObjectId));
+    }
+
+    public void testNewObject() {
+
+        CayenneContext context = new CayenneContext(new MockDataChannel());
+
+        ObjEntity entity = new ObjEntity("test_entity");
+        entity.setClassName(MockPersistentObject.class.getName());
+
+        DataMap dataMap = new DataMap("test");
+        dataMap.addObjEntity(entity);
+        Collection<DataMap> entities = Collections.singleton(dataMap);
+        context.setEntityResolver(new EntityResolver(entities));
+
+        Persistent object = context.newObject(MockPersistentObject.class);
+        assertNotNull(object);
+        assertTrue(object instanceof MockPersistentObject);
+        assertEquals(PersistenceState.NEW, object.getPersistenceState());
+        assertSame(context, object.getObjectContext());
+        assertTrue(context
+                .internalGraphManager()
+                .dirtyNodes(PersistenceState.NEW)
+                .contains(object));
+        assertNotNull(object.getObjectId());
+        assertTrue(object.getObjectId().isTemporary());
+    }
+
+    public void testDeleteObject() {
+
+        CayenneContext context = new CayenneContext(new MockDataChannel());
+        ObjEntity entity = new ObjEntity("test_entity");
+        entity.setClassName(MockPersistentObject.class.getName());
+
+        DataMap dataMap = new DataMap("test");
+        dataMap.addObjEntity(entity);
+        Collection<DataMap> entities = Collections.singleton(dataMap);
+        context.setEntityResolver(new EntityResolver(entities));
+
+        // TRANSIENT ... should quietly ignore it
+        Persistent transientObject = new MockPersistentObject();
+        context.deleteObjects(transientObject);
+        assertEquals(PersistenceState.TRANSIENT, transientObject.getPersistenceState());
+
+        // NEW ... should make it TRANSIENT
+        // create via context to make sure that object store would register it
+        Persistent newObject = context.newObject(MockPersistentObject.class);
+        assertNotNull(newObject.getObjectContext());
+        context.deleteObjects(newObject);
+        assertNull(newObject.getObjectContext());
+        assertEquals(PersistenceState.TRANSIENT, newObject.getPersistenceState());
+        assertFalse(context
+                .internalGraphManager()
+                .dirtyNodes()
+                .contains(newObject.getObjectId()));
+
+        // see CAY-547 for details...
+        assertFalse(context.internalGraphManager().dirtyNodes().contains(null));
+
+        // COMMITTED
+        Persistent committed = new MockPersistentObject();
+        committed.setPersistenceState(PersistenceState.COMMITTED);
+        committed.setObjectId(new ObjectId("test_entity", "key", "value1"));
+        committed.setObjectContext(context);
+        context.deleteObjects(committed);
+        assertEquals(PersistenceState.DELETED, committed.getPersistenceState());
+
+        // MODIFIED
+        Persistent modified = new MockPersistentObject();
+        modified.setPersistenceState(PersistenceState.MODIFIED);
+        modified.setObjectId(new ObjectId("test_entity", "key", "value2"));
+        modified.setObjectContext(context);
+        context.deleteObjects(modified);
+        assertEquals(PersistenceState.DELETED, modified.getPersistenceState());
+
+        // DELETED
+        Persistent deleted = new MockPersistentObject();
+        deleted.setPersistenceState(PersistenceState.DELETED);
+        deleted.setObjectId(new ObjectId("test_entity", "key", "value3"));
+        deleted.setObjectContext(context);
+        context.deleteObjects(deleted);
+        assertEquals(PersistenceState.DELETED, committed.getPersistenceState());
+    }
+
+    public void testBeforePropertyReadShouldInflateHollow() {
+
+        ObjectId gid = new ObjectId("MtTable1", "a", "b");
+        final ClientMtTable1 inflated = new ClientMtTable1();
+        inflated.setPersistenceState(PersistenceState.COMMITTED);
+        inflated.setObjectId(gid);
+        inflated.setGlobalAttribute1("abc");
+
+        ClientConnection connection = mock(ClientConnection.class);
+        when(connection.sendMessage((ClientMessage) any())).thenAnswer(
+                new Answer<Object>() {
+
+                    public Object answer(InvocationOnMock invocation) {
+                        ClientMessage arg = (ClientMessage) invocation.getArguments()[0];
+
+                        if (arg instanceof BootstrapMessage) {
+                            return new EntityResolver();
+                        }
+                        else {
+                            return new GenericResponse(Arrays.asList(inflated));
+                        }
+                    }
+                });
+
+        ClientChannel channel = new ClientChannel(
+                connection,
+                false,
+                new MockEventManager(),
+                false);
+
+        // check that a HOLLOW object is infalted on "beforePropertyRead"
+        ClientMtTable1 hollow = new ClientMtTable1();
+        hollow.setPersistenceState(PersistenceState.HOLLOW);
+        hollow.setObjectId(gid);
+
+        final boolean[] selectExecuted = new boolean[1];
+        CayenneContext context = new CayenneContext(channel) {
+
+            @Override
+            public List<?> performQuery(Query query) {
+                selectExecuted[0] = true;
+                return super.performQuery(query);
+            }
+        };
+
+        context.setEntityResolver(serverContext
+                .getEntityResolver()
+                .getClientEntityResolver());
+
+        context.graphManager.registerNode(hollow.getObjectId(), hollow);
+
+        // testing this...
+        context
+                .prepareForAccess(
+                        hollow,
+                        ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY,
+                        false);
+        assertTrue(selectExecuted[0]);
+        assertSame(hollow, context.getGraphManager().getNode(gid));
+        assertEquals(
+                inflated.getGlobalAttribute1Direct(),
+                hollow.getGlobalAttribute1Direct());
+        assertEquals(PersistenceState.COMMITTED, hollow.getPersistenceState());
+    }
+
+    public void testBeforeHollowDeleteShouldChangeStateToCommited() {
+
+        ObjectId gid = new ObjectId("MtTable1", "a", "b");
+        final ClientMtTable1 inflated = new ClientMtTable1();
+        inflated.setPersistenceState(PersistenceState.COMMITTED);
+        inflated.setObjectId(gid);
+        inflated.setGlobalAttribute1("abc");
+
+        ClientConnection connection = mock(ClientConnection.class);
+        when(connection.sendMessage((ClientMessage) any())).thenAnswer(
+                new Answer<Object>() {
+
+                    public Object answer(InvocationOnMock invocation) {
+                        ClientMessage arg = (ClientMessage) invocation.getArguments()[0];
+
+                        if (arg instanceof BootstrapMessage) {
+                            return new EntityResolver();
+                        }
+                        else {
+                            return new GenericResponse(Arrays.asList(inflated));
+                        }
+                    }
+                });
+        ClientChannel channel = new ClientChannel(
+                connection,
+                false,
+                new MockEventManager(),
+                false);
+
+        CayenneContext context = new CayenneContext(channel);
+        context.setEntityResolver(serverContext
+                .getEntityResolver()
+                .getClientEntityResolver());
+        ClientMtTable1 hollow = context.localObject(inflated);
+        assertEquals(PersistenceState.HOLLOW, hollow.getPersistenceState());
+
+        // testing this...
+        context.deleteObjects(hollow);
+        assertSame(hollow, context.getGraphManager().getNode(gid));
+        assertEquals(
+                inflated.getGlobalAttribute1Direct(),
+                hollow.getGlobalAttribute1Direct());
+        assertEquals(PersistenceState.DELETED, hollow.getPersistenceState());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextInheritanceIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextInheritanceIT.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextInheritanceIT.java
new file mode 100644
index 0000000..ec8c43a
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextInheritanceIT.java
@@ -0,0 +1,151 @@
+/*****************************************************************
+ *   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;
+
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.exp.ExpressionFactory;
+import org.apache.cayenne.query.SelectQuery;
+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.unit.di.client.ClientCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+import java.sql.Types;
+import java.util.List;
+
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class CayenneContextInheritanceIT extends ClientCase {
+
+    @Inject
+    private DBHelper dbHelper;
+
+    @Inject
+    private CayenneContext context;
+
+    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",
+                "SUBCLASS_ATTRIBUTE1").setColumnTypes(
+                Types.INTEGER,
+                Types.VARCHAR,
+                Types.VARCHAR,
+                Types.VARCHAR);
+    }
+
+    public void testInsertSubclass() throws Exception {
+
+        ClientMtTable1Subclass1 object = context.newObject(ClientMtTable1Subclass1.class);
+        object.setGlobalAttribute1("sub1");
+        object.setServerAttribute1("sa1");
+        object.setSubclass1Attribute1("suba1");
+
+        context.commitChanges();
+
+        assertEquals(1, tMtTable1.getRowCount());
+        assertEquals("sub1", tMtTable1.getString("GLOBAL_ATTRIBUTE1"));
+        assertEquals("sa1", tMtTable1.getString("SERVER_ATTRIBUTE1"));
+        assertEquals("suba1", tMtTable1.getString("SUBCLASS_ATTRIBUTE1"));
+    }
+
+    public void testPerformQueryInheritanceLeaf() throws Exception {
+
+        tMtTable1.insert(1, "xxx", "yyy", null);
+        tMtTable1.insert(2, "sub1", "zzz", "sa1");
+        tMtTable1.insert(3, "1111", "aaa", null);
+
+        SelectQuery query = new SelectQuery(ClientMtTable1Subclass1.class);
+        List<ClientMtTable1Subclass1> objects = context.performQuery(query);
+
+        assertEquals(1, objects.size());
+        assertEquals("sa1", objects.get(0).getSubclass1Attribute1());
+    }
+
+    public void testPerformQueryInheritanceSuper() throws Exception {
+
+        tMtTable1.insert(1, "a", "yyy", null);
+        tMtTable1.insert(2, "sub1", "zzz", "sa1");
+        tMtTable1.insert(3, "z", "aaa", null);
+
+        SelectQuery query = new SelectQuery(ClientMtTable1.class);
+        List<ClientMtTable1> objects = context.performQuery(query);
+
+        assertEquals(3, objects.size());
+
+        int checkedFields = 0;
+        for (int i = 0; i < objects.size(); i++) {
+            Integer id = (Integer) objects.get(i).getObjectId().getIdSnapshot().get(
+                    "TABLE1_ID");
+            if (id == 1) {
+                assertEquals("a", objects.get(i).getGlobalAttribute1());
+                checkedFields++;
+            }
+            else if (id == 2) {
+                assertEquals("sa1", ((ClientMtTable1Subclass1) objects.get(i))
+                        .getSubclass1Attribute1());
+                checkedFields++;
+            }
+
+        }
+        assertEquals(2, checkedFields);
+    }
+
+    public void testPerformQueryWithQualifierInheritanceSuper() throws Exception {
+
+        tMtTable1.insert(1, "a", "XX", null);
+        tMtTable1.insert(2, "sub1", "XXA", "sa1");
+        tMtTable1.insert(3, "z", "MM", null);
+
+        SelectQuery query = new SelectQuery(ClientMtTable1.class);
+        query.andQualifier(ExpressionFactory.likeExp(
+                ClientMtTable1.SERVER_ATTRIBUTE1_PROPERTY,
+                "X%"));
+        List<ClientMtTable1> objects = context.performQuery(query);
+
+        assertEquals(2, objects.size());
+
+        int checkedFields = 0;
+        for (int i = 0; i < objects.size(); i++) {
+            Integer id = (Integer) objects.get(i).getObjectId().getIdSnapshot().get(
+                    "TABLE1_ID");
+            if (id == 1) {
+                assertEquals("a", objects.get(i).getGlobalAttribute1());
+                checkedFields++;
+            }
+            else if (id == 2) {
+                assertEquals("sa1", ((ClientMtTable1Subclass1) objects.get(i))
+                        .getSubclass1Attribute1());
+                checkedFields++;
+            }
+
+        }
+        assertEquals(2, checkedFields);
+    }
+
+}


[6/8] Rename Integration Tests in cayenne-client (*IT.java instead of *Test.java)

Posted by aa...@apache.org.
http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextInheritanceTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextInheritanceTest.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextInheritanceTest.java
deleted file mode 100644
index edf788f..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextInheritanceTest.java
+++ /dev/null
@@ -1,151 +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;
-
-import java.sql.Types;
-import java.util.List;
-
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.exp.ExpressionFactory;
-import org.apache.cayenne.query.SelectQuery;
-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.unit.di.client.ClientCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class CayenneContextInheritanceTest extends ClientCase {
-
-    @Inject
-    private DBHelper dbHelper;
-
-    @Inject
-    private CayenneContext context;
-
-    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",
-                "SUBCLASS_ATTRIBUTE1").setColumnTypes(
-                Types.INTEGER,
-                Types.VARCHAR,
-                Types.VARCHAR,
-                Types.VARCHAR);
-    }
-
-    public void testInsertSubclass() throws Exception {
-
-        ClientMtTable1Subclass1 object = context.newObject(ClientMtTable1Subclass1.class);
-        object.setGlobalAttribute1("sub1");
-        object.setServerAttribute1("sa1");
-        object.setSubclass1Attribute1("suba1");
-
-        context.commitChanges();
-
-        assertEquals(1, tMtTable1.getRowCount());
-        assertEquals("sub1", tMtTable1.getString("GLOBAL_ATTRIBUTE1"));
-        assertEquals("sa1", tMtTable1.getString("SERVER_ATTRIBUTE1"));
-        assertEquals("suba1", tMtTable1.getString("SUBCLASS_ATTRIBUTE1"));
-    }
-
-    public void testPerformQueryInheritanceLeaf() throws Exception {
-
-        tMtTable1.insert(1, "xxx", "yyy", null);
-        tMtTable1.insert(2, "sub1", "zzz", "sa1");
-        tMtTable1.insert(3, "1111", "aaa", null);
-
-        SelectQuery query = new SelectQuery(ClientMtTable1Subclass1.class);
-        List<ClientMtTable1Subclass1> objects = context.performQuery(query);
-
-        assertEquals(1, objects.size());
-        assertEquals("sa1", objects.get(0).getSubclass1Attribute1());
-    }
-
-    public void testPerformQueryInheritanceSuper() throws Exception {
-
-        tMtTable1.insert(1, "a", "yyy", null);
-        tMtTable1.insert(2, "sub1", "zzz", "sa1");
-        tMtTable1.insert(3, "z", "aaa", null);
-
-        SelectQuery query = new SelectQuery(ClientMtTable1.class);
-        List<ClientMtTable1> objects = context.performQuery(query);
-
-        assertEquals(3, objects.size());
-
-        int checkedFields = 0;
-        for (int i = 0; i < objects.size(); i++) {
-            Integer id = (Integer) objects.get(i).getObjectId().getIdSnapshot().get(
-                    "TABLE1_ID");
-            if (id == 1) {
-                assertEquals("a", objects.get(i).getGlobalAttribute1());
-                checkedFields++;
-            }
-            else if (id == 2) {
-                assertEquals("sa1", ((ClientMtTable1Subclass1) objects.get(i))
-                        .getSubclass1Attribute1());
-                checkedFields++;
-            }
-
-        }
-        assertEquals(2, checkedFields);
-    }
-
-    public void testPerformQueryWithQualifierInheritanceSuper() throws Exception {
-
-        tMtTable1.insert(1, "a", "XX", null);
-        tMtTable1.insert(2, "sub1", "XXA", "sa1");
-        tMtTable1.insert(3, "z", "MM", null);
-
-        SelectQuery query = new SelectQuery(ClientMtTable1.class);
-        query.andQualifier(ExpressionFactory.likeExp(
-                ClientMtTable1.SERVER_ATTRIBUTE1_PROPERTY,
-                "X%"));
-        List<ClientMtTable1> objects = context.performQuery(query);
-
-        assertEquals(2, objects.size());
-
-        int checkedFields = 0;
-        for (int i = 0; i < objects.size(); i++) {
-            Integer id = (Integer) objects.get(i).getObjectId().getIdSnapshot().get(
-                    "TABLE1_ID");
-            if (id == 1) {
-                assertEquals("a", objects.get(i).getGlobalAttribute1());
-                checkedFields++;
-            }
-            else if (id == 2) {
-                assertEquals("sa1", ((ClientMtTable1Subclass1) objects.get(i))
-                        .getSubclass1Attribute1());
-                checkedFields++;
-            }
-
-        }
-        assertEquals(2, checkedFields);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextMapRelationshipIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextMapRelationshipIT.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextMapRelationshipIT.java
new file mode 100644
index 0000000..0ff92b1
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextMapRelationshipIT.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;
+
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.query.ObjectIdQuery;
+import org.apache.cayenne.query.RefreshQuery;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.test.jdbc.TableHelper;
+import org.apache.cayenne.testdo.mt.ClientMtMapToMany;
+import org.apache.cayenne.testdo.mt.ClientMtMapToManyTarget;
+import org.apache.cayenne.testdo.mt.MtMapToMany;
+import org.apache.cayenne.unit.di.client.ClientCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+import java.util.Map;
+
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class CayenneContextMapRelationshipIT extends ClientCase {
+
+    @Inject
+    private CayenneContext context;
+
+    @Inject
+    private DBHelper dbHelper;
+
+    private TableHelper tMtMapToMany;
+    private TableHelper tMtMapToManyTarget;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("MT_MAP_TO_MANY_TARGET");
+        dbHelper.deleteAll("MT_MAP_TO_MANY");
+
+        tMtMapToMany = new TableHelper(dbHelper, "MT_MAP_TO_MANY");
+        tMtMapToMany.setColumns("ID");
+
+        tMtMapToManyTarget = new TableHelper(dbHelper, "MT_MAP_TO_MANY_TARGET");
+        tMtMapToManyTarget.setColumns("ID", "MAP_TO_MANY_ID");
+    }
+
+    private void createTwoMapToManysWithTargetsDataSet() throws Exception {
+        tMtMapToMany.insert(1).insert(2);
+        tMtMapToManyTarget.insert(1, 1).insert(2, 1).insert(3, 1).insert(4, 2);
+    }
+
+    public void testReadToMany() throws Exception {
+        createTwoMapToManysWithTargetsDataSet();
+
+        ObjectId id = new ObjectId("MtMapToMany", MtMapToMany.ID_PK_COLUMN, 1);
+        ClientMtMapToMany o1 = (ClientMtMapToMany) Cayenne.objectForQuery(
+                context,
+                new ObjectIdQuery(id));
+
+        Map<Object, ClientMtMapToManyTarget> targets = o1.getTargets();
+
+        assertTrue(((ValueHolder) targets).isFault());
+
+        assertNotNull(targets);
+        assertEquals(3, targets.size());
+        assertNotNull(targets.get(new Integer(1)));
+        assertNotNull(targets.get(new Integer(2)));
+        assertNotNull(targets.get(new Integer(3)));
+    }
+
+    public void testAddToMany() throws Exception {
+        createTwoMapToManysWithTargetsDataSet();
+
+        ObjectId id = new ObjectId("MtMapToMany", MtMapToMany.ID_PK_COLUMN, 1);
+        ClientMtMapToMany o1 = (ClientMtMapToMany) Cayenne.objectForQuery(
+                context,
+                new ObjectIdQuery(id));
+
+        Map<Object, ClientMtMapToManyTarget> targets = o1.getTargets();
+        assertNotNull(targets);
+        assertEquals(3, targets.size());
+
+        ClientMtMapToManyTarget newTarget = o1.getObjectContext().newObject(
+                ClientMtMapToManyTarget.class);
+
+        o1.addToTargets(newTarget);
+        assertEquals(4, targets.size());
+        assertSame(o1, newTarget.getMapToMany());
+
+        o1.getObjectContext().commitChanges();
+
+        o1.getObjectContext().performGenericQuery(new RefreshQuery());
+        assertEquals(4, o1.getTargets().size());
+
+        int newId = Cayenne.intPKForObject(newTarget);
+        assertSame(newTarget, o1.getTargets().get(new Integer(newId)));
+
+        assertEquals(PersistenceState.COMMITTED, o1.getPersistenceState());
+        assertEquals(PersistenceState.COMMITTED, newTarget.getPersistenceState());
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextMapRelationshipTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextMapRelationshipTest.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextMapRelationshipTest.java
deleted file mode 100644
index 182643a..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextMapRelationshipTest.java
+++ /dev/null
@@ -1,112 +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;
-
-import java.util.Map;
-
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.query.ObjectIdQuery;
-import org.apache.cayenne.query.RefreshQuery;
-import org.apache.cayenne.test.jdbc.DBHelper;
-import org.apache.cayenne.test.jdbc.TableHelper;
-import org.apache.cayenne.testdo.mt.ClientMtMapToMany;
-import org.apache.cayenne.testdo.mt.ClientMtMapToManyTarget;
-import org.apache.cayenne.testdo.mt.MtMapToMany;
-import org.apache.cayenne.unit.di.client.ClientCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class CayenneContextMapRelationshipTest extends ClientCase {
-
-    @Inject
-    private CayenneContext context;
-
-    @Inject
-    private DBHelper dbHelper;
-
-    private TableHelper tMtMapToMany;
-    private TableHelper tMtMapToManyTarget;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("MT_MAP_TO_MANY_TARGET");
-        dbHelper.deleteAll("MT_MAP_TO_MANY");
-
-        tMtMapToMany = new TableHelper(dbHelper, "MT_MAP_TO_MANY");
-        tMtMapToMany.setColumns("ID");
-
-        tMtMapToManyTarget = new TableHelper(dbHelper, "MT_MAP_TO_MANY_TARGET");
-        tMtMapToManyTarget.setColumns("ID", "MAP_TO_MANY_ID");
-    }
-
-    private void createTwoMapToManysWithTargetsDataSet() throws Exception {
-        tMtMapToMany.insert(1).insert(2);
-        tMtMapToManyTarget.insert(1, 1).insert(2, 1).insert(3, 1).insert(4, 2);
-    }
-
-    public void testReadToMany() throws Exception {
-        createTwoMapToManysWithTargetsDataSet();
-
-        ObjectId id = new ObjectId("MtMapToMany", MtMapToMany.ID_PK_COLUMN, 1);
-        ClientMtMapToMany o1 = (ClientMtMapToMany) Cayenne.objectForQuery(
-                context,
-                new ObjectIdQuery(id));
-
-        Map<Object, ClientMtMapToManyTarget> targets = o1.getTargets();
-
-        assertTrue(((ValueHolder) targets).isFault());
-
-        assertNotNull(targets);
-        assertEquals(3, targets.size());
-        assertNotNull(targets.get(new Integer(1)));
-        assertNotNull(targets.get(new Integer(2)));
-        assertNotNull(targets.get(new Integer(3)));
-    }
-
-    public void testAddToMany() throws Exception {
-        createTwoMapToManysWithTargetsDataSet();
-
-        ObjectId id = new ObjectId("MtMapToMany", MtMapToMany.ID_PK_COLUMN, 1);
-        ClientMtMapToMany o1 = (ClientMtMapToMany) Cayenne.objectForQuery(
-                context,
-                new ObjectIdQuery(id));
-
-        Map<Object, ClientMtMapToManyTarget> targets = o1.getTargets();
-        assertNotNull(targets);
-        assertEquals(3, targets.size());
-
-        ClientMtMapToManyTarget newTarget = o1.getObjectContext().newObject(
-                ClientMtMapToManyTarget.class);
-
-        o1.addToTargets(newTarget);
-        assertEquals(4, targets.size());
-        assertSame(o1, newTarget.getMapToMany());
-
-        o1.getObjectContext().commitChanges();
-
-        o1.getObjectContext().performGenericQuery(new RefreshQuery());
-        assertEquals(4, o1.getTargets().size());
-
-        int newId = Cayenne.intPKForObject(newTarget);
-        assertSame(newTarget, o1.getTargets().get(new Integer(newId)));
-
-        assertEquals(PersistenceState.COMMITTED, o1.getPersistenceState());
-        assertEquals(PersistenceState.COMMITTED, newTarget.getPersistenceState());
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextMergeHandlerIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextMergeHandlerIT.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextMergeHandlerIT.java
new file mode 100644
index 0000000..a5b4815
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextMergeHandlerIT.java
@@ -0,0 +1,90 @@
+/*****************************************************************
+ *   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;
+
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.graph.GraphEvent;
+import org.apache.cayenne.testdo.mt.ClientMtTable1;
+import org.apache.cayenne.unit.di.client.ClientCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+import static org.mockito.Mockito.mock;
+
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class CayenneContextMergeHandlerIT extends ClientCase {
+
+    @Inject
+    protected CayenneContext context;
+
+    public void testShouldProcessEvent() {
+
+        CayenneContextMergeHandler handler = new CayenneContextMergeHandler(context);
+
+        // 1. Our context initiated the sync:
+        // src == channel && postedBy == context
+        GraphEvent e1 = new GraphEvent(context.getChannel(), context, null);
+        assertFalse(handler.shouldProcessEvent(e1));
+
+        // 2. Another context initiated the sync:
+        // postedBy != context && source == channel
+        GraphEvent e2 = new GraphEvent(context.getChannel(), mock(ObjectContext.class), null);
+        assertTrue(handler.shouldProcessEvent(e2));
+
+        // 2.1 Another object initiated the sync:
+        // postedBy != context && source == channel
+        GraphEvent e21 = new GraphEvent(context.getChannel(), new Object(), null);
+        assertTrue(handler.shouldProcessEvent(e21));
+
+        // 3. Another channel initiated the sync:
+        // postedBy == ? && source != channel
+        GraphEvent e3 = new GraphEvent(new MockDataChannel(), new Object(), null);
+        assertFalse(handler.shouldProcessEvent(e3));
+
+        // 4. inactive
+        GraphEvent e4 = new GraphEvent(context.getChannel(), mock(ObjectContext.class), null);
+        handler.active = false;
+        assertFalse(handler.shouldProcessEvent(e4));
+    }
+
+    public void testNodePropertyChanged() {
+
+        ClientMtTable1 o1 = context.newObject(ClientMtTable1.class);
+
+        CayenneContextMergeHandler handler = new CayenneContextMergeHandler(context);
+
+        assertNull(o1.getGlobalAttribute1Direct());
+
+        handler.nodePropertyChanged(o1.getObjectId(), ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY, null, "abc");
+        assertEquals("abc", o1.getGlobalAttribute1Direct());
+
+        handler.nodePropertyChanged(o1.getObjectId(), ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY, "abc", "xyz");
+
+        assertEquals("xyz", o1.getGlobalAttribute1Direct());
+
+        // block if old value is different
+        handler.nodePropertyChanged(o1.getObjectId(), ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY, "123", "mnk");
+
+        assertEquals("xyz", o1.getGlobalAttribute1Direct());
+
+        handler.nodePropertyChanged(o1.getObjectId(), ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY, "xyz", null);
+
+        assertNull(o1.getGlobalAttribute1Direct());
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextMergeHandlerTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextMergeHandlerTest.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextMergeHandlerTest.java
deleted file mode 100644
index e7dd147..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextMergeHandlerTest.java
+++ /dev/null
@@ -1,90 +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;
-
-import static org.mockito.Mockito.mock;
-
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.graph.GraphEvent;
-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 CayenneContextMergeHandlerTest extends ClientCase {
-
-    @Inject
-    protected CayenneContext context;
-
-    public void testShouldProcessEvent() {
-
-        CayenneContextMergeHandler handler = new CayenneContextMergeHandler(context);
-
-        // 1. Our context initiated the sync:
-        // src == channel && postedBy == context
-        GraphEvent e1 = new GraphEvent(context.getChannel(), context, null);
-        assertFalse(handler.shouldProcessEvent(e1));
-
-        // 2. Another context initiated the sync:
-        // postedBy != context && source == channel
-        GraphEvent e2 = new GraphEvent(context.getChannel(), mock(ObjectContext.class), null);
-        assertTrue(handler.shouldProcessEvent(e2));
-
-        // 2.1 Another object initiated the sync:
-        // postedBy != context && source == channel
-        GraphEvent e21 = new GraphEvent(context.getChannel(), new Object(), null);
-        assertTrue(handler.shouldProcessEvent(e21));
-
-        // 3. Another channel initiated the sync:
-        // postedBy == ? && source != channel
-        GraphEvent e3 = new GraphEvent(new MockDataChannel(), new Object(), null);
-        assertFalse(handler.shouldProcessEvent(e3));
-
-        // 4. inactive
-        GraphEvent e4 = new GraphEvent(context.getChannel(), mock(ObjectContext.class), null);
-        handler.active = false;
-        assertFalse(handler.shouldProcessEvent(e4));
-    }
-
-    public void testNodePropertyChanged() {
-
-        ClientMtTable1 o1 = context.newObject(ClientMtTable1.class);
-
-        CayenneContextMergeHandler handler = new CayenneContextMergeHandler(context);
-
-        assertNull(o1.getGlobalAttribute1Direct());
-
-        handler.nodePropertyChanged(o1.getObjectId(), ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY, null, "abc");
-        assertEquals("abc", o1.getGlobalAttribute1Direct());
-
-        handler.nodePropertyChanged(o1.getObjectId(), ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY, "abc", "xyz");
-
-        assertEquals("xyz", o1.getGlobalAttribute1Direct());
-
-        // block if old value is different
-        handler.nodePropertyChanged(o1.getObjectId(), ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY, "123", "mnk");
-
-        assertEquals("xyz", o1.getGlobalAttribute1Direct());
-
-        handler.nodePropertyChanged(o1.getObjectId(), ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY, "xyz", null);
-
-        assertNull(o1.getGlobalAttribute1Direct());
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextNamedQueryCachingIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextNamedQueryCachingIT.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextNamedQueryCachingIT.java
new file mode 100644
index 0000000..f286274
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextNamedQueryCachingIT.java
@@ -0,0 +1,133 @@
+/*****************************************************************
+ *   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;
+
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.query.NamedQuery;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.test.jdbc.TableHelper;
+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 java.util.Collections;
+import java.util.List;
+
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class CayenneContextNamedQueryCachingIT extends ClientCase {
+
+    @Inject
+    private DBHelper dbHelper;
+
+    @Inject
+    private CayenneContext context;
+
+    @Inject(ClientCase.ROP_CLIENT_KEY)
+    private DataChannelInterceptor clientServerInterceptor;
+
+    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 createThreeMtTable1sDataSet() throws Exception {
+        tMtTable1.insert(1, "g1", "s1");
+        tMtTable1.insert(2, "g2", "s2");
+        tMtTable1.insert(3, "g3", "s3");
+    }
+
+    public void testLocalCache() throws Exception {
+        createThreeMtTable1sDataSet();
+
+        final NamedQuery q1 = new NamedQuery("MtQueryWithLocalCache");
+
+        final List<?> result1 = context.performQuery(q1);
+        assertEquals(3, result1.size());
+
+        clientServerInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                List<?> result2 = context.performQuery(q1);
+                assertSame(result1, result2);
+            }
+        });
+
+        // refresh
+        q1.setForceNoCache(true);
+        List<?> result3 = context.performQuery(q1);
+        assertNotSame(result1, result3);
+        assertEquals(3, result3.size());
+    }
+
+    public void testLocalCacheParameterized() throws Exception {
+        createThreeMtTable1sDataSet();
+
+        final NamedQuery q1 = new NamedQuery(
+                "ParameterizedMtQueryWithLocalCache",
+                Collections.singletonMap("g", "g1"));
+
+        final NamedQuery q2 = new NamedQuery(
+                "ParameterizedMtQueryWithLocalCache",
+                Collections.singletonMap("g", "g2"));
+
+        final List<?> result1 = context.performQuery(q1);
+        assertEquals(1, result1.size());
+
+        clientServerInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                List<?> result2 = context.performQuery(q1);
+                assertSame(result1, result2);
+            }
+        });
+        
+        final List<?> result3 = context.performQuery(q2);
+        assertNotSame(result1, result3);
+        assertEquals(1, result3.size());
+
+        clientServerInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                List<?> result4 = context.performQuery(q2);
+                assertSame(result3, result4);
+
+                List<?> result5 = context.performQuery(q1);
+                assertSame(result1, result5);
+            }
+        });
+    
+    }
+    
+    public void testParameterizedMappedToEJBQLQueries() throws Exception {
+        
+        createThreeMtTable1sDataSet();
+        NamedQuery query = new NamedQuery("ParameterizedEJBQLMtQuery", Collections.singletonMap("g", "g1"));
+        
+        List<?> r1 = context.performQuery(query);
+        assertEquals(1, r1.size());
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextNamedQueryCachingTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextNamedQueryCachingTest.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextNamedQueryCachingTest.java
deleted file mode 100644
index d9e71bc..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextNamedQueryCachingTest.java
+++ /dev/null
@@ -1,133 +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;
-
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.query.NamedQuery;
-import org.apache.cayenne.test.jdbc.DBHelper;
-import org.apache.cayenne.test.jdbc.TableHelper;
-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;
-
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class CayenneContextNamedQueryCachingTest extends ClientCase {
-
-    @Inject
-    private DBHelper dbHelper;
-
-    @Inject
-    private CayenneContext context;
-
-    @Inject(ClientCase.ROP_CLIENT_KEY)
-    private DataChannelInterceptor clientServerInterceptor;
-
-    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 createThreeMtTable1sDataSet() throws Exception {
-        tMtTable1.insert(1, "g1", "s1");
-        tMtTable1.insert(2, "g2", "s2");
-        tMtTable1.insert(3, "g3", "s3");
-    }
-
-    public void testLocalCache() throws Exception {
-        createThreeMtTable1sDataSet();
-
-        final NamedQuery q1 = new NamedQuery("MtQueryWithLocalCache");
-
-        final List<?> result1 = context.performQuery(q1);
-        assertEquals(3, result1.size());
-
-        clientServerInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                List<?> result2 = context.performQuery(q1);
-                assertSame(result1, result2);
-            }
-        });
-
-        // refresh
-        q1.setForceNoCache(true);
-        List<?> result3 = context.performQuery(q1);
-        assertNotSame(result1, result3);
-        assertEquals(3, result3.size());
-    }
-
-    public void testLocalCacheParameterized() throws Exception {
-        createThreeMtTable1sDataSet();
-
-        final NamedQuery q1 = new NamedQuery(
-                "ParameterizedMtQueryWithLocalCache",
-                Collections.singletonMap("g", "g1"));
-
-        final NamedQuery q2 = new NamedQuery(
-                "ParameterizedMtQueryWithLocalCache",
-                Collections.singletonMap("g", "g2"));
-
-        final List<?> result1 = context.performQuery(q1);
-        assertEquals(1, result1.size());
-
-        clientServerInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                List<?> result2 = context.performQuery(q1);
-                assertSame(result1, result2);
-            }
-        });
-        
-        final List<?> result3 = context.performQuery(q2);
-        assertNotSame(result1, result3);
-        assertEquals(1, result3.size());
-
-        clientServerInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                List<?> result4 = context.performQuery(q2);
-                assertSame(result3, result4);
-
-                List<?> result5 = context.performQuery(q1);
-                assertSame(result1, result5);
-            }
-        });
-    
-    }
-    
-    public void testParameterizedMappedToEJBQLQueries() throws Exception {
-        
-        createThreeMtTable1sDataSet();
-        NamedQuery query = new NamedQuery("ParameterizedEJBQLMtQuery", Collections.singletonMap("g", "g1"));
-        
-        List<?> r1 = context.performQuery(query);
-        assertEquals(1, r1.size());
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextPaginatedListCachingIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextPaginatedListCachingIT.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextPaginatedListCachingIT.java
new file mode 100644
index 0000000..e59bcc9
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextPaginatedListCachingIT.java
@@ -0,0 +1,75 @@
+/*****************************************************************
+ *   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;
+
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.query.QueryCacheStrategy;
+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.unit.di.client.ClientCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+import java.util.List;
+
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class CayenneContextPaginatedListCachingIT extends ClientCase {
+
+    @Inject
+    private DBHelper dbHelper;
+
+    @Inject
+    private CayenneContext context;
+
+    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 createSevenMtTable1sDataSet() throws Exception {
+        for (int i = 1; i <= 7; i++) {
+            tMtTable1.insert(i, "g" + i, "s" + i);
+        }
+    }
+
+    public void testLocalCache() throws Exception {
+        createSevenMtTable1sDataSet();
+
+        SelectQuery query = new SelectQuery(ClientMtTable1.class);
+        query.addOrdering(ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY, SortOrder.ASCENDING);
+        query.setPageSize(3);
+        query.setCacheStrategy(QueryCacheStrategy.LOCAL_CACHE);
+
+        List<ClientMtTable1> result1 = context.performQuery(query);
+        assertEquals(7, result1.size());
+
+        // ensure we can resolve all objects without a failure...
+        for (ClientMtTable1 x : result1) {
+            x.getGlobalAttribute1();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextPaginatedListCachingTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextPaginatedListCachingTest.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextPaginatedListCachingTest.java
deleted file mode 100644
index 479948e..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextPaginatedListCachingTest.java
+++ /dev/null
@@ -1,75 +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;
-
-import java.util.List;
-
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.query.QueryCacheStrategy;
-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.unit.di.client.ClientCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class CayenneContextPaginatedListCachingTest extends ClientCase {
-
-    @Inject
-    private DBHelper dbHelper;
-
-    @Inject
-    private CayenneContext context;
-
-    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 createSevenMtTable1sDataSet() throws Exception {
-        for (int i = 1; i <= 7; i++) {
-            tMtTable1.insert(i, "g" + i, "s" + i);
-        }
-    }
-
-    public void testLocalCache() throws Exception {
-        createSevenMtTable1sDataSet();
-
-        SelectQuery query = new SelectQuery(ClientMtTable1.class);
-        query.addOrdering(ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY, SortOrder.ASCENDING);
-        query.setPageSize(3);
-        query.setCacheStrategy(QueryCacheStrategy.LOCAL_CACHE);
-
-        List<ClientMtTable1> result1 = context.performQuery(query);
-        assertEquals(7, result1.size());
-
-        // ensure we can resolve all objects without a failure...
-        for (ClientMtTable1 x : result1) {
-            x.getGlobalAttribute1();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextPrimitiveIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextPrimitiveIT.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextPrimitiveIT.java
new file mode 100644
index 0000000..e3865d0
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextPrimitiveIT.java
@@ -0,0 +1,100 @@
+/*****************************************************************
+ *   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;
+
+import org.apache.cayenne.di.Inject;
+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.ClientMtTablePrimitives;
+import org.apache.cayenne.testdo.mt.MtTablePrimitives;
+import org.apache.cayenne.unit.UnitDbAdapter;
+import org.apache.cayenne.unit.di.client.ClientCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+import java.sql.Types;
+import java.util.List;
+
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class CayenneContextPrimitiveIT extends ClientCase {
+
+    @Inject
+    private CayenneContext context;
+    
+    @Inject
+    private UnitDbAdapter accessStackAdapter;
+
+    @Inject
+    private DBHelper dbHelper;
+
+    private TableHelper tMtTablePrimitives;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("MT_TABLE_PRIMITIVES");
+
+        int bool = accessStackAdapter.supportsBoolean() ? Types.BOOLEAN : Types.INTEGER;
+        
+        tMtTablePrimitives = new TableHelper(dbHelper, "MT_TABLE_PRIMITIVES");
+        tMtTablePrimitives.setColumns("ID", "BOOLEAN_COLUMN", "INT_COLUMN").setColumnTypes(
+                Types.INTEGER,
+                bool,
+                Types.INTEGER);
+    }
+
+    private void createTwoPrimitivesDataSet() throws Exception {
+        tMtTablePrimitives.insert(1, accessStackAdapter.supportsBoolean() ? true : 1, 0);
+        tMtTablePrimitives.insert(2, accessStackAdapter.supportsBoolean() ? false : 0, 5);
+    }
+
+    public void testSelectPrimitives() throws Exception {
+        createTwoPrimitivesDataSet();
+
+        SelectQuery query = new SelectQuery(ClientMtTablePrimitives.class);
+        query.addOrdering("db:" + MtTablePrimitives.ID_PK_COLUMN, SortOrder.ASCENDING);
+
+        List<ClientMtTablePrimitives> results = context.performQuery(query);
+        assertTrue(results.get(0).isBooleanColumn());
+        assertFalse(results.get(1).isBooleanColumn());
+
+        assertEquals(0, results.get(0).getIntColumn());
+        assertEquals(5, results.get(1).getIntColumn());
+    }
+
+    public void testCommitChangesPrimitives() throws Exception {
+
+        ClientMtTablePrimitives object = context.newObject(ClientMtTablePrimitives.class);
+
+        object.setBooleanColumn(true);
+        object.setIntColumn(3);
+
+        context.commitChanges();
+
+        assertTrue(tMtTablePrimitives.getBoolean("BOOLEAN_COLUMN"));
+        assertEquals(3, tMtTablePrimitives.getInt("INT_COLUMN"));
+
+        object.setBooleanColumn(false);
+        object.setIntColumn(8);
+        context.commitChanges();
+
+        assertFalse(tMtTablePrimitives.getBoolean("BOOLEAN_COLUMN"));
+        assertEquals(8, tMtTablePrimitives.getInt("INT_COLUMN"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextPrimitiveTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextPrimitiveTest.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextPrimitiveTest.java
deleted file mode 100644
index 2b02654..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextPrimitiveTest.java
+++ /dev/null
@@ -1,100 +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;
-
-import java.sql.Types;
-import java.util.List;
-
-import org.apache.cayenne.di.Inject;
-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.ClientMtTablePrimitives;
-import org.apache.cayenne.testdo.mt.MtTablePrimitives;
-import org.apache.cayenne.unit.UnitDbAdapter;
-import org.apache.cayenne.unit.di.client.ClientCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class CayenneContextPrimitiveTest extends ClientCase {
-
-    @Inject
-    private CayenneContext context;
-    
-    @Inject
-    private UnitDbAdapter accessStackAdapter;
-
-    @Inject
-    private DBHelper dbHelper;
-
-    private TableHelper tMtTablePrimitives;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("MT_TABLE_PRIMITIVES");
-
-        int bool = accessStackAdapter.supportsBoolean() ? Types.BOOLEAN : Types.INTEGER;
-        
-        tMtTablePrimitives = new TableHelper(dbHelper, "MT_TABLE_PRIMITIVES");
-        tMtTablePrimitives.setColumns("ID", "BOOLEAN_COLUMN", "INT_COLUMN").setColumnTypes(
-                Types.INTEGER,
-                bool,
-                Types.INTEGER);
-    }
-
-    private void createTwoPrimitivesDataSet() throws Exception {
-        tMtTablePrimitives.insert(1, accessStackAdapter.supportsBoolean() ? true : 1, 0);
-        tMtTablePrimitives.insert(2, accessStackAdapter.supportsBoolean() ? false : 0, 5);
-    }
-
-    public void testSelectPrimitives() throws Exception {
-        createTwoPrimitivesDataSet();
-
-        SelectQuery query = new SelectQuery(ClientMtTablePrimitives.class);
-        query.addOrdering("db:" + MtTablePrimitives.ID_PK_COLUMN, SortOrder.ASCENDING);
-
-        List<ClientMtTablePrimitives> results = context.performQuery(query);
-        assertTrue(results.get(0).isBooleanColumn());
-        assertFalse(results.get(1).isBooleanColumn());
-
-        assertEquals(0, results.get(0).getIntColumn());
-        assertEquals(5, results.get(1).getIntColumn());
-    }
-
-    public void testCommitChangesPrimitives() throws Exception {
-
-        ClientMtTablePrimitives object = context.newObject(ClientMtTablePrimitives.class);
-
-        object.setBooleanColumn(true);
-        object.setIntColumn(3);
-
-        context.commitChanges();
-
-        assertTrue(tMtTablePrimitives.getBoolean("BOOLEAN_COLUMN"));
-        assertEquals(3, tMtTablePrimitives.getInt("INT_COLUMN"));
-
-        object.setBooleanColumn(false);
-        object.setIntColumn(8);
-        context.commitChanges();
-
-        assertFalse(tMtTablePrimitives.getBoolean("BOOLEAN_COLUMN"));
-        assertEquals(8, tMtTablePrimitives.getInt("INT_COLUMN"));
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextRefreshQueryIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextRefreshQueryIT.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextRefreshQueryIT.java
new file mode 100644
index 0000000..2100320
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextRefreshQueryIT.java
@@ -0,0 +1,76 @@
+/*****************************************************************
+ *   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;
+
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.query.RefreshQuery;
+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 CayenneContextRefreshQueryIT extends ClientCase {
+
+    @Inject
+    private DBHelper dbHelper;
+
+    @Inject
+    private CayenneContext context;
+
+    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");
+    }
+
+    private void createM1AndTwoM2sDataSet() throws Exception {
+        tMtTable1.insert(1, "g1", "s1");
+        tMtTable2.insert(1, 1, "g1").insert(2, 1, "g1");
+    }
+
+    private void delete1M2DataSet() throws Exception {
+        tMtTable2.delete().where("TABLE2_ID", 1).execute();
+    }
+
+    public void testRefreshToMany() throws Exception {
+
+        createM1AndTwoM2sDataSet();
+
+        ClientMtTable1 a = Cayenne.objectForPK(context, ClientMtTable1.class, 1);
+        assertEquals(2, a.getTable2Array().size());
+
+        delete1M2DataSet();
+
+        RefreshQuery refresh = new RefreshQuery(a);
+        context.performGenericQuery(refresh);
+        assertEquals(PersistenceState.HOLLOW, a.getPersistenceState());
+        assertEquals(1, a.getTable2Array().size());
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextRefreshQueryTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextRefreshQueryTest.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextRefreshQueryTest.java
deleted file mode 100644
index ca7c476..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextRefreshQueryTest.java
+++ /dev/null
@@ -1,76 +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;
-
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.query.RefreshQuery;
-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 CayenneContextRefreshQueryTest extends ClientCase {
-
-    @Inject
-    private DBHelper dbHelper;
-
-    @Inject
-    private CayenneContext context;
-
-    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");
-    }
-
-    private void createM1AndTwoM2sDataSet() throws Exception {
-        tMtTable1.insert(1, "g1", "s1");
-        tMtTable2.insert(1, 1, "g1").insert(2, 1, "g1");
-    }
-
-    private void delete1M2DataSet() throws Exception {
-        tMtTable2.delete().where("TABLE2_ID", 1).execute();
-    }
-
-    public void testRefreshToMany() throws Exception {
-
-        createM1AndTwoM2sDataSet();
-
-        ClientMtTable1 a = Cayenne.objectForPK(context, ClientMtTable1.class, 1);
-        assertEquals(2, a.getTable2Array().size());
-
-        delete1M2DataSet();
-
-        RefreshQuery refresh = new RefreshQuery(a);
-        context.performGenericQuery(refresh);
-        assertEquals(PersistenceState.HOLLOW, a.getPersistenceState());
-        assertEquals(1, a.getTable2Array().size());
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextRelationshipsIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextRelationshipsIT.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextRelationshipsIT.java
new file mode 100644
index 0000000..fbc9f20
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextRelationshipsIT.java
@@ -0,0 +1,100 @@
+/*****************************************************************
+ *   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;
+
+import org.apache.cayenne.access.DataContext;
+import org.apache.cayenne.di.Inject;
+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.testdo.mt.MtTable1;
+import org.apache.cayenne.testdo.mt.MtTable2;
+import org.apache.cayenne.unit.di.client.ClientCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class CayenneContextRelationshipsIT extends ClientCase {
+
+    @Inject
+    private DBHelper dbHelper;
+
+    @Inject
+    private CayenneContext context;
+
+    @Inject
+    private DataContext serverContext;
+
+    private TableHelper tMtTable1;
+    private TableHelper tMtTable2;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("MT_TABLE2");
+        dbHelper.deleteAll("MT_TABLE1");
+        dbHelper.deleteAll("MT_JOIN45");
+        dbHelper.deleteAll("MT_TABLE4");
+        dbHelper.deleteAll("MT_TABLE5");
+
+        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");
+    }
+
+    public void testLostUncommittedToOneModifications_Client() throws Exception {
+
+        tMtTable1.insert(1, "G1", "S1");
+        tMtTable1.insert(2, "G2", "S2");
+        tMtTable2.insert(33, 1, "GX");
+
+        ClientMtTable2 o = Cayenne.objectForPK(context, ClientMtTable2.class, 33);
+
+        ClientMtTable1 r2 = Cayenne.objectForPK(context, ClientMtTable1.class, 2);
+        ClientMtTable1 r1 = o.getTable1();
+
+        o.setTable1(r2);
+
+        assertSame(r2, o.getTable1());
+
+        // see CAY-1757 - this used to reset our changes
+        assertFalse(r1.getTable2Array().contains(o));
+        assertSame(r2, o.getTable1());
+    }
+
+    public void testLostUncommittedToOneModifications_Server() throws Exception {
+
+        tMtTable1.insert(1, "G1", "S1");
+        tMtTable1.insert(2, "G2", "S2");
+        tMtTable2.insert(33, 1, "GX");
+
+        MtTable2 o = Cayenne.objectForPK(serverContext, MtTable2.class, 33);
+
+        MtTable1 r2 = Cayenne.objectForPK(serverContext, MtTable1.class, 2);
+        MtTable1 r1 = o.getTable1();
+
+        o.setTable1(r2);
+
+        assertSame(r2, o.getTable1());
+
+        assertFalse(r1.getTable2Array().contains(o));
+        assertSame(r2, o.getTable1());
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextRelationshipsTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextRelationshipsTest.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextRelationshipsTest.java
deleted file mode 100644
index 38aa1b4..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextRelationshipsTest.java
+++ /dev/null
@@ -1,100 +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;
-
-import org.apache.cayenne.access.DataContext;
-import org.apache.cayenne.di.Inject;
-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.testdo.mt.MtTable1;
-import org.apache.cayenne.testdo.mt.MtTable2;
-import org.apache.cayenne.unit.di.client.ClientCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class CayenneContextRelationshipsTest extends ClientCase {
-
-    @Inject
-    private DBHelper dbHelper;
-
-    @Inject
-    private CayenneContext context;
-
-    @Inject
-    private DataContext serverContext;
-
-    private TableHelper tMtTable1;
-    private TableHelper tMtTable2;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("MT_TABLE2");
-        dbHelper.deleteAll("MT_TABLE1");
-        dbHelper.deleteAll("MT_JOIN45");
-        dbHelper.deleteAll("MT_TABLE4");
-        dbHelper.deleteAll("MT_TABLE5");
-
-        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");
-    }
-
-    public void testLostUncommittedToOneModifications_Client() throws Exception {
-
-        tMtTable1.insert(1, "G1", "S1");
-        tMtTable1.insert(2, "G2", "S2");
-        tMtTable2.insert(33, 1, "GX");
-
-        ClientMtTable2 o = Cayenne.objectForPK(context, ClientMtTable2.class, 33);
-
-        ClientMtTable1 r2 = Cayenne.objectForPK(context, ClientMtTable1.class, 2);
-        ClientMtTable1 r1 = o.getTable1();
-
-        o.setTable1(r2);
-
-        assertSame(r2, o.getTable1());
-
-        // see CAY-1757 - this used to reset our changes
-        assertFalse(r1.getTable2Array().contains(o));
-        assertSame(r2, o.getTable1());
-    }
-
-    public void testLostUncommittedToOneModifications_Server() throws Exception {
-
-        tMtTable1.insert(1, "G1", "S1");
-        tMtTable1.insert(2, "G2", "S2");
-        tMtTable2.insert(33, 1, "GX");
-
-        MtTable2 o = Cayenne.objectForPK(serverContext, MtTable2.class, 33);
-
-        MtTable1 r2 = Cayenne.objectForPK(serverContext, MtTable1.class, 2);
-        MtTable1 r1 = o.getTable1();
-
-        o.setTable1(r2);
-
-        assertSame(r2, o.getTable1());
-
-        assertFalse(r1.getTable2Array().contains(o));
-        assertSame(r2, o.getTable1());
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextSQLTemplateIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextSQLTemplateIT.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextSQLTemplateIT.java
new file mode 100644
index 0000000..1cd129b
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextSQLTemplateIT.java
@@ -0,0 +1,54 @@
+/*****************************************************************
+ *   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;
+
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.query.SQLTemplate;
+import org.apache.cayenne.test.jdbc.DBHelper;
+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 CayenneContextSQLTemplateIT extends ClientCase {
+
+    @Inject
+    private DBHelper dbHelper;
+
+    @Inject
+    private CayenneContext context;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("MT_TABLE2");
+        dbHelper.deleteAll("MT_TABLE1");
+    }
+
+    public void testObjectRoot() throws Exception {
+
+        assertNull(Cayenne.objectForPK(context, ClientMtTable1.class, 1));
+        context.performGenericQuery(new SQLTemplate(
+                ClientMtTable1.class,
+                "insert into MT_TABLE1 "
+                        + "(TABLE1_ID, GLOBAL_ATTRIBUTE1, SERVER_ATTRIBUTE1) "
+                        + "values (1, 'g1', 's1')"));
+
+        assertNotNull(Cayenne.objectForPK(context, ClientMtTable1.class, 1));
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextSQLTemplateTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextSQLTemplateTest.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextSQLTemplateTest.java
deleted file mode 100644
index ac71e78..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextSQLTemplateTest.java
+++ /dev/null
@@ -1,54 +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;
-
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.query.SQLTemplate;
-import org.apache.cayenne.test.jdbc.DBHelper;
-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 CayenneContextSQLTemplateTest extends ClientCase {
-
-    @Inject
-    private DBHelper dbHelper;
-
-    @Inject
-    private CayenneContext context;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("MT_TABLE2");
-        dbHelper.deleteAll("MT_TABLE1");
-    }
-
-    public void testObjectRoot() throws Exception {
-
-        assertNull(Cayenne.objectForPK(context, ClientMtTable1.class, 1));
-        context.performGenericQuery(new SQLTemplate(
-                ClientMtTable1.class,
-                "insert into MT_TABLE1 "
-                        + "(TABLE1_ID, GLOBAL_ATTRIBUTE1, SERVER_ATTRIBUTE1) "
-                        + "values (1, 'g1', 's1')"));
-
-        assertNotNull(Cayenne.objectForPK(context, ClientMtTable1.class, 1));
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextServerDiffsIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextServerDiffsIT.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextServerDiffsIT.java
new file mode 100644
index 0000000..4faed91
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextServerDiffsIT.java
@@ -0,0 +1,153 @@
+/*****************************************************************
+ *   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;
+
+import org.apache.cayenne.access.ClientServerChannel;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.map.LifecycleEvent;
+import org.apache.cayenne.reflect.LifecycleCallbackRegistry;
+import org.apache.cayenne.remote.ClientChannelServerDiffsListener1;
+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;
+
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class CayenneContextServerDiffsIT extends ClientCase {
+
+    @Inject
+    private ClientServerChannel clientServerChannel;
+
+    @Inject
+    private CayenneContext context;
+
+    public void testReturnDiffInPrePersist() {
+
+        LifecycleCallbackRegistry callbackRegistry = clientServerChannel
+                .getEntityResolver()
+                .getCallbackRegistry();
+
+        try {
+
+            callbackRegistry.addListener(
+                    LifecycleEvent.POST_ADD,
+                    MtTable1.class,
+                    new ClientChannelServerDiffsListener1(),
+                    "prePersist");
+
+            ClientMtTable1 o = context.newObject(ClientMtTable1.class);
+            o.setServerAttribute1("YY");
+            context.commitChanges();
+
+            assertFalse(o.getObjectId().isTemporary());
+            assertEquals(PersistenceState.COMMITTED, o.getPersistenceState());
+            assertEquals("XXX", o.getGlobalAttribute1());
+        }
+        finally {
+            callbackRegistry.clear();
+        }
+    }
+
+    public void testReturnDiffInPreUpdate() {
+        LifecycleCallbackRegistry callbackRegistry = clientServerChannel
+                .getEntityResolver()
+                .getCallbackRegistry();
+
+        try {
+
+            callbackRegistry.addListener(
+                    LifecycleEvent.PRE_UPDATE,
+                    MtTable1.class,
+                    new ClientChannelServerDiffsListener1(),
+                    "preUpdate");
+
+            ClientMtTable1 o = context.newObject(ClientMtTable1.class);
+            o.setServerAttribute1("YY");
+            context.commitChanges();
+
+            assertNull(o.getGlobalAttribute1());
+
+            o.setServerAttribute1("XX");
+            context.commitChanges();
+
+            assertFalse(o.getObjectId().isTemporary());
+            assertEquals(PersistenceState.COMMITTED, o.getPersistenceState());
+            assertEquals("111", o.getGlobalAttribute1());
+        }
+        finally {
+            callbackRegistry.clear();
+        }
+    }
+
+    public void testReturnDiffClientArcChanges() {
+
+        LifecycleCallbackRegistry callbackRegistry = clientServerChannel
+                .getEntityResolver()
+                .getCallbackRegistry();
+
+        try {
+            callbackRegistry.addListener(
+                    LifecycleEvent.POST_ADD,
+                    MtTable1.class,
+                    new ClientChannelServerDiffsListener1(),
+                    "prePersist");
+
+            ClientMtTable1 o = context.newObject(ClientMtTable1.class);
+            ClientMtTable2 o1 = context.newObject(ClientMtTable2.class);
+            o.addToTable2Array(o1);
+            context.commitChanges();
+
+            assertFalse(o.getObjectId().isTemporary());
+            assertEquals(PersistenceState.COMMITTED, o.getPersistenceState());
+            assertEquals("XXX", o.getGlobalAttribute1());
+        }
+        finally {
+            callbackRegistry.clear();
+        }
+    }
+
+    public void testReturnDiffServerArcChanges() {
+
+        LifecycleCallbackRegistry callbackRegistry = clientServerChannel
+                .getEntityResolver()
+                .getCallbackRegistry();
+
+        try {
+            callbackRegistry.addListener(
+                    LifecycleEvent.POST_ADD,
+                    MtTable1.class,
+                    new ClientChannelServerDiffsListener1(),
+                    "prePersistAddRelationship");
+
+            ClientMtTable1 o = context.newObject(ClientMtTable1.class);
+            ClientMtTable2 o1 = context.newObject(ClientMtTable2.class);
+            o.addToTable2Array(o1);
+            context.commitChanges();
+
+            assertFalse(o.getObjectId().isTemporary());
+            assertEquals(PersistenceState.COMMITTED, o.getPersistenceState());
+            assertEquals(2, o.getTable2Array().size());
+
+        }
+        finally {
+            callbackRegistry.clear();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextServerDiffsTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextServerDiffsTest.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextServerDiffsTest.java
deleted file mode 100644
index 54027a1..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextServerDiffsTest.java
+++ /dev/null
@@ -1,153 +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;
-
-import org.apache.cayenne.access.ClientServerChannel;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.map.LifecycleEvent;
-import org.apache.cayenne.reflect.LifecycleCallbackRegistry;
-import org.apache.cayenne.remote.ClientChannelServerDiffsListener1;
-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;
-
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class CayenneContextServerDiffsTest extends ClientCase {
-
-    @Inject
-    private ClientServerChannel clientServerChannel;
-
-    @Inject
-    private CayenneContext context;
-
-    public void testReturnDiffInPrePersist() {
-
-        LifecycleCallbackRegistry callbackRegistry = clientServerChannel
-                .getEntityResolver()
-                .getCallbackRegistry();
-
-        try {
-
-            callbackRegistry.addListener(
-                    LifecycleEvent.POST_ADD,
-                    MtTable1.class,
-                    new ClientChannelServerDiffsListener1(),
-                    "prePersist");
-
-            ClientMtTable1 o = context.newObject(ClientMtTable1.class);
-            o.setServerAttribute1("YY");
-            context.commitChanges();
-
-            assertFalse(o.getObjectId().isTemporary());
-            assertEquals(PersistenceState.COMMITTED, o.getPersistenceState());
-            assertEquals("XXX", o.getGlobalAttribute1());
-        }
-        finally {
-            callbackRegistry.clear();
-        }
-    }
-
-    public void testReturnDiffInPreUpdate() {
-        LifecycleCallbackRegistry callbackRegistry = clientServerChannel
-                .getEntityResolver()
-                .getCallbackRegistry();
-
-        try {
-
-            callbackRegistry.addListener(
-                    LifecycleEvent.PRE_UPDATE,
-                    MtTable1.class,
-                    new ClientChannelServerDiffsListener1(),
-                    "preUpdate");
-
-            ClientMtTable1 o = context.newObject(ClientMtTable1.class);
-            o.setServerAttribute1("YY");
-            context.commitChanges();
-
-            assertNull(o.getGlobalAttribute1());
-
-            o.setServerAttribute1("XX");
-            context.commitChanges();
-
-            assertFalse(o.getObjectId().isTemporary());
-            assertEquals(PersistenceState.COMMITTED, o.getPersistenceState());
-            assertEquals("111", o.getGlobalAttribute1());
-        }
-        finally {
-            callbackRegistry.clear();
-        }
-    }
-
-    public void testReturnDiffClientArcChanges() {
-
-        LifecycleCallbackRegistry callbackRegistry = clientServerChannel
-                .getEntityResolver()
-                .getCallbackRegistry();
-
-        try {
-            callbackRegistry.addListener(
-                    LifecycleEvent.POST_ADD,
-                    MtTable1.class,
-                    new ClientChannelServerDiffsListener1(),
-                    "prePersist");
-
-            ClientMtTable1 o = context.newObject(ClientMtTable1.class);
-            ClientMtTable2 o1 = context.newObject(ClientMtTable2.class);
-            o.addToTable2Array(o1);
-            context.commitChanges();
-
-            assertFalse(o.getObjectId().isTemporary());
-            assertEquals(PersistenceState.COMMITTED, o.getPersistenceState());
-            assertEquals("XXX", o.getGlobalAttribute1());
-        }
-        finally {
-            callbackRegistry.clear();
-        }
-    }
-
-    public void testReturnDiffServerArcChanges() {
-
-        LifecycleCallbackRegistry callbackRegistry = clientServerChannel
-                .getEntityResolver()
-                .getCallbackRegistry();
-
-        try {
-            callbackRegistry.addListener(
-                    LifecycleEvent.POST_ADD,
-                    MtTable1.class,
-                    new ClientChannelServerDiffsListener1(),
-                    "prePersistAddRelationship");
-
-            ClientMtTable1 o = context.newObject(ClientMtTable1.class);
-            ClientMtTable2 o1 = context.newObject(ClientMtTable2.class);
-            o.addToTable2Array(o1);
-            context.commitChanges();
-
-            assertFalse(o.getObjectId().isTemporary());
-            assertEquals(PersistenceState.COMMITTED, o.getPersistenceState());
-            assertEquals(2, o.getTable2Array().size());
-
-        }
-        finally {
-            callbackRegistry.clear();
-        }
-    }
-}


[8/8] git commit: Merge Pull request #23 , commit f6640dd9033330cb863fb425160492f4873c8319

Posted by aa...@apache.org.
Merge Pull request #23 , commit f6640dd9033330cb863fb425160492f4873c8319


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

Branch: refs/heads/master
Commit: dd009c6d9db3270ea6893783f1ec993043e1047b
Parents: 5fdb080 fcb1d53
Author: aadamchik <aa...@apache.org>
Authored: Sun Nov 2 10:32:20 2014 +0300
Committer: aadamchik <aa...@apache.org>
Committed: Sun Nov 2 10:33:02 2014 +0300

----------------------------------------------------------------------
 .../apache/cayenne/CayenneContextCayenneIT.java |  55 ++
 .../cayenne/CayenneContextCayenneTest.java      |  55 --
 .../CayenneContextClientChannelEventsIT.java    | 345 ++++++++
 .../CayenneContextClientChannelEventsTest.java  | 345 --------
 .../cayenne/CayenneContextDeleteRulesIT.java    | 111 +++
 .../cayenne/CayenneContextDeleteRulesTest.java  | 111 ---
 .../apache/cayenne/CayenneContextEJBQLIT.java   |  87 ++
 .../apache/cayenne/CayenneContextEJBQLTest.java |  87 --
 .../CayenneContextGraphDiffCompressorIT.java    |  96 +++
 .../CayenneContextGraphDiffCompressorTest.java  |  96 ---
 .../org/apache/cayenne/CayenneContextIT.java    | 351 ++++++++
 .../cayenne/CayenneContextInheritanceIT.java    | 151 ++++
 .../cayenne/CayenneContextInheritanceTest.java  | 151 ----
 .../CayenneContextMapRelationshipIT.java        | 112 +++
 .../CayenneContextMapRelationshipTest.java      | 112 ---
 .../cayenne/CayenneContextMergeHandlerIT.java   |  90 ++
 .../cayenne/CayenneContextMergeHandlerTest.java |  90 --
 .../CayenneContextNamedQueryCachingIT.java      | 133 +++
 .../CayenneContextNamedQueryCachingTest.java    | 133 ---
 .../CayenneContextPaginatedListCachingIT.java   |  75 ++
 .../CayenneContextPaginatedListCachingTest.java |  75 --
 .../cayenne/CayenneContextPrimitiveIT.java      | 100 +++
 .../cayenne/CayenneContextPrimitiveTest.java    | 100 ---
 .../cayenne/CayenneContextRefreshQueryIT.java   |  76 ++
 .../cayenne/CayenneContextRefreshQueryTest.java |  76 --
 .../cayenne/CayenneContextRelationshipsIT.java  | 100 +++
 .../CayenneContextRelationshipsTest.java        | 100 ---
 .../cayenne/CayenneContextSQLTemplateIT.java    |  54 ++
 .../cayenne/CayenneContextSQLTemplateTest.java  |  54 --
 .../cayenne/CayenneContextServerDiffsIT.java    | 153 ++++
 .../cayenne/CayenneContextServerDiffsTest.java  | 153 ----
 .../org/apache/cayenne/CayenneContextTest.java  | 351 --------
 .../cayenne/CayenneContextValidationIT.java     |  89 ++
 .../cayenne/CayenneContextValidationTest.java   |  89 --
 .../CayenneContextWithDataContextIT.java        | 570 ++++++++++++
 .../CayenneContextWithDataContextTest.java      | 570 ------------
 .../apache/cayenne/NestedCayenneContextIT.java  | 864 +++++++++++++++++++
 .../cayenne/NestedCayenneContextTest.java       | 864 -------------------
 .../cayenne/PersistentObjectInContextIT.java    | 142 +++
 .../cayenne/PersistentObjectInContextTest.java  | 142 ---
 .../cayenne/access/ClientServerChannelIT.java   | 260 ++++++
 .../access/ClientServerChannelQueryIT.java      | 239 +++++
 .../access/ClientServerChannelQueryTest.java    | 239 -----
 .../cayenne/access/ClientServerChannelTest.java | 260 ------
 .../cayenne/map/ClientEntityResolverIT.java     |  62 ++
 .../cayenne/map/ClientEntityResolverTest.java   |  62 --
 .../cayenne/query/ClientExpressionIT.java       | 319 +++++++
 .../cayenne/query/ClientExpressionTest.java     | 319 -------
 .../query/ClientSelectQueryExpressionIT.java    |  71 ++
 .../query/ClientSelectQueryExpressionTest.java  |  71 --
 .../remote/CayenneContextDeletionIT.java        |  38 +
 .../remote/CayenneContextDeletionTest.java      |  38 -
 .../remote/ClientChannelServerDiffsIT.java      | 263 ++++++
 .../remote/ClientChannelServerDiffsTest.java    | 263 ------
 .../cayenne/remote/LightSuperClassIT.java       |  95 ++
 .../cayenne/remote/LightSuperClassTest.java     |  95 --
 .../remote/NestedObjectContextLocalIT.java      |  58 ++
 .../remote/NestedObjectContextLocalTest.java    |  58 --
 .../NestedObjectContextParentEventsIT.java      |  64 ++
 .../NestedObjectContextParentEventsTest.java    |  64 --
 .../remote/NestedObjectContextPeerEventsIT.java | 149 ++++
 .../NestedObjectContextPeerEventsTest.java      | 149 ----
 .../remote/NestedObjectContextRollbackIT.java   |  71 ++
 .../remote/NestedObjectContextRollbackTest.java |  71 --
 .../cayenne/remote/ROPPrefetchToManyMapIT.java  |  70 ++
 .../remote/ROPPrefetchToManyMapTest.java        |  70 --
 .../cayenne/remote/RelationshipChangeIT.java    |  60 ++
 .../cayenne/remote/RelationshipChangeTest.java  |  60 --
 .../cayenne/remote/RemoteCallbacksIT.java       | 118 +++
 .../cayenne/remote/RemoteCallbacksTest.java     | 118 ---
 .../remote/RemoteIncrementalFaultListIT.java    | 266 ++++++
 .../remote/RemoteIncrementalFaultListTest.java  | 266 ------
 .../apache/cayenne/remote/RemoteRollbackIT.java | 147 ++++
 .../cayenne/remote/RemoteRollbackTest.java      | 147 ----
 .../apache/cayenne/remote/ValueInjectorIT.java  |  73 ++
 .../cayenne/remote/ValueInjectorTest.java       |  73 --
 .../unit/di/client/ClientCaseSelfIT.java        |  46 +
 .../unit/di/client/ClientCaseSelfTest.java      |  46 -
 .../cayenne/util/ObjectDetachOperationIT.java   | 112 +++
 .../cayenne/util/ObjectDetachOperationTest.java | 112 ---
 .../util/ShallowMergeOperation_ClientIT.java    | 210 +++++
 .../util/ShallowMergeOperation_ClientTest.java  | 210 -----
 82 files changed, 6545 insertions(+), 6545 deletions(-)
----------------------------------------------------------------------



[5/8] Rename Integration Tests in cayenne-client (*IT.java instead of *Test.java)

Posted by aa...@apache.org.
http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextTest.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextTest.java
deleted file mode 100644
index 405036e..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextTest.java
+++ /dev/null
@@ -1,351 +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;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.event.DefaultEventManager;
-import org.apache.cayenne.event.EventManager;
-import org.apache.cayenne.event.MockEventManager;
-import org.apache.cayenne.graph.CompoundDiff;
-import org.apache.cayenne.graph.GraphDiff;
-import org.apache.cayenne.graph.MockGraphDiff;
-import org.apache.cayenne.graph.NodeIdChangeOperation;
-import org.apache.cayenne.map.DataMap;
-import org.apache.cayenne.map.EntityResolver;
-import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.query.Query;
-import org.apache.cayenne.remote.BootstrapMessage;
-import org.apache.cayenne.remote.ClientChannel;
-import org.apache.cayenne.remote.ClientConnection;
-import org.apache.cayenne.remote.ClientMessage;
-import org.apache.cayenne.testdo.mt.ClientMtTable1;
-import org.apache.cayenne.unit.di.client.ClientCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-import org.apache.cayenne.util.GenericResponse;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class CayenneContextTest extends ClientCase {
-
-    @Inject
-    private ObjectContext serverContext;
-
-    public void testConstructor() {
-
-        CayenneContext context = new CayenneContext();
-
-        // test default property parameters
-        assertNotNull(context.getGraphManager());
-        assertNull(context.channel);
-
-        MockDataChannel channel = new MockDataChannel();
-        context.setChannel(channel);
-        assertSame(channel, context.getChannel());
-    }
-
-    public void testChannel() {
-        MockDataChannel channel = new MockDataChannel();
-        CayenneContext context = new CayenneContext(channel);
-
-        assertSame(channel, context.getChannel());
-    }
-
-    public void testCommitUnchanged() {
-
-        MockDataChannel channel = new MockDataChannel();
-        CayenneContext context = new CayenneContext(channel);
-
-        // no context changes so no connector access is expected
-        context.commitChanges();
-        assertTrue(channel.getRequestObjects().isEmpty());
-    }
-
-    public void testCommitCommandExecuted() {
-
-        MockDataChannel channel = new MockDataChannel(new MockGraphDiff());
-        channel.setEntityResolver(serverContext
-                .getEntityResolver()
-                .getClientEntityResolver());
-        CayenneContext context = new CayenneContext(channel);
-
-        // test that a command is being sent via connector on commit...
-
-        context.internalGraphManager().nodePropertyChanged(
-                new ObjectId("MtTable1"),
-                "x",
-                "y",
-                "z");
-
-        context.commitChanges();
-        assertEquals(1, channel.getRequestObjects().size());
-
-        // expect a sync/commit chain
-        Object mainMessage = channel.getRequestObjects().iterator().next();
-        assertTrue(mainMessage instanceof GraphDiff);
-    }
-
-    public void testCommitChangesNew() {
-        final CompoundDiff diff = new CompoundDiff();
-        final Object newObjectId = new ObjectId("test", "key", "generated");
-        final EventManager eventManager = new DefaultEventManager(0);
-
-        // test that ids that are passed back are actually propagated to the right
-        // objects...
-
-        MockDataChannel channel = new MockDataChannel() {
-
-            @Override
-            public GraphDiff onSync(
-                    ObjectContext originatingContext,
-                    GraphDiff changes,
-                    int syncType) {
-
-                return diff;
-            }
-
-            // must provide a channel with working event manager
-            @Override
-            public EventManager getEventManager() {
-                return eventManager;
-            }
-        };
-
-        CayenneContext context = new CayenneContext(channel);
-        ObjEntity entity = new ObjEntity("test_entity");
-        entity.setClassName(MockPersistentObject.class.getName());
-
-        DataMap dataMap = new DataMap("test");
-        dataMap.addObjEntity(entity);
-        Collection<DataMap> entities = Collections.singleton(dataMap);
-        context.setEntityResolver(new EntityResolver(entities));
-        Persistent object = context.newObject(MockPersistentObject.class);
-
-        // record change here to make it available to the anonymous connector method..
-        diff.add(new NodeIdChangeOperation(object.getObjectId(), newObjectId));
-
-        // check that a generated object ID is assigned back to the object...
-        assertNotSame(newObjectId, object.getObjectId());
-        context.commitChanges();
-        assertSame(newObjectId, object.getObjectId());
-        assertSame(object, context.graphManager.getNode(newObjectId));
-    }
-
-    public void testNewObject() {
-
-        CayenneContext context = new CayenneContext(new MockDataChannel());
-
-        ObjEntity entity = new ObjEntity("test_entity");
-        entity.setClassName(MockPersistentObject.class.getName());
-
-        DataMap dataMap = new DataMap("test");
-        dataMap.addObjEntity(entity);
-        Collection<DataMap> entities = Collections.singleton(dataMap);
-        context.setEntityResolver(new EntityResolver(entities));
-
-        Persistent object = context.newObject(MockPersistentObject.class);
-        assertNotNull(object);
-        assertTrue(object instanceof MockPersistentObject);
-        assertEquals(PersistenceState.NEW, object.getPersistenceState());
-        assertSame(context, object.getObjectContext());
-        assertTrue(context
-                .internalGraphManager()
-                .dirtyNodes(PersistenceState.NEW)
-                .contains(object));
-        assertNotNull(object.getObjectId());
-        assertTrue(object.getObjectId().isTemporary());
-    }
-
-    public void testDeleteObject() {
-
-        CayenneContext context = new CayenneContext(new MockDataChannel());
-        ObjEntity entity = new ObjEntity("test_entity");
-        entity.setClassName(MockPersistentObject.class.getName());
-
-        DataMap dataMap = new DataMap("test");
-        dataMap.addObjEntity(entity);
-        Collection<DataMap> entities = Collections.singleton(dataMap);
-        context.setEntityResolver(new EntityResolver(entities));
-
-        // TRANSIENT ... should quietly ignore it
-        Persistent transientObject = new MockPersistentObject();
-        context.deleteObjects(transientObject);
-        assertEquals(PersistenceState.TRANSIENT, transientObject.getPersistenceState());
-
-        // NEW ... should make it TRANSIENT
-        // create via context to make sure that object store would register it
-        Persistent newObject = context.newObject(MockPersistentObject.class);
-        assertNotNull(newObject.getObjectContext());
-        context.deleteObjects(newObject);
-        assertNull(newObject.getObjectContext());
-        assertEquals(PersistenceState.TRANSIENT, newObject.getPersistenceState());
-        assertFalse(context
-                .internalGraphManager()
-                .dirtyNodes()
-                .contains(newObject.getObjectId()));
-
-        // see CAY-547 for details...
-        assertFalse(context.internalGraphManager().dirtyNodes().contains(null));
-
-        // COMMITTED
-        Persistent committed = new MockPersistentObject();
-        committed.setPersistenceState(PersistenceState.COMMITTED);
-        committed.setObjectId(new ObjectId("test_entity", "key", "value1"));
-        committed.setObjectContext(context);
-        context.deleteObjects(committed);
-        assertEquals(PersistenceState.DELETED, committed.getPersistenceState());
-
-        // MODIFIED
-        Persistent modified = new MockPersistentObject();
-        modified.setPersistenceState(PersistenceState.MODIFIED);
-        modified.setObjectId(new ObjectId("test_entity", "key", "value2"));
-        modified.setObjectContext(context);
-        context.deleteObjects(modified);
-        assertEquals(PersistenceState.DELETED, modified.getPersistenceState());
-
-        // DELETED
-        Persistent deleted = new MockPersistentObject();
-        deleted.setPersistenceState(PersistenceState.DELETED);
-        deleted.setObjectId(new ObjectId("test_entity", "key", "value3"));
-        deleted.setObjectContext(context);
-        context.deleteObjects(deleted);
-        assertEquals(PersistenceState.DELETED, committed.getPersistenceState());
-    }
-
-    public void testBeforePropertyReadShouldInflateHollow() {
-
-        ObjectId gid = new ObjectId("MtTable1", "a", "b");
-        final ClientMtTable1 inflated = new ClientMtTable1();
-        inflated.setPersistenceState(PersistenceState.COMMITTED);
-        inflated.setObjectId(gid);
-        inflated.setGlobalAttribute1("abc");
-
-        ClientConnection connection = mock(ClientConnection.class);
-        when(connection.sendMessage((ClientMessage) any())).thenAnswer(
-                new Answer<Object>() {
-
-                    public Object answer(InvocationOnMock invocation) {
-                        ClientMessage arg = (ClientMessage) invocation.getArguments()[0];
-
-                        if (arg instanceof BootstrapMessage) {
-                            return new EntityResolver();
-                        }
-                        else {
-                            return new GenericResponse(Arrays.asList(inflated));
-                        }
-                    }
-                });
-
-        ClientChannel channel = new ClientChannel(
-                connection,
-                false,
-                new MockEventManager(),
-                false);
-
-        // check that a HOLLOW object is infalted on "beforePropertyRead"
-        ClientMtTable1 hollow = new ClientMtTable1();
-        hollow.setPersistenceState(PersistenceState.HOLLOW);
-        hollow.setObjectId(gid);
-
-        final boolean[] selectExecuted = new boolean[1];
-        CayenneContext context = new CayenneContext(channel) {
-
-            @Override
-            public List<?> performQuery(Query query) {
-                selectExecuted[0] = true;
-                return super.performQuery(query);
-            }
-        };
-
-        context.setEntityResolver(serverContext
-                .getEntityResolver()
-                .getClientEntityResolver());
-
-        context.graphManager.registerNode(hollow.getObjectId(), hollow);
-
-        // testing this...
-        context
-                .prepareForAccess(
-                        hollow,
-                        ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY,
-                        false);
-        assertTrue(selectExecuted[0]);
-        assertSame(hollow, context.getGraphManager().getNode(gid));
-        assertEquals(
-                inflated.getGlobalAttribute1Direct(),
-                hollow.getGlobalAttribute1Direct());
-        assertEquals(PersistenceState.COMMITTED, hollow.getPersistenceState());
-    }
-
-    public void testBeforeHollowDeleteShouldChangeStateToCommited() {
-
-        ObjectId gid = new ObjectId("MtTable1", "a", "b");
-        final ClientMtTable1 inflated = new ClientMtTable1();
-        inflated.setPersistenceState(PersistenceState.COMMITTED);
-        inflated.setObjectId(gid);
-        inflated.setGlobalAttribute1("abc");
-
-        ClientConnection connection = mock(ClientConnection.class);
-        when(connection.sendMessage((ClientMessage) any())).thenAnswer(
-                new Answer<Object>() {
-
-                    public Object answer(InvocationOnMock invocation) {
-                        ClientMessage arg = (ClientMessage) invocation.getArguments()[0];
-
-                        if (arg instanceof BootstrapMessage) {
-                            return new EntityResolver();
-                        }
-                        else {
-                            return new GenericResponse(Arrays.asList(inflated));
-                        }
-                    }
-                });
-        ClientChannel channel = new ClientChannel(
-                connection,
-                false,
-                new MockEventManager(),
-                false);
-
-        CayenneContext context = new CayenneContext(channel);
-        context.setEntityResolver(serverContext
-                .getEntityResolver()
-                .getClientEntityResolver());
-        ClientMtTable1 hollow = context.localObject(inflated);
-        assertEquals(PersistenceState.HOLLOW, hollow.getPersistenceState());
-
-        // testing this...
-        context.deleteObjects(hollow);
-        assertSame(hollow, context.getGraphManager().getNode(gid));
-        assertEquals(
-                inflated.getGlobalAttribute1Direct(),
-                hollow.getGlobalAttribute1Direct());
-        assertEquals(PersistenceState.DELETED, hollow.getPersistenceState());
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextValidationIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextValidationIT.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextValidationIT.java
new file mode 100644
index 0000000..f8e3c78
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextValidationIT.java
@@ -0,0 +1,89 @@
+/*****************************************************************
+ *   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;
+
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.test.jdbc.DBHelper;
+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.validation.ValidationException;
+
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class CayenneContextValidationIT extends ClientCase {
+
+    @Inject
+    private DBHelper dbHelper;
+
+    @Inject
+    private CayenneContext context;
+
+    @Override
+    protected void setUpAfterInjection() throws Exception {
+        dbHelper.deleteAll("MT_TABLE2");
+        dbHelper.deleteAll("MT_TABLE1");
+    }
+
+    public void testValidate() throws Exception {
+
+        ClientMtTable1 o1 = context.newObject(ClientMtTable1.class);
+        o1.setGlobalAttribute1("G1");
+        o1.resetValidation(false);
+
+        // this one is not validating
+        ClientMtTable2 o2 = context.newObject(ClientMtTable2.class);
+        o2.setTable1(o1);
+
+        context.commitChanges();
+        assertTrue(o1.isValidatedForInsert());
+        assertFalse(o1.isValidatedForDelete());
+        assertFalse(o1.isValidatedForUpdate());
+
+        o1.resetValidation(false);
+        o1.setGlobalAttribute1("G2");
+
+        context.commitChanges();
+        assertFalse(o1.isValidatedForInsert());
+        assertFalse(o1.isValidatedForDelete());
+        assertTrue(o1.isValidatedForUpdate());
+
+        o1.resetValidation(false);
+        context.deleteObjects(o1);
+        context.deleteObjects(o2);
+
+        context.commitChanges();
+        assertFalse(o1.isValidatedForInsert());
+        assertTrue(o1.isValidatedForDelete());
+        assertFalse(o1.isValidatedForUpdate());
+
+        ClientMtTable1 o11 = context.newObject(ClientMtTable1.class);
+        o11.setGlobalAttribute1("G1");
+        o11.resetValidation(true);
+
+        try {
+            context.commitChanges();
+            fail("Validation failure must have prevented commit");
+        }
+        catch (ValidationException e) {
+            // expected
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextValidationTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextValidationTest.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextValidationTest.java
deleted file mode 100644
index fcac894..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextValidationTest.java
+++ /dev/null
@@ -1,89 +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;
-
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.test.jdbc.DBHelper;
-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.validation.ValidationException;
-
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class CayenneContextValidationTest extends ClientCase {
-
-    @Inject
-    private DBHelper dbHelper;
-
-    @Inject
-    private CayenneContext context;
-
-    @Override
-    protected void setUpAfterInjection() throws Exception {
-        dbHelper.deleteAll("MT_TABLE2");
-        dbHelper.deleteAll("MT_TABLE1");
-    }
-
-    public void testValidate() throws Exception {
-
-        ClientMtTable1 o1 = context.newObject(ClientMtTable1.class);
-        o1.setGlobalAttribute1("G1");
-        o1.resetValidation(false);
-
-        // this one is not validating
-        ClientMtTable2 o2 = context.newObject(ClientMtTable2.class);
-        o2.setTable1(o1);
-
-        context.commitChanges();
-        assertTrue(o1.isValidatedForInsert());
-        assertFalse(o1.isValidatedForDelete());
-        assertFalse(o1.isValidatedForUpdate());
-
-        o1.resetValidation(false);
-        o1.setGlobalAttribute1("G2");
-
-        context.commitChanges();
-        assertFalse(o1.isValidatedForInsert());
-        assertFalse(o1.isValidatedForDelete());
-        assertTrue(o1.isValidatedForUpdate());
-
-        o1.resetValidation(false);
-        context.deleteObjects(o1);
-        context.deleteObjects(o2);
-
-        context.commitChanges();
-        assertFalse(o1.isValidatedForInsert());
-        assertTrue(o1.isValidatedForDelete());
-        assertFalse(o1.isValidatedForUpdate());
-
-        ClientMtTable1 o11 = context.newObject(ClientMtTable1.class);
-        o11.setGlobalAttribute1("G1");
-        o11.resetValidation(true);
-
-        try {
-            context.commitChanges();
-            fail("Validation failure must have prevented commit");
-        }
-        catch (ValidationException e) {
-            // expected
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextWithDataContextIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextWithDataContextIT.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextWithDataContextIT.java
new file mode 100644
index 0000000..a5cf087
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextWithDataContextIT.java
@@ -0,0 +1,570 @@
+/*****************************************************************
+ *   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;
+
+import java.sql.Types;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.cayenne.access.ClientServerChannel;
+import org.apache.cayenne.access.DataContext;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.map.LifecycleEvent;
+import org.apache.cayenne.query.ObjectIdQuery;
+import org.apache.cayenne.query.QueryCacheStrategy;
+import org.apache.cayenne.query.SelectQuery;
+import org.apache.cayenne.query.SortOrder;
+import org.apache.cayenne.reflect.LifecycleCallbackRegistry;
+import org.apache.cayenne.remote.RemoteIncrementalFaultList;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.test.jdbc.TableHelper;
+import org.apache.cayenne.test.parallel.ParallelTestContainer;
+import org.apache.cayenne.testdo.mt.ClientMtMeaningfulPk;
+import org.apache.cayenne.testdo.mt.ClientMtReflexive;
+import org.apache.cayenne.testdo.mt.ClientMtTable1;
+import org.apache.cayenne.testdo.mt.ClientMtTable2;
+import org.apache.cayenne.testdo.mt.MtReflexive;
+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;
+
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class CayenneContextWithDataContextIT extends ClientCase {
+
+    @Inject
+    private CayenneContext clientContext;
+
+    @Inject
+    private DBHelper dbHelper;
+
+    @Inject(ClientCase.ROP_CLIENT_KEY)
+    private DataChannelInterceptor clientServerInterceptor;
+
+    @Inject
+    private ClientServerChannel clientServerChannel;
+
+    private TableHelper tMtTable1;
+    private TableHelper tMtTable2;
+
+    private TableHelper tMtMeaningfulPK;
+
+    @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").setColumnTypes(
+                Types.INTEGER, Types.INTEGER, Types.VARCHAR);
+
+        tMtMeaningfulPK = new TableHelper(dbHelper, "MT_MEANINGFUL_PK");
+        tMtMeaningfulPK.setColumns("PK");
+    }
+
+    private void deleteAndCreateTwoMeaningfulPKsDataSet() throws Exception {
+        tMtMeaningfulPK.deleteAll();
+        tMtMeaningfulPK.insert("A");
+        tMtMeaningfulPK.insert("B");
+    }
+
+    private void createTwoMtTable1sAnd2sDataSet() throws Exception {
+        tMtTable1.insert(1, "g1", "s1");
+        tMtTable1.insert(2, "g2", "s2");
+
+        tMtTable2.insert(1, 1, "g1");
+        tMtTable2.insert(2, 1, "g2");
+    }
+
+    private void createEightMtTable1s() throws Exception {
+        for (int i = 1; i <= 8; i++) {
+            tMtTable1.insert(i, "g" + i, "s" + i);
+        }
+    }
+
+    public void testLocalCacheStaysLocal() {
+
+        DataContext serverContext = (DataContext) clientServerChannel.getParentChannel();
+
+        SelectQuery query = new SelectQuery(ClientMtTable1.class);
+        query.setCacheStrategy(QueryCacheStrategy.LOCAL_CACHE);
+
+        assertEquals(0, clientContext.getQueryCache().size());
+        assertEquals(0, serverContext.getQueryCache().size());
+
+        List<?> results = clientContext.performQuery(query);
+
+        assertEquals(1, clientContext.getQueryCache().size());
+        assertSame(results, clientContext.getQueryCache().get(
+                query.getMetaData(clientContext.getEntityResolver())));
+
+        assertEquals(0, serverContext.getQueryCache().size());
+    }
+
+    public void testAddToList() throws Exception {
+
+        ClientMtTable1 t1 = clientContext.newObject(ClientMtTable1.class);
+        ClientMtTable2 t2 = clientContext.newObject(ClientMtTable2.class);
+
+        t1.addToTable2Array(t2);
+        assertEquals(1, t1.getTable2Array().size());
+        assertSame(t1, t2.getTable1());
+
+        // do it again to make sure action can handle series of changes
+        ClientMtTable1 t3 = clientContext.newObject(ClientMtTable1.class);
+        ClientMtTable2 t4 = clientContext.newObject(ClientMtTable2.class);
+
+        t3.addToTable2Array(t4);
+        assertEquals(1, t3.getTable2Array().size());
+        assertSame(t3, t4.getTable1());
+    }
+
+    public void testSetValueHolder() throws Exception {
+
+        ClientMtTable1 t1 = clientContext.newObject(ClientMtTable1.class);
+        ClientMtTable2 t2 = clientContext.newObject(ClientMtTable2.class);
+
+        t2.setTable1(t1);
+        assertEquals(1, t1.getTable2Array().size());
+        assertSame(t1, t2.getTable1());
+    }
+
+    public void testPostAddCallback() throws Exception {
+
+        LifecycleCallbackRegistry callbackRegistry = clientServerChannel
+                .getEntityResolver()
+                .getCallbackRegistry();
+
+        final boolean[] flag = new boolean[1];
+
+        try {
+            callbackRegistry.addListener(MtTable1.class, new LifecycleListener() {
+
+                public void postLoad(Object entity) {
+                }
+
+                public void postPersist(Object entity) {
+                }
+
+                public void postRemove(Object entity) {
+                }
+
+                public void postUpdate(Object entity) {
+                }
+
+                public void postAdd(Object entity) {
+                    flag[0] = true;
+                }
+
+                public void preRemove(Object entity) {
+                }
+
+                public void preUpdate(Object entity) {
+                }
+
+                public void prePersist(Object entity) {
+                }
+            });
+
+            clientContext.newObject(ClientMtTable1.class);
+
+            assertFalse(flag[0]);
+            clientContext.commitChanges();
+            assertTrue(flag[0]);
+        }
+        finally {
+            callbackRegistry.clear();
+        }
+    }
+
+    public void testPostAddOnObjectCallback() throws Exception {
+
+        final DataContext serverContext = (DataContext) clientServerChannel.getParentChannel();
+
+        LifecycleCallbackRegistry callbackRegistry = serverContext
+                .getEntityResolver()
+                .getCallbackRegistry();
+
+        try {
+            callbackRegistry.addCallback(
+                    LifecycleEvent.POST_ADD,
+                    MtTable1.class,
+                    "prePersistMethod");
+
+            final Persistent clientObject = clientContext.newObject(ClientMtTable1.class);
+            clientContext.commitChanges();
+
+        new ParallelTestContainer() {
+
+            @Override
+            protected void assertResult() throws Exception {
+            	// find peer
+            	MtTable1 peer = (MtTable1) serverContext.getGraphManager().getNode(
+                    clientObject.getObjectId());
+
+            	assertNotNull(peer);
+            	assertTrue(peer.isPrePersisted());
+            }
+        }.runTest(1000);
+
+
+        }
+        finally {
+            callbackRegistry.clear();
+        }
+    }
+
+    public void testPreRemoveCallback() throws Exception {
+
+        // an exception was triggered within POST_LOAD callback
+        LifecycleCallbackRegistry callbackRegistry = clientServerChannel
+                .getEntityResolver()
+                .getCallbackRegistry();
+
+        final boolean[] flag = new boolean[1];
+
+        try {
+            callbackRegistry.addListener(MtTable1.class, new LifecycleListener() {
+
+                public void postLoad(Object entity) {
+                }
+
+                public void postPersist(Object entity) {
+                }
+
+                public void postRemove(Object entity) {
+                }
+
+                public void postUpdate(Object entity) {
+                }
+
+                public void postAdd(Object entity) {
+                }
+
+                public void preRemove(Object entity) {
+                    flag[0] = true;
+                }
+
+                public void preUpdate(Object entity) {
+                }
+
+                public void prePersist(Object entity) {
+                }
+            });
+
+            ClientMtTable1 object = clientContext.newObject(ClientMtTable1.class);
+
+            assertFalse(flag[0]);
+            clientContext.commitChanges();
+            assertFalse(flag[0]);
+
+            clientContext.deleteObjects(object);
+            clientContext.commitChanges();
+            assertTrue(flag[0]);
+        }
+        finally {
+            callbackRegistry.clear();
+        }
+    }
+
+    public void testCAY830() throws Exception {
+
+        // an exception was triggered within POST_LOAD callback
+        LifecycleCallbackRegistry callbackRegistry = clientServerChannel
+                .getEntityResolver()
+                .getCallbackRegistry();
+
+        try {
+            callbackRegistry.addListener(MtReflexive.class, new LifecycleListener() {
+
+                public void postLoad(Object entity) {
+                }
+
+                public void postPersist(Object entity) {
+                }
+
+                public void postRemove(Object entity) {
+                }
+
+                public void postUpdate(Object entity) {
+                }
+
+                public void postAdd(Object entity) {
+                }
+
+                public void preRemove(Object entity) {
+                }
+
+                public void preUpdate(Object entity) {
+                }
+
+                public void prePersist(Object entity) {
+                }
+            });
+
+            ClientMtReflexive o1 = clientContext.newObject(ClientMtReflexive.class);
+            o1.setName("parent");
+
+            ClientMtReflexive o2 = clientContext.newObject(ClientMtReflexive.class);
+            o2.setName("child");
+            o2.setToParent(o1);
+            clientContext.commitChanges();
+
+            clientContext.deleteObjects(o1);
+            clientContext.deleteObjects(o2);
+            clientContext.commitChanges();
+            // per CAY-830 an exception is thrown here
+        }
+        finally {
+            callbackRegistry.clear();
+        }
+    }
+
+    public void testRollbackChanges() throws Exception {
+
+        ClientMtTable1 o = clientContext.newObject(ClientMtTable1.class);
+        o.setGlobalAttribute1("1");
+        clientContext.commitChanges();
+
+        assertEquals("1", o.getGlobalAttribute1());
+        o.setGlobalAttribute1("2");
+        assertEquals("2", o.getGlobalAttribute1());
+        clientContext.rollbackChanges();
+
+        assertEquals("1", o.getGlobalAttribute1());
+        assertTrue(clientContext.modifiedObjects().isEmpty());
+    }
+
+    public void testCreateFault() throws Exception {
+        tMtTable1.insert(1, "g1", "s1");
+
+        ObjectId id = new ObjectId("MtTable1", MtTable1.TABLE1_ID_PK_COLUMN, 1);
+
+        Object fault = clientContext.createFault(id);
+        assertTrue(fault instanceof ClientMtTable1);
+
+        ClientMtTable1 o = (ClientMtTable1) fault;
+        assertEquals(PersistenceState.HOLLOW, o.getPersistenceState());
+        assertSame(clientContext, o.getObjectContext());
+        assertNull(o.getGlobalAttribute1Direct());
+
+        // make sure we haven't tripped the fault yet
+        assertEquals(PersistenceState.HOLLOW, o.getPersistenceState());
+
+        // try tripping fault
+        assertEquals("g1", o.getGlobalAttribute1());
+        assertEquals(PersistenceState.COMMITTED, o.getPersistenceState());
+    }
+
+    public void testCreateBadFault() throws Exception {
+        tMtTable1.insert(1, "g1", "s1");
+
+        ObjectId id = new ObjectId("MtTable1", MtTable1.TABLE1_ID_PK_COLUMN, 2);
+
+        Object fault = clientContext.createFault(id);
+        assertTrue(fault instanceof ClientMtTable1);
+
+        ClientMtTable1 o = (ClientMtTable1) fault;
+
+        // try tripping fault
+        try {
+            o.getGlobalAttribute1();
+            fail("resolving bad fault should've thrown");
+        }
+        catch (FaultFailureException e) {
+            // expected
+        }
+    }
+
+    public void testMeaningfulPK() throws Exception {
+        deleteAndCreateTwoMeaningfulPKsDataSet();
+
+        SelectQuery query = new SelectQuery(ClientMtMeaningfulPk.class);
+        query.addOrdering(ClientMtMeaningfulPk.PK_PROPERTY, SortOrder.DESCENDING);
+
+        List<?> results = clientContext.performQuery(query);
+        assertEquals(2, results.size());
+    }
+
+    public void testPrefetchingToOne() throws Exception {
+        createTwoMtTable1sAnd2sDataSet();
+
+        final ObjectId prefetchedId = new ObjectId(
+                "MtTable1",
+                MtTable1.TABLE1_ID_PK_COLUMN,
+                1);
+
+        SelectQuery q = new SelectQuery(ClientMtTable2.class);
+        q.addOrdering(ClientMtTable2.GLOBAL_ATTRIBUTE_PROPERTY, SortOrder.ASCENDING);
+        q.addPrefetch(ClientMtTable2.TABLE1_PROPERTY);
+
+        final List<ClientMtTable2> results = clientContext.performQuery(q);
+
+        clientServerInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                assertEquals(2, results.size());
+
+                for (ClientMtTable2 o : results) {
+                    assertEquals(PersistenceState.COMMITTED, o.getPersistenceState());
+                    assertSame(clientContext, o.getObjectContext());
+
+                    ClientMtTable1 o1 = o.getTable1();
+                    assertNotNull(o1);
+                    assertEquals(PersistenceState.COMMITTED, o1.getPersistenceState());
+                    assertSame(clientContext, o1.getObjectContext());
+                    assertEquals(prefetchedId, o1.getObjectId());
+                }
+            }
+        });
+    }
+
+    public void testPrefetchingToOneNull() throws Exception {
+        tMtTable2.insert(15, null, "g3");
+
+        SelectQuery q = new SelectQuery(ClientMtTable2.class);
+        q.addPrefetch(ClientMtTable2.TABLE1_PROPERTY);
+
+        final List<ClientMtTable2> results = clientContext.performQuery(q);
+
+        clientServerInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+
+                assertEquals(1, results.size());
+
+                ClientMtTable2 o = results.get(0);
+                assertEquals(PersistenceState.COMMITTED, o.getPersistenceState());
+                assertSame(clientContext, o.getObjectContext());
+
+                assertNull(o.getTable1());
+            }
+        });
+    }
+
+    public void testPrefetchingToMany() throws Exception {
+        createTwoMtTable1sAnd2sDataSet();
+
+        SelectQuery q = new SelectQuery(ClientMtTable1.class);
+        q.addOrdering(ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY, SortOrder.ASCENDING);
+        q.addPrefetch(ClientMtTable1.TABLE2ARRAY_PROPERTY);
+
+        final List<ClientMtTable1> results = clientContext.performQuery(q);
+
+        clientServerInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+
+                ClientMtTable1 o1 = results.get(0);
+                assertEquals(PersistenceState.COMMITTED, o1.getPersistenceState());
+                assertSame(clientContext, o1.getObjectContext());
+
+                List<?> children1 = o1.getTable2Array();
+
+                assertEquals(2, children1.size());
+                Iterator<?> it = children1.iterator();
+                while (it.hasNext()) {
+                    ClientMtTable2 o = (ClientMtTable2) it.next();
+                    assertEquals(PersistenceState.COMMITTED, o.getPersistenceState());
+                    assertSame(clientContext, o.getObjectContext());
+
+                    // TODO: fixme... reverse relationship is not connected and will
+                    // cause a fetch
+                    // assertEquals(o1, o.getTable1());
+                }
+            }
+        });
+    }
+
+    public void testPerformPaginatedQuery() throws Exception {
+        createEightMtTable1s();
+
+        SelectQuery query = new SelectQuery(ClientMtTable1.class);
+        query.setPageSize(5);
+        List<ClientMtTable1> objects = clientContext.performQuery(query);
+        assertNotNull(objects);
+        assertTrue(objects instanceof RemoteIncrementalFaultList);
+    }
+
+    public void testPrefetchingToManyEmpty() throws Exception {
+        createTwoMtTable1sAnd2sDataSet();
+
+        SelectQuery q = new SelectQuery(ClientMtTable1.class);
+        q.addOrdering(ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY, SortOrder.ASCENDING);
+        q.addPrefetch(ClientMtTable1.TABLE2ARRAY_PROPERTY);
+
+        final List<ClientMtTable1> results = clientContext.performQuery(q);
+
+        clientServerInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                ClientMtTable1 o2 = results.get(1);
+                assertEquals(PersistenceState.COMMITTED, o2.getPersistenceState());
+                assertSame(clientContext, o2.getObjectContext());
+
+                List<ClientMtTable2> children2 = o2.getTable2Array();
+                assertFalse(((ValueHolder) children2).isFault());
+                assertEquals(0, children2.size());
+            }
+        });
+    }
+
+    public void testOIDQueryInterception() throws Exception {
+
+        final ClientMtTable1 o = clientContext.newObject(ClientMtTable1.class);
+        o.setGlobalAttribute1("aaa");
+
+        // fetch new
+        final ObjectIdQuery q1 = new ObjectIdQuery(
+                o.getObjectId(),
+                false,
+                ObjectIdQuery.CACHE);
+
+        clientServerInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                List<?> objects = clientContext.performQuery(q1);
+                assertEquals(1, objects.size());
+                assertSame(o, objects.get(0));
+            }
+        });
+
+        clientContext.commitChanges();
+
+        // fetch committed
+        final ObjectIdQuery q2 = new ObjectIdQuery(
+                o.getObjectId(),
+                false,
+                ObjectIdQuery.CACHE);
+
+        clientServerInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                List<?> objects = clientContext.performQuery(q2);
+                assertEquals(1, objects.size());
+                assertSame(o, objects.get(0));
+            }
+        });
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextWithDataContextTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextWithDataContextTest.java b/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextWithDataContextTest.java
deleted file mode 100644
index c9b45a2..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/CayenneContextWithDataContextTest.java
+++ /dev/null
@@ -1,570 +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;
-
-import java.sql.Types;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.cayenne.access.ClientServerChannel;
-import org.apache.cayenne.access.DataContext;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.map.LifecycleEvent;
-import org.apache.cayenne.query.ObjectIdQuery;
-import org.apache.cayenne.query.QueryCacheStrategy;
-import org.apache.cayenne.query.SelectQuery;
-import org.apache.cayenne.query.SortOrder;
-import org.apache.cayenne.reflect.LifecycleCallbackRegistry;
-import org.apache.cayenne.remote.RemoteIncrementalFaultList;
-import org.apache.cayenne.test.jdbc.DBHelper;
-import org.apache.cayenne.test.jdbc.TableHelper;
-import org.apache.cayenne.test.parallel.ParallelTestContainer;
-import org.apache.cayenne.testdo.mt.ClientMtMeaningfulPk;
-import org.apache.cayenne.testdo.mt.ClientMtReflexive;
-import org.apache.cayenne.testdo.mt.ClientMtTable1;
-import org.apache.cayenne.testdo.mt.ClientMtTable2;
-import org.apache.cayenne.testdo.mt.MtReflexive;
-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;
-
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class CayenneContextWithDataContextTest extends ClientCase {
-
-    @Inject
-    private CayenneContext clientContext;
-
-    @Inject
-    private DBHelper dbHelper;
-
-    @Inject(ClientCase.ROP_CLIENT_KEY)
-    private DataChannelInterceptor clientServerInterceptor;
-
-    @Inject
-    private ClientServerChannel clientServerChannel;
-
-    private TableHelper tMtTable1;
-    private TableHelper tMtTable2;
-
-    private TableHelper tMtMeaningfulPK;
-
-    @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").setColumnTypes(
-                Types.INTEGER, Types.INTEGER, Types.VARCHAR);
-
-        tMtMeaningfulPK = new TableHelper(dbHelper, "MT_MEANINGFUL_PK");
-        tMtMeaningfulPK.setColumns("PK");
-    }
-
-    private void deleteAndCreateTwoMeaningfulPKsDataSet() throws Exception {
-        tMtMeaningfulPK.deleteAll();
-        tMtMeaningfulPK.insert("A");
-        tMtMeaningfulPK.insert("B");
-    }
-
-    private void createTwoMtTable1sAnd2sDataSet() throws Exception {
-        tMtTable1.insert(1, "g1", "s1");
-        tMtTable1.insert(2, "g2", "s2");
-
-        tMtTable2.insert(1, 1, "g1");
-        tMtTable2.insert(2, 1, "g2");
-    }
-
-    private void createEightMtTable1s() throws Exception {
-        for (int i = 1; i <= 8; i++) {
-            tMtTable1.insert(i, "g" + i, "s" + i);
-        }
-    }
-
-    public void testLocalCacheStaysLocal() {
-
-        DataContext serverContext = (DataContext) clientServerChannel.getParentChannel();
-
-        SelectQuery query = new SelectQuery(ClientMtTable1.class);
-        query.setCacheStrategy(QueryCacheStrategy.LOCAL_CACHE);
-
-        assertEquals(0, clientContext.getQueryCache().size());
-        assertEquals(0, serverContext.getQueryCache().size());
-
-        List<?> results = clientContext.performQuery(query);
-
-        assertEquals(1, clientContext.getQueryCache().size());
-        assertSame(results, clientContext.getQueryCache().get(
-                query.getMetaData(clientContext.getEntityResolver())));
-
-        assertEquals(0, serverContext.getQueryCache().size());
-    }
-
-    public void testAddToList() throws Exception {
-
-        ClientMtTable1 t1 = clientContext.newObject(ClientMtTable1.class);
-        ClientMtTable2 t2 = clientContext.newObject(ClientMtTable2.class);
-
-        t1.addToTable2Array(t2);
-        assertEquals(1, t1.getTable2Array().size());
-        assertSame(t1, t2.getTable1());
-
-        // do it again to make sure action can handle series of changes
-        ClientMtTable1 t3 = clientContext.newObject(ClientMtTable1.class);
-        ClientMtTable2 t4 = clientContext.newObject(ClientMtTable2.class);
-
-        t3.addToTable2Array(t4);
-        assertEquals(1, t3.getTable2Array().size());
-        assertSame(t3, t4.getTable1());
-    }
-
-    public void testSetValueHolder() throws Exception {
-
-        ClientMtTable1 t1 = clientContext.newObject(ClientMtTable1.class);
-        ClientMtTable2 t2 = clientContext.newObject(ClientMtTable2.class);
-
-        t2.setTable1(t1);
-        assertEquals(1, t1.getTable2Array().size());
-        assertSame(t1, t2.getTable1());
-    }
-
-    public void testPostAddCallback() throws Exception {
-
-        LifecycleCallbackRegistry callbackRegistry = clientServerChannel
-                .getEntityResolver()
-                .getCallbackRegistry();
-
-        final boolean[] flag = new boolean[1];
-
-        try {
-            callbackRegistry.addListener(MtTable1.class, new LifecycleListener() {
-
-                public void postLoad(Object entity) {
-                }
-
-                public void postPersist(Object entity) {
-                }
-
-                public void postRemove(Object entity) {
-                }
-
-                public void postUpdate(Object entity) {
-                }
-
-                public void postAdd(Object entity) {
-                    flag[0] = true;
-                }
-
-                public void preRemove(Object entity) {
-                }
-
-                public void preUpdate(Object entity) {
-                }
-
-                public void prePersist(Object entity) {
-                }
-            });
-
-            clientContext.newObject(ClientMtTable1.class);
-
-            assertFalse(flag[0]);
-            clientContext.commitChanges();
-            assertTrue(flag[0]);
-        }
-        finally {
-            callbackRegistry.clear();
-        }
-    }
-
-    public void testPostAddOnObjectCallback() throws Exception {
-
-        final DataContext serverContext = (DataContext) clientServerChannel.getParentChannel();
-
-        LifecycleCallbackRegistry callbackRegistry = serverContext
-                .getEntityResolver()
-                .getCallbackRegistry();
-
-        try {
-            callbackRegistry.addCallback(
-                    LifecycleEvent.POST_ADD,
-                    MtTable1.class,
-                    "prePersistMethod");
-
-            final Persistent clientObject = clientContext.newObject(ClientMtTable1.class);
-            clientContext.commitChanges();
-
-        new ParallelTestContainer() {
-
-            @Override
-            protected void assertResult() throws Exception {
-            	// find peer
-            	MtTable1 peer = (MtTable1) serverContext.getGraphManager().getNode(
-                    clientObject.getObjectId());
-
-            	assertNotNull(peer);
-            	assertTrue(peer.isPrePersisted());
-            }
-        }.runTest(1000);
-
-
-        }
-        finally {
-            callbackRegistry.clear();
-        }
-    }
-
-    public void testPreRemoveCallback() throws Exception {
-
-        // an exception was triggered within POST_LOAD callback
-        LifecycleCallbackRegistry callbackRegistry = clientServerChannel
-                .getEntityResolver()
-                .getCallbackRegistry();
-
-        final boolean[] flag = new boolean[1];
-
-        try {
-            callbackRegistry.addListener(MtTable1.class, new LifecycleListener() {
-
-                public void postLoad(Object entity) {
-                }
-
-                public void postPersist(Object entity) {
-                }
-
-                public void postRemove(Object entity) {
-                }
-
-                public void postUpdate(Object entity) {
-                }
-
-                public void postAdd(Object entity) {
-                }
-
-                public void preRemove(Object entity) {
-                    flag[0] = true;
-                }
-
-                public void preUpdate(Object entity) {
-                }
-
-                public void prePersist(Object entity) {
-                }
-            });
-
-            ClientMtTable1 object = clientContext.newObject(ClientMtTable1.class);
-
-            assertFalse(flag[0]);
-            clientContext.commitChanges();
-            assertFalse(flag[0]);
-
-            clientContext.deleteObjects(object);
-            clientContext.commitChanges();
-            assertTrue(flag[0]);
-        }
-        finally {
-            callbackRegistry.clear();
-        }
-    }
-
-    public void testCAY830() throws Exception {
-
-        // an exception was triggered within POST_LOAD callback
-        LifecycleCallbackRegistry callbackRegistry = clientServerChannel
-                .getEntityResolver()
-                .getCallbackRegistry();
-
-        try {
-            callbackRegistry.addListener(MtReflexive.class, new LifecycleListener() {
-
-                public void postLoad(Object entity) {
-                }
-
-                public void postPersist(Object entity) {
-                }
-
-                public void postRemove(Object entity) {
-                }
-
-                public void postUpdate(Object entity) {
-                }
-
-                public void postAdd(Object entity) {
-                }
-
-                public void preRemove(Object entity) {
-                }
-
-                public void preUpdate(Object entity) {
-                }
-
-                public void prePersist(Object entity) {
-                }
-            });
-
-            ClientMtReflexive o1 = clientContext.newObject(ClientMtReflexive.class);
-            o1.setName("parent");
-
-            ClientMtReflexive o2 = clientContext.newObject(ClientMtReflexive.class);
-            o2.setName("child");
-            o2.setToParent(o1);
-            clientContext.commitChanges();
-
-            clientContext.deleteObjects(o1);
-            clientContext.deleteObjects(o2);
-            clientContext.commitChanges();
-            // per CAY-830 an exception is thrown here
-        }
-        finally {
-            callbackRegistry.clear();
-        }
-    }
-
-    public void testRollbackChanges() throws Exception {
-
-        ClientMtTable1 o = clientContext.newObject(ClientMtTable1.class);
-        o.setGlobalAttribute1("1");
-        clientContext.commitChanges();
-
-        assertEquals("1", o.getGlobalAttribute1());
-        o.setGlobalAttribute1("2");
-        assertEquals("2", o.getGlobalAttribute1());
-        clientContext.rollbackChanges();
-
-        assertEquals("1", o.getGlobalAttribute1());
-        assertTrue(clientContext.modifiedObjects().isEmpty());
-    }
-
-    public void testCreateFault() throws Exception {
-        tMtTable1.insert(1, "g1", "s1");
-
-        ObjectId id = new ObjectId("MtTable1", MtTable1.TABLE1_ID_PK_COLUMN, 1);
-
-        Object fault = clientContext.createFault(id);
-        assertTrue(fault instanceof ClientMtTable1);
-
-        ClientMtTable1 o = (ClientMtTable1) fault;
-        assertEquals(PersistenceState.HOLLOW, o.getPersistenceState());
-        assertSame(clientContext, o.getObjectContext());
-        assertNull(o.getGlobalAttribute1Direct());
-
-        // make sure we haven't tripped the fault yet
-        assertEquals(PersistenceState.HOLLOW, o.getPersistenceState());
-
-        // try tripping fault
-        assertEquals("g1", o.getGlobalAttribute1());
-        assertEquals(PersistenceState.COMMITTED, o.getPersistenceState());
-    }
-
-    public void testCreateBadFault() throws Exception {
-        tMtTable1.insert(1, "g1", "s1");
-
-        ObjectId id = new ObjectId("MtTable1", MtTable1.TABLE1_ID_PK_COLUMN, 2);
-
-        Object fault = clientContext.createFault(id);
-        assertTrue(fault instanceof ClientMtTable1);
-
-        ClientMtTable1 o = (ClientMtTable1) fault;
-
-        // try tripping fault
-        try {
-            o.getGlobalAttribute1();
-            fail("resolving bad fault should've thrown");
-        }
-        catch (FaultFailureException e) {
-            // expected
-        }
-    }
-
-    public void testMeaningfulPK() throws Exception {
-        deleteAndCreateTwoMeaningfulPKsDataSet();
-
-        SelectQuery query = new SelectQuery(ClientMtMeaningfulPk.class);
-        query.addOrdering(ClientMtMeaningfulPk.PK_PROPERTY, SortOrder.DESCENDING);
-
-        List<?> results = clientContext.performQuery(query);
-        assertEquals(2, results.size());
-    }
-
-    public void testPrefetchingToOne() throws Exception {
-        createTwoMtTable1sAnd2sDataSet();
-
-        final ObjectId prefetchedId = new ObjectId(
-                "MtTable1",
-                MtTable1.TABLE1_ID_PK_COLUMN,
-                1);
-
-        SelectQuery q = new SelectQuery(ClientMtTable2.class);
-        q.addOrdering(ClientMtTable2.GLOBAL_ATTRIBUTE_PROPERTY, SortOrder.ASCENDING);
-        q.addPrefetch(ClientMtTable2.TABLE1_PROPERTY);
-
-        final List<ClientMtTable2> results = clientContext.performQuery(q);
-
-        clientServerInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                assertEquals(2, results.size());
-
-                for (ClientMtTable2 o : results) {
-                    assertEquals(PersistenceState.COMMITTED, o.getPersistenceState());
-                    assertSame(clientContext, o.getObjectContext());
-
-                    ClientMtTable1 o1 = o.getTable1();
-                    assertNotNull(o1);
-                    assertEquals(PersistenceState.COMMITTED, o1.getPersistenceState());
-                    assertSame(clientContext, o1.getObjectContext());
-                    assertEquals(prefetchedId, o1.getObjectId());
-                }
-            }
-        });
-    }
-
-    public void testPrefetchingToOneNull() throws Exception {
-        tMtTable2.insert(15, null, "g3");
-
-        SelectQuery q = new SelectQuery(ClientMtTable2.class);
-        q.addPrefetch(ClientMtTable2.TABLE1_PROPERTY);
-
-        final List<ClientMtTable2> results = clientContext.performQuery(q);
-
-        clientServerInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-
-                assertEquals(1, results.size());
-
-                ClientMtTable2 o = results.get(0);
-                assertEquals(PersistenceState.COMMITTED, o.getPersistenceState());
-                assertSame(clientContext, o.getObjectContext());
-
-                assertNull(o.getTable1());
-            }
-        });
-    }
-
-    public void testPrefetchingToMany() throws Exception {
-        createTwoMtTable1sAnd2sDataSet();
-
-        SelectQuery q = new SelectQuery(ClientMtTable1.class);
-        q.addOrdering(ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY, SortOrder.ASCENDING);
-        q.addPrefetch(ClientMtTable1.TABLE2ARRAY_PROPERTY);
-
-        final List<ClientMtTable1> results = clientContext.performQuery(q);
-
-        clientServerInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-
-                ClientMtTable1 o1 = results.get(0);
-                assertEquals(PersistenceState.COMMITTED, o1.getPersistenceState());
-                assertSame(clientContext, o1.getObjectContext());
-
-                List<?> children1 = o1.getTable2Array();
-
-                assertEquals(2, children1.size());
-                Iterator<?> it = children1.iterator();
-                while (it.hasNext()) {
-                    ClientMtTable2 o = (ClientMtTable2) it.next();
-                    assertEquals(PersistenceState.COMMITTED, o.getPersistenceState());
-                    assertSame(clientContext, o.getObjectContext());
-
-                    // TODO: fixme... reverse relationship is not connected and will
-                    // cause a fetch
-                    // assertEquals(o1, o.getTable1());
-                }
-            }
-        });
-    }
-
-    public void testPerformPaginatedQuery() throws Exception {
-        createEightMtTable1s();
-
-        SelectQuery query = new SelectQuery(ClientMtTable1.class);
-        query.setPageSize(5);
-        List<ClientMtTable1> objects = clientContext.performQuery(query);
-        assertNotNull(objects);
-        assertTrue(objects instanceof RemoteIncrementalFaultList);
-    }
-
-    public void testPrefetchingToManyEmpty() throws Exception {
-        createTwoMtTable1sAnd2sDataSet();
-
-        SelectQuery q = new SelectQuery(ClientMtTable1.class);
-        q.addOrdering(ClientMtTable1.GLOBAL_ATTRIBUTE1_PROPERTY, SortOrder.ASCENDING);
-        q.addPrefetch(ClientMtTable1.TABLE2ARRAY_PROPERTY);
-
-        final List<ClientMtTable1> results = clientContext.performQuery(q);
-
-        clientServerInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                ClientMtTable1 o2 = results.get(1);
-                assertEquals(PersistenceState.COMMITTED, o2.getPersistenceState());
-                assertSame(clientContext, o2.getObjectContext());
-
-                List<ClientMtTable2> children2 = o2.getTable2Array();
-                assertFalse(((ValueHolder) children2).isFault());
-                assertEquals(0, children2.size());
-            }
-        });
-    }
-
-    public void testOIDQueryInterception() throws Exception {
-
-        final ClientMtTable1 o = clientContext.newObject(ClientMtTable1.class);
-        o.setGlobalAttribute1("aaa");
-
-        // fetch new
-        final ObjectIdQuery q1 = new ObjectIdQuery(
-                o.getObjectId(),
-                false,
-                ObjectIdQuery.CACHE);
-
-        clientServerInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                List<?> objects = clientContext.performQuery(q1);
-                assertEquals(1, objects.size());
-                assertSame(o, objects.get(0));
-            }
-        });
-
-        clientContext.commitChanges();
-
-        // fetch committed
-        final ObjectIdQuery q2 = new ObjectIdQuery(
-                o.getObjectId(),
-                false,
-                ObjectIdQuery.CACHE);
-
-        clientServerInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                List<?> objects = clientContext.performQuery(q2);
-                assertEquals(1, objects.size());
-                assertSame(o, objects.get(0));
-            }
-        });
-    }
-}


[4/8] Rename Integration Tests in cayenne-client (*IT.java instead of *Test.java)

Posted by aa...@apache.org.
http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/NestedCayenneContextIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/NestedCayenneContextIT.java b/cayenne-client/src/test/java/org/apache/cayenne/NestedCayenneContextIT.java
new file mode 100644
index 0000000..937f39c
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/NestedCayenneContextIT.java
@@ -0,0 +1,864 @@
+/*****************************************************************
+ *   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;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.cayenne.configuration.rop.client.ClientRuntime;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.graph.GraphChangeHandler;
+import org.apache.cayenne.graph.GraphDiff;
+import org.apache.cayenne.query.SelectQuery;
+import org.apache.cayenne.query.SortOrder;
+import org.apache.cayenne.remote.RemoteCayenneCase;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.testdo.mt.ClientMtTable1;
+import org.apache.cayenne.testdo.mt.ClientMtTable2;
+import org.apache.cayenne.testdo.mt.ClientMtTooneDep;
+import org.apache.cayenne.testdo.mt.ClientMtTooneMaster;
+import org.apache.cayenne.testdo.testmap.Artist;
+import org.apache.cayenne.testdo.testmap.Painting;
+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;
+
+/**
+ * Tests nested object contexts
+ */
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class NestedCayenneContextIT extends RemoteCayenneCase {
+
+    @Inject
+    private ClientRuntime runtime;
+    
+    @Inject
+    private DBHelper dbHelper;
+
+    @Inject
+    private DataChannelInterceptor queryInterceptor;
+
+    @Override
+    public void setUpAfterInjection() throws Exception {
+        super.setUpAfterInjection();
+
+        dbHelper.deleteAll("MT_TABLE2");
+        dbHelper.deleteAll("MT_TABLE1");
+    }
+
+    public void testChannels() {
+        ObjectContext child = runtime.newContext(clientContext);
+
+        assertNotNull(child);
+        assertSame(clientContext, child.getChannel());
+
+        // second level of nesting
+        ObjectContext grandchild = runtime.newContext((DataChannel) child);
+
+        assertNotNull(grandchild);
+        assertSame(child, grandchild.getChannel());
+    }
+
+    public void testSelect() throws Exception {
+        ObjectContext child = runtime.newContext(clientContext);
+
+        ClientMtTable1 committed = clientContext.newObject(ClientMtTable1.class);
+        ClientMtTable1 deleted = clientContext.newObject(ClientMtTable1.class);
+        ClientMtTable1 modified = clientContext.newObject(ClientMtTable1.class);
+
+        clientContext.commitChanges();
+        int modifiedid = Cayenne.intPKForObject(modified);
+
+        // test how different object states appear in the child on select
+
+        clientContext.deleteObjects(deleted);
+        modified.setGlobalAttribute1("a");
+
+        ClientMtTable1 _new = clientContext.newObject(ClientMtTable1.class);
+
+        assertEquals(PersistenceState.COMMITTED, committed.getPersistenceState());
+        assertEquals(PersistenceState.MODIFIED, modified.getPersistenceState());
+        assertEquals(PersistenceState.DELETED, deleted.getPersistenceState());
+        assertEquals(PersistenceState.NEW, _new.getPersistenceState());
+
+        List<?> objects = child.performQuery(new SelectQuery(ClientMtTable1.class));
+        assertEquals("All but NEW object must have been included", 3, objects.size());
+
+        Iterator<?> it = objects.iterator();
+        while (it.hasNext()) {
+            ClientMtTable1 next = (ClientMtTable1) it.next();
+            assertEquals(PersistenceState.COMMITTED, next.getPersistenceState());
+
+            int id = Cayenne.intPKForObject(next);
+            if (id == modifiedid) {
+                assertEquals("a", next.getGlobalAttribute1());
+            }
+        }
+    }
+
+    public void testPrefetchingToOne() throws Exception {
+        final ClientMtTable1 mt11 = clientContext.newObject(ClientMtTable1.class);
+        clientContext.newObject(ClientMtTable1.class);
+        ClientMtTable2 mt21 = clientContext.newObject(ClientMtTable2.class);
+        ClientMtTable2 mt22 = clientContext.newObject(ClientMtTable2.class);
+
+        mt21.setTable1(mt11);
+        mt22.setTable1(mt11);
+
+        clientContext.commitChanges();
+
+        final ObjectContext child = runtime.newContext(clientContext);
+
+        SelectQuery q = new SelectQuery(ClientMtTable2.class);
+        q.addPrefetch(ClientMtTable2.TABLE1_PROPERTY);
+
+        final List<?> results = child.performQuery(q);
+
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                assertEquals(2, results.size());
+                Iterator<?> it = results.iterator();
+                while (it.hasNext()) {
+                    ClientMtTable2 o = (ClientMtTable2) it.next();
+                    assertEquals(PersistenceState.COMMITTED, o.getPersistenceState());
+                    assertSame(child, o.getObjectContext());
+
+                    ClientMtTable1 o1 = o.getTable1();
+                    assertNotNull(o1);
+                    assertEquals(PersistenceState.COMMITTED, o1.getPersistenceState());
+                    assertSame(child, o1.getObjectContext());
+                    assertEquals(mt11.getObjectId(), o1.getObjectId());
+                }
+            }
+        });
+    }
+
+    public void testPrefetchingToMany() throws Exception {
+        ClientMtTable1 mt11 = clientContext.newObject(ClientMtTable1.class);
+        mt11.setGlobalAttribute1("1");
+
+        ClientMtTable1 mt12 = clientContext.newObject(ClientMtTable1.class);
+        mt12.setGlobalAttribute1("2");
+
+        ClientMtTable2 mt21 = clientContext.newObject(ClientMtTable2.class);
+        ClientMtTable2 mt22 = clientContext.newObject(ClientMtTable2.class);
+
+        mt21.setTable1(mt11);
+        mt22.setTable1(mt11);
+
+        clientContext.commitChanges();
+
+        final ObjectContext child = runtime.newContext(clientContext);
+
+        SelectQuery q = new SelectQuery(ClientMtTable1.class);
+        q.addOrdering("globalAttribute1", SortOrder.ASCENDING);
+        q.addPrefetch(ClientMtTable1.TABLE2ARRAY_PROPERTY);
+
+        final List<?> results = child.performQuery(q);
+
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                ClientMtTable1 o1 = (ClientMtTable1) results.get(0);
+                assertEquals(PersistenceState.COMMITTED, o1.getPersistenceState());
+                assertSame(child, o1.getObjectContext());
+
+                List<ClientMtTable2> children1 = o1.getTable2Array();
+
+                assertEquals(2, children1.size());
+                Iterator<ClientMtTable2> it = children1.iterator();
+                while (it.hasNext()) {
+                    ClientMtTable2 o = it.next();
+                    assertEquals(PersistenceState.COMMITTED, o.getPersistenceState());
+                    assertSame(child, o.getObjectContext());
+
+                    assertEquals(o1, o.getTable1());
+                }
+
+                ClientMtTable1 o2 = (ClientMtTable1) results.get(1);
+                assertEquals(PersistenceState.COMMITTED, o2.getPersistenceState());
+                assertSame(child, o2.getObjectContext());
+
+                List<?> children2 = o2.getTable2Array();
+
+                assertEquals(0, children2.size());
+            }
+        });
+    }
+
+    public void testDeleteNew() throws Exception {
+        ObjectContext child = runtime.newContext(clientContext);
+
+        ClientMtTable1 a = clientContext.newObject(ClientMtTable1.class);
+        clientContext.commitChanges();
+
+        ClientMtTable2 p = child.newObject(ClientMtTable2.class);
+        ClientMtTable1 aChild = (ClientMtTable1) Cayenne.objectForPK(
+                child,
+                a.getObjectId());
+        p.setGlobalAttribute("X");
+        aChild.addToTable2Array(p);
+
+        child.commitChangesToParent();
+
+        child.deleteObjects(p);
+        aChild.removeFromTable2Array(p);
+
+        child.commitChangesToParent();
+    }
+
+    /**
+     * A test case for CAY-698 bug.
+     */
+    public void testNullifyToOne() throws Exception {
+        ClientMtTable1 a = clientContext.newObject(ClientMtTable1.class);
+        ClientMtTable2 b = clientContext.newObject(ClientMtTable2.class);
+        a.addToTable2Array(b);
+
+        clientContext.commitChanges();
+
+        final ObjectContext child = runtime.newContext(clientContext);
+        ObjectContext childPeer = runtime.newContext(clientContext);
+
+        final ClientMtTable2 childP1 = (ClientMtTable2) Cayenne.objectForPK(
+                child,
+                b.getObjectId());
+
+        // trigger object creation in the peer nested DC
+        Cayenne.objectForPK(childPeer, b.getObjectId());
+        childP1.setTable1(null);
+
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                child.commitChangesToParent();
+                assertEquals(PersistenceState.COMMITTED, childP1.getPersistenceState());
+
+                ClientMtTable2 parentP1 = (ClientMtTable2) clientContext
+                        .getGraphManager()
+                        .getNode(childP1.getObjectId());
+
+                assertNotNull(parentP1);
+                assertEquals(PersistenceState.MODIFIED, parentP1.getPersistenceState());
+                assertNull(parentP1.getTable1());
+
+                // check that arc changes got recorded in the parent context
+                GraphDiff diffs = clientContext.internalGraphManager().getDiffs();
+                final int[] arcDiffs = new int[1];
+
+                diffs.apply(new GraphChangeHandler() {
+
+                    public void arcCreated(
+                            Object nodeId,
+                            Object targetNodeId,
+                            Object arcId) {
+                        arcDiffs[0]++;
+                    }
+
+                    public void arcDeleted(
+                            Object nodeId,
+                            Object targetNodeId,
+                            Object arcId) {
+                        arcDiffs[0]--;
+                    }
+
+                    public void nodeCreated(Object nodeId) {
+
+                    }
+
+                    public void nodeIdChanged(Object nodeId, Object newId) {
+                    }
+
+                    public void nodePropertyChanged(
+                            Object nodeId,
+                            String property,
+                            Object oldValue,
+                            Object newValue) {
+                    }
+
+                    public void nodeRemoved(Object nodeId) {
+
+                    }
+                });
+
+                assertEquals(-2, arcDiffs[0]);
+            }
+        });
+    }
+
+    public void testCommitChangesToParent() throws Exception {
+        clientContext.newObject(ClientMtTable1.class);
+        clientContext.newObject(ClientMtTable1.class);
+        clientContext.newObject(ClientMtTable1.class);
+        clientContext.newObject(ClientMtTable1.class);
+        clientContext.commitChanges();
+
+        final ObjectContext child = runtime.newContext(clientContext);
+
+        SelectQuery query = new SelectQuery(ClientMtTable1.class);
+        List<?> objects = child.performQuery(query);
+
+        assertEquals(4, objects.size());
+
+        final ClientMtTable1 childNew = child.newObject(ClientMtTable1.class);
+        childNew.setGlobalAttribute1("NNN");
+
+        final ClientMtTable1 childModified = (ClientMtTable1) objects.get(0);
+        childModified.setGlobalAttribute1("MMM");
+
+        final ClientMtTable1 childCommitted = (ClientMtTable1) objects.get(1);
+
+        final ClientMtTable1 childHollow = (ClientMtTable1) objects.get(3);
+        child.invalidateObjects(childHollow);
+
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                child.commitChangesToParent();
+
+                // * all modified child objects must be in committed state now
+                // * all modifications should be propagated to the parent
+                // * no actual commit should occur.
+
+                assertEquals(PersistenceState.COMMITTED, childNew.getPersistenceState());
+                assertEquals(
+                        PersistenceState.COMMITTED,
+                        childModified.getPersistenceState());
+                assertEquals(
+                        PersistenceState.COMMITTED,
+                        childCommitted.getPersistenceState());
+                assertEquals(PersistenceState.HOLLOW, childHollow.getPersistenceState());
+
+                ClientMtTable1 parentNew = (ClientMtTable1) clientContext
+                        .getGraphManager()
+                        .getNode(childNew.getObjectId());
+                final ClientMtTable1 parentModified = (ClientMtTable1) clientContext
+                        .getGraphManager()
+                        .getNode(childModified.getObjectId());
+                ClientMtTable1 parentCommitted = (ClientMtTable1) clientContext
+                        .getGraphManager()
+                        .getNode(childCommitted.getObjectId());
+                ClientMtTable1 parentHollow = (ClientMtTable1) clientContext
+                        .getGraphManager()
+                        .getNode(childHollow.getObjectId());
+
+                assertNotNull(parentNew);
+                assertEquals(PersistenceState.NEW, parentNew.getPersistenceState());
+                assertEquals("NNN", parentNew.getGlobalAttribute1());
+
+                assertNotNull(parentModified);
+                assertEquals(
+                        PersistenceState.MODIFIED,
+                        parentModified.getPersistenceState());
+                assertEquals("MMM", parentModified.getGlobalAttribute1());
+
+                assertNotNull(parentCommitted);
+                assertEquals(
+                        PersistenceState.COMMITTED,
+                        parentCommitted.getPersistenceState());
+
+                assertNotNull(parentHollow);
+
+                // check that arc changes got recorded in the parent context
+                GraphDiff diffs = clientContext.internalGraphManager().getDiffs();
+
+                final int[] modifiedProperties = new int[1];
+
+                diffs.apply(new GraphChangeHandler() {
+
+                    public void arcCreated(
+                            Object nodeId,
+                            Object targetNodeId,
+                            Object arcId) {
+
+                    }
+
+                    public void arcDeleted(
+                            Object nodeId,
+                            Object targetNodeId,
+                            Object arcId) {
+
+                    }
+
+                    public void nodeCreated(Object nodeId) {
+
+                    }
+
+                    public void nodeIdChanged(Object nodeId, Object newId) {
+                    }
+
+                    public void nodePropertyChanged(
+                            Object nodeId,
+                            String property,
+                            Object oldValue,
+                            Object newValue) {
+
+                        if (nodeId.equals(parentModified.getObjectId())) {
+                            modifiedProperties[0]++;
+                        }
+                    }
+
+                    public void nodeRemoved(Object nodeId) {
+
+                    }
+                });
+
+                assertEquals(1, modifiedProperties[0]);
+            }
+        });
+    }
+
+    public void testCommitChangesToParentDeleted() throws Exception {
+        clientContext.newObject(ClientMtTable1.class);
+        clientContext.newObject(ClientMtTable1.class);
+        clientContext.newObject(ClientMtTable1.class);
+        clientContext.newObject(ClientMtTable1.class);
+        clientContext.commitChanges();
+
+        ObjectContext child = runtime.newContext(clientContext);
+
+        // make sure we fetch in predictable order
+        SelectQuery query = new SelectQuery(ClientMtTable1.class);
+        List<?> objects = child.performQuery(query);
+
+        assertEquals(4, objects.size());
+
+        // delete AND modify
+        ClientMtTable1 childDeleted = (ClientMtTable1) objects.get(2);
+        child.deleteObjects(childDeleted);
+        childDeleted.setGlobalAttribute1("DDD");
+
+        // don't block queries - on delete Cayenne may need to resolve delete rules via
+        // fetch
+        child.commitChangesToParent();
+
+        // * all modified child objects must be in committed state now
+        // * all modifications should be propagated to the parent
+        // * no actual commit should occur.
+
+        assertEquals(PersistenceState.TRANSIENT, childDeleted.getPersistenceState());
+
+        ClientMtTable1 parentDeleted = (ClientMtTable1) clientContext
+                .getGraphManager()
+                .getNode(childDeleted.getObjectId());
+
+        assertNotNull(parentDeleted);
+        assertEquals(PersistenceState.DELETED, parentDeleted.getPersistenceState());
+        assertEquals("DDD", parentDeleted.getGlobalAttribute1());
+    }
+
+    /*
+     * was added for CAY-1636
+     */
+    public void testCAY1636() throws Exception {
+
+        ClientMtTooneMaster A = clientContext.newObject(ClientMtTooneMaster.class);
+        clientContext.commitChanges();
+
+        ClientMtTooneDep B = clientContext.newObject(ClientMtTooneDep.class);
+        A.setToDependent(B);
+        clientContext.commitChanges();
+
+        ObjectContext child = runtime.newContext(clientContext);
+
+        SelectQuery query = new SelectQuery(ClientMtTooneMaster.class);
+        List<?> objects = child.performQuery(query);
+
+        assertEquals(1, objects.size());
+
+        ClientMtTooneMaster childDeleted = (ClientMtTooneMaster) objects.get(0);
+
+        child.deleteObjects(childDeleted);
+
+        child.commitChangesToParent();
+
+        ClientMtTooneMaster parentDeleted = (ClientMtTooneMaster) clientContext
+                .getGraphManager()
+                .getNode(childDeleted.getObjectId());
+
+        assertNotNull(parentDeleted);
+        assertEquals(PersistenceState.DELETED, parentDeleted.getPersistenceState());
+
+        clientContext.commitChanges();
+
+        SelectQuery query2 = new SelectQuery(ClientMtTooneMaster.class);
+        List<?> objects2 = child.performQuery(query2);
+
+        assertEquals(0, objects2.size());
+
+    }
+
+    public void testCAY1636_2() throws Exception {
+
+        ClientMtTooneMaster A = clientContext.newObject(ClientMtTooneMaster.class);
+        clientContext.commitChanges();
+
+        ClientMtTooneDep B = clientContext.newObject(ClientMtTooneDep.class);
+        A.setToDependent(B);
+        clientContext.commitChanges();
+
+        ObjectContext child = runtime.newContext(clientContext);
+
+        SelectQuery queryB = new SelectQuery(ClientMtTooneDep.class);
+        List<?> objectsB = child.performQuery(queryB);
+
+        assertEquals(1, objectsB.size());
+
+        ClientMtTooneDep childBDeleted = (ClientMtTooneDep) objectsB.get(0);
+        child.deleteObjects(childBDeleted);
+
+        SelectQuery query = new SelectQuery(ClientMtTooneMaster.class);
+        List<?> objects = child.performQuery(query);
+
+        assertEquals(1, objects.size());
+
+        ClientMtTooneMaster childDeleted = (ClientMtTooneMaster) objects.get(0);
+
+        child.deleteObjects(childDeleted);
+
+        child.commitChangesToParent();
+
+        ClientMtTooneMaster parentDeleted = (ClientMtTooneMaster) clientContext
+                .getGraphManager()
+                .getNode(childDeleted.getObjectId());
+
+        assertNotNull(parentDeleted);
+        assertEquals(PersistenceState.DELETED, parentDeleted.getPersistenceState());
+
+        clientContext.commitChanges();
+
+        SelectQuery query2 = new SelectQuery(ClientMtTooneMaster.class);
+        List<?> objects2 = child.performQuery(query2);
+
+        assertEquals(0, objects2.size());
+
+    }
+
+    public void testCommitChanges() throws Exception {
+        clientContext.newObject(ClientMtTable1.class);
+        clientContext.newObject(ClientMtTable1.class);
+        clientContext.newObject(ClientMtTable1.class);
+        clientContext.newObject(ClientMtTable1.class);
+        clientContext.commitChanges();
+
+        ObjectContext child = runtime.newContext(clientContext);
+
+        // make sure we fetch in predictable order
+        SelectQuery query = new SelectQuery(ClientMtTable1.class);
+        List<?> objects = child.performQuery(query);
+
+        assertEquals(4, objects.size());
+
+        ClientMtTable1 childNew = child.newObject(ClientMtTable1.class);
+        childNew.setGlobalAttribute1("NNN");
+
+        ClientMtTable1 childModified = (ClientMtTable1) objects.get(0);
+        childModified.setGlobalAttribute1("MMM");
+
+        ClientMtTable1 childCommitted = (ClientMtTable1) objects.get(1);
+
+        // delete AND modify
+        ClientMtTable1 childDeleted = (ClientMtTable1) objects.get(2);
+        child.deleteObjects(childDeleted);
+        childDeleted.setGlobalAttribute1("DDD");
+
+        ClientMtTable1 childHollow = (ClientMtTable1) objects.get(3);
+        child.invalidateObjects(childHollow);
+
+        child.commitChanges();
+
+        assertEquals(PersistenceState.COMMITTED, childNew.getPersistenceState());
+        assertEquals(PersistenceState.COMMITTED, childModified.getPersistenceState());
+        assertEquals(PersistenceState.COMMITTED, childCommitted.getPersistenceState());
+        assertEquals(PersistenceState.TRANSIENT, childDeleted.getPersistenceState());
+        assertEquals(PersistenceState.HOLLOW, childHollow.getPersistenceState());
+
+        ClientMtTable1 parentNew = (ClientMtTable1) clientContext
+                .getGraphManager()
+                .getNode(childNew.getObjectId());
+        ClientMtTable1 parentModified = (ClientMtTable1) clientContext
+                .getGraphManager()
+                .getNode(childModified.getObjectId());
+        ClientMtTable1 parentCommitted = (ClientMtTable1) clientContext
+                .getGraphManager()
+                .getNode(childCommitted.getObjectId());
+        ClientMtTable1 parentDeleted = (ClientMtTable1) clientContext
+                .getGraphManager()
+                .getNode(childDeleted.getObjectId());
+        ClientMtTable1 parentHollow = (ClientMtTable1) clientContext
+                .getGraphManager()
+                .getNode(childHollow.getObjectId());
+
+        assertNotNull(parentNew);
+        assertEquals(PersistenceState.COMMITTED, parentNew.getPersistenceState());
+        assertEquals("NNN", parentNew.getGlobalAttribute1());
+
+        assertNotNull(parentModified);
+        assertEquals(PersistenceState.COMMITTED, parentModified.getPersistenceState());
+        assertEquals("MMM", parentModified.getGlobalAttribute1());
+
+        assertNull("Deleted object should not be registered.", parentDeleted);
+
+        assertNotNull(parentCommitted);
+        assertEquals(PersistenceState.COMMITTED, parentCommitted.getPersistenceState());
+
+        assertNotNull(parentHollow);
+    }
+
+    public void testAddRemove() throws Exception {
+        ObjectContext child = runtime.newContext(clientContext);
+
+        ClientMtTable1 a = child.newObject(ClientMtTable1.class);
+        a.setGlobalAttribute1("X");
+        child.commitChanges();
+
+        ClientMtTable2 p1 = child.newObject(ClientMtTable2.class);
+        p1.setGlobalAttribute("P1");
+        a.addToTable2Array(p1);
+
+        ClientMtTable2 p2 = child.newObject(ClientMtTable2.class);
+        p2.setGlobalAttribute("P2");
+        a.addToTable2Array(p2);
+
+        a.removeFromTable2Array(p2);
+
+        // this causes an error on commit
+        child.deleteObjects(p2);
+
+        child.commitChangesToParent();
+
+    }
+
+    public void testChangeRel() throws Exception {
+        ObjectContext child = runtime.newContext(clientContext);
+
+        ClientMtTable1 a = child.newObject(ClientMtTable1.class);
+        ClientMtTable2 b = child.newObject(ClientMtTable2.class);
+        child.commitChanges();
+
+        assertEquals(PersistenceState.COMMITTED, a.getPersistenceState());
+
+        a.addToTable2Array(b);
+        assertEquals(PersistenceState.MODIFIED, a.getPersistenceState());
+
+        child.commitChangesToParent();
+        ClientMtTable1 parentA = (ClientMtTable1) clientContext
+                .getGraphManager()
+                .getNode(a.getObjectId());
+        assertEquals(PersistenceState.COMMITTED, a.getPersistenceState());
+        assertEquals(PersistenceState.MODIFIED, parentA.getPersistenceState());
+        assertEquals(1, parentA.getTable2Array().size());
+
+        clientContext.commitChanges();
+        assertEquals(PersistenceState.COMMITTED, parentA.getPersistenceState());
+
+        a.removeFromTable2Array(b);
+        assertEquals(PersistenceState.MODIFIED, a.getPersistenceState());
+
+        child.commitChangesToParent();
+        assertEquals(PersistenceState.COMMITTED, a.getPersistenceState());
+        assertEquals(PersistenceState.MODIFIED, parentA.getPersistenceState());
+        assertEquals(0, parentA.getTable2Array().size());
+    }
+
+    public void testCAY1183() throws Exception {
+        ClientMtTable1 parentMt = clientContext.newObject(ClientMtTable1.class);
+        clientContext.commitChanges();
+
+        ObjectContext child = runtime.newContext(clientContext);
+        ClientMtTable1 childMt = (ClientMtTable1) Cayenne.objectForPK(
+                child,
+                parentMt.getObjectId());
+        childMt.setGlobalAttribute1("1183");
+        ClientMtTable2 childMt2 = child.newObject(ClientMtTable2.class);
+        childMt2.setGlobalAttribute("1183");
+        childMt2.setTable1(childMt);
+
+        child.commitChangesToParent();
+
+        // fetching other relationship... this fails per CAY-1183
+        childMt2.getTable3();
+    }
+    
+    /**
+     * CAY1714
+     */
+    public void testQueriesOnTemporaryObject() throws Exception {
+        ObjectContext clientContext = runtime.newContext((DataChannel) this.clientContext);
+        ClientMtTable1 parentMt = clientContext.newObject(ClientMtTable1.class);
+
+        ObjectContext childContext = runtime.newContext((DataChannel) clientContext);
+        ClientMtTable1 childMt = (ClientMtTable1) Cayenne.objectForPK(childContext, parentMt.getObjectId());
+        childMt.setGlobalAttribute1("1183");
+        ClientMtTable2 childMt2 = childContext.newObject(ClientMtTable2.class);
+        childMt2.setGlobalAttribute("1183");
+        childMt2.setTable1(childMt);
+
+        childContext.commitChangesToParent();
+
+        assertNull(childMt2.getTable3());
+    }
+
+    public void testCAY1194() throws Exception {
+        ClientMtTable1 parentMt = clientContext.newObject(ClientMtTable1.class);
+        ObjectContext child = runtime.newContext(clientContext);
+
+        ClientMtTable2 childMt2 = child.newObject(ClientMtTable2.class);
+        childMt2.setGlobalAttribute("222");
+
+        ClientMtTable1 localParentMt = child.localObject(parentMt);
+        assertEquals(0, parentMt.getTable2Array().size());
+        assertEquals(0, localParentMt.getTable2Array().size());
+
+        childMt2.setTable1(localParentMt);
+
+        assertEquals(0, parentMt.getTable2Array().size());
+        assertEquals(1, localParentMt.getTable2Array().size());
+
+        assertEquals(localParentMt.getTable2Array().get(0).getObjectContext(), child);
+
+        child.commitChangesToParent();
+        assertEquals(1, parentMt.getTable2Array().size());
+        assertEquals(parentMt.getTable2Array().get(0).getObjectContext(), clientContext);
+    }
+
+    public void testCommitChangesToParentOneToMany() throws Exception {
+        ObjectContext child = runtime.newContext(clientContext);
+
+        ClientMtTable1 master = child.newObject(ClientMtTable1.class);
+        ClientMtTable2 dep = child.newObject(ClientMtTable2.class);
+        master.addToTable2Array(dep);
+
+        child.commitChangesToParent();
+
+        ClientMtTable1 masterParent = (ClientMtTable1) clientContext
+                .getGraphManager()
+                .getNode(master.getObjectId());
+        ClientMtTable2 depParent = (ClientMtTable2) clientContext
+                .getGraphManager()
+                .getNode(dep.getObjectId());
+
+        assertNotNull(masterParent);
+        assertNotNull(depParent);
+
+        assertSame(masterParent, depParent.getTable1());
+        assertTrue(masterParent.getTable2Array().contains(depParent));
+
+        // check that arc changes got recorded in the parent context
+        GraphDiff diffs = clientContext.internalGraphManager().getDiffs();
+
+        final int[] arcDiffs = new int[1];
+        final int[] newNodes = new int[1];
+
+        diffs.apply(new GraphChangeHandler() {
+
+            public void arcCreated(Object nodeId, Object targetNodeId, Object arcId) {
+                arcDiffs[0]++;
+            }
+
+            public void arcDeleted(Object nodeId, Object targetNodeId, Object arcId) {
+                arcDiffs[0]--;
+            }
+
+            public void nodeCreated(Object nodeId) {
+                newNodes[0]++;
+            }
+
+            public void nodeIdChanged(Object nodeId, Object newId) {
+            }
+
+            public void nodePropertyChanged(
+                    Object nodeId,
+                    String property,
+                    Object oldValue,
+                    Object newValue) {
+            }
+
+            public void nodeRemoved(Object nodeId) {
+                newNodes[0]--;
+            }
+        });
+
+        assertEquals(2, newNodes[0]);
+        assertEquals(2, arcDiffs[0]);
+    }
+
+    public void testCommitChangesToParentOneToOne() throws Exception {
+        ObjectContext child = runtime.newContext(clientContext);
+
+        ClientMtTooneMaster master = child.newObject(ClientMtTooneMaster.class);
+        ClientMtTooneDep dep = child.newObject(ClientMtTooneDep.class);
+        master.setToDependent(dep);
+
+        child.commitChangesToParent();
+
+        ClientMtTooneMaster masterParent = (ClientMtTooneMaster) clientContext
+                .getGraphManager()
+                .getNode(master.getObjectId());
+        ClientMtTooneDep depParent = (ClientMtTooneDep) clientContext
+                .getGraphManager()
+                .getNode(dep.getObjectId());
+
+        assertNotNull(masterParent);
+        assertNotNull(depParent);
+
+        assertSame(masterParent, depParent.getToMaster());
+        assertSame(depParent, masterParent.getToDependent());
+
+        // check that arc changes got recorded in the parent context
+        GraphDiff diffs = clientContext.internalGraphManager().getDiffs();
+
+        final int[] arcDiffs = new int[1];
+        final int[] newNodes = new int[1];
+
+        diffs.apply(new GraphChangeHandler() {
+
+            public void arcCreated(Object nodeId, Object targetNodeId, Object arcId) {
+                arcDiffs[0]++;
+            }
+
+            public void arcDeleted(Object nodeId, Object targetNodeId, Object arcId) {
+                arcDiffs[0]--;
+            }
+
+            public void nodeCreated(Object nodeId) {
+                newNodes[0]++;
+            }
+
+            public void nodeIdChanged(Object nodeId, Object newId) {
+            }
+
+            public void nodePropertyChanged(
+                    Object nodeId,
+                    String property,
+                    Object oldValue,
+                    Object newValue) {
+            }
+
+            public void nodeRemoved(Object nodeId) {
+                newNodes[0]--;
+            }
+        });
+
+        assertEquals(2, newNodes[0]);
+        assertEquals(2, arcDiffs[0]);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/NestedCayenneContextTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/NestedCayenneContextTest.java b/cayenne-client/src/test/java/org/apache/cayenne/NestedCayenneContextTest.java
deleted file mode 100644
index aec2547..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/NestedCayenneContextTest.java
+++ /dev/null
@@ -1,864 +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;
-
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.cayenne.configuration.rop.client.ClientRuntime;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.graph.GraphChangeHandler;
-import org.apache.cayenne.graph.GraphDiff;
-import org.apache.cayenne.query.SelectQuery;
-import org.apache.cayenne.query.SortOrder;
-import org.apache.cayenne.remote.RemoteCayenneCase;
-import org.apache.cayenne.test.jdbc.DBHelper;
-import org.apache.cayenne.testdo.mt.ClientMtTable1;
-import org.apache.cayenne.testdo.mt.ClientMtTable2;
-import org.apache.cayenne.testdo.mt.ClientMtTooneDep;
-import org.apache.cayenne.testdo.mt.ClientMtTooneMaster;
-import org.apache.cayenne.testdo.testmap.Artist;
-import org.apache.cayenne.testdo.testmap.Painting;
-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;
-
-/**
- * Tests nested object contexts
- */
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class NestedCayenneContextTest extends RemoteCayenneCase {
-
-    @Inject
-    private ClientRuntime runtime;
-    
-    @Inject
-    private DBHelper dbHelper;
-
-    @Inject
-    private DataChannelInterceptor queryInterceptor;
-
-    @Override
-    public void setUpAfterInjection() throws Exception {
-        super.setUpAfterInjection();
-
-        dbHelper.deleteAll("MT_TABLE2");
-        dbHelper.deleteAll("MT_TABLE1");
-    }
-
-    public void testChannels() {
-        ObjectContext child = runtime.newContext(clientContext);
-
-        assertNotNull(child);
-        assertSame(clientContext, child.getChannel());
-
-        // second level of nesting
-        ObjectContext grandchild = runtime.newContext((DataChannel) child);
-
-        assertNotNull(grandchild);
-        assertSame(child, grandchild.getChannel());
-    }
-
-    public void testSelect() throws Exception {
-        ObjectContext child = runtime.newContext(clientContext);
-
-        ClientMtTable1 committed = clientContext.newObject(ClientMtTable1.class);
-        ClientMtTable1 deleted = clientContext.newObject(ClientMtTable1.class);
-        ClientMtTable1 modified = clientContext.newObject(ClientMtTable1.class);
-
-        clientContext.commitChanges();
-        int modifiedid = Cayenne.intPKForObject(modified);
-
-        // test how different object states appear in the child on select
-
-        clientContext.deleteObjects(deleted);
-        modified.setGlobalAttribute1("a");
-
-        ClientMtTable1 _new = clientContext.newObject(ClientMtTable1.class);
-
-        assertEquals(PersistenceState.COMMITTED, committed.getPersistenceState());
-        assertEquals(PersistenceState.MODIFIED, modified.getPersistenceState());
-        assertEquals(PersistenceState.DELETED, deleted.getPersistenceState());
-        assertEquals(PersistenceState.NEW, _new.getPersistenceState());
-
-        List<?> objects = child.performQuery(new SelectQuery(ClientMtTable1.class));
-        assertEquals("All but NEW object must have been included", 3, objects.size());
-
-        Iterator<?> it = objects.iterator();
-        while (it.hasNext()) {
-            ClientMtTable1 next = (ClientMtTable1) it.next();
-            assertEquals(PersistenceState.COMMITTED, next.getPersistenceState());
-
-            int id = Cayenne.intPKForObject(next);
-            if (id == modifiedid) {
-                assertEquals("a", next.getGlobalAttribute1());
-            }
-        }
-    }
-
-    public void testPrefetchingToOne() throws Exception {
-        final ClientMtTable1 mt11 = clientContext.newObject(ClientMtTable1.class);
-        clientContext.newObject(ClientMtTable1.class);
-        ClientMtTable2 mt21 = clientContext.newObject(ClientMtTable2.class);
-        ClientMtTable2 mt22 = clientContext.newObject(ClientMtTable2.class);
-
-        mt21.setTable1(mt11);
-        mt22.setTable1(mt11);
-
-        clientContext.commitChanges();
-
-        final ObjectContext child = runtime.newContext(clientContext);
-
-        SelectQuery q = new SelectQuery(ClientMtTable2.class);
-        q.addPrefetch(ClientMtTable2.TABLE1_PROPERTY);
-
-        final List<?> results = child.performQuery(q);
-
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                assertEquals(2, results.size());
-                Iterator<?> it = results.iterator();
-                while (it.hasNext()) {
-                    ClientMtTable2 o = (ClientMtTable2) it.next();
-                    assertEquals(PersistenceState.COMMITTED, o.getPersistenceState());
-                    assertSame(child, o.getObjectContext());
-
-                    ClientMtTable1 o1 = o.getTable1();
-                    assertNotNull(o1);
-                    assertEquals(PersistenceState.COMMITTED, o1.getPersistenceState());
-                    assertSame(child, o1.getObjectContext());
-                    assertEquals(mt11.getObjectId(), o1.getObjectId());
-                }
-            }
-        });
-    }
-
-    public void testPrefetchingToMany() throws Exception {
-        ClientMtTable1 mt11 = clientContext.newObject(ClientMtTable1.class);
-        mt11.setGlobalAttribute1("1");
-
-        ClientMtTable1 mt12 = clientContext.newObject(ClientMtTable1.class);
-        mt12.setGlobalAttribute1("2");
-
-        ClientMtTable2 mt21 = clientContext.newObject(ClientMtTable2.class);
-        ClientMtTable2 mt22 = clientContext.newObject(ClientMtTable2.class);
-
-        mt21.setTable1(mt11);
-        mt22.setTable1(mt11);
-
-        clientContext.commitChanges();
-
-        final ObjectContext child = runtime.newContext(clientContext);
-
-        SelectQuery q = new SelectQuery(ClientMtTable1.class);
-        q.addOrdering("globalAttribute1", SortOrder.ASCENDING);
-        q.addPrefetch(ClientMtTable1.TABLE2ARRAY_PROPERTY);
-
-        final List<?> results = child.performQuery(q);
-
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                ClientMtTable1 o1 = (ClientMtTable1) results.get(0);
-                assertEquals(PersistenceState.COMMITTED, o1.getPersistenceState());
-                assertSame(child, o1.getObjectContext());
-
-                List<ClientMtTable2> children1 = o1.getTable2Array();
-
-                assertEquals(2, children1.size());
-                Iterator<ClientMtTable2> it = children1.iterator();
-                while (it.hasNext()) {
-                    ClientMtTable2 o = it.next();
-                    assertEquals(PersistenceState.COMMITTED, o.getPersistenceState());
-                    assertSame(child, o.getObjectContext());
-
-                    assertEquals(o1, o.getTable1());
-                }
-
-                ClientMtTable1 o2 = (ClientMtTable1) results.get(1);
-                assertEquals(PersistenceState.COMMITTED, o2.getPersistenceState());
-                assertSame(child, o2.getObjectContext());
-
-                List<?> children2 = o2.getTable2Array();
-
-                assertEquals(0, children2.size());
-            }
-        });
-    }
-
-    public void testDeleteNew() throws Exception {
-        ObjectContext child = runtime.newContext(clientContext);
-
-        ClientMtTable1 a = clientContext.newObject(ClientMtTable1.class);
-        clientContext.commitChanges();
-
-        ClientMtTable2 p = child.newObject(ClientMtTable2.class);
-        ClientMtTable1 aChild = (ClientMtTable1) Cayenne.objectForPK(
-                child,
-                a.getObjectId());
-        p.setGlobalAttribute("X");
-        aChild.addToTable2Array(p);
-
-        child.commitChangesToParent();
-
-        child.deleteObjects(p);
-        aChild.removeFromTable2Array(p);
-
-        child.commitChangesToParent();
-    }
-
-    /**
-     * A test case for CAY-698 bug.
-     */
-    public void testNullifyToOne() throws Exception {
-        ClientMtTable1 a = clientContext.newObject(ClientMtTable1.class);
-        ClientMtTable2 b = clientContext.newObject(ClientMtTable2.class);
-        a.addToTable2Array(b);
-
-        clientContext.commitChanges();
-
-        final ObjectContext child = runtime.newContext(clientContext);
-        ObjectContext childPeer = runtime.newContext(clientContext);
-
-        final ClientMtTable2 childP1 = (ClientMtTable2) Cayenne.objectForPK(
-                child,
-                b.getObjectId());
-
-        // trigger object creation in the peer nested DC
-        Cayenne.objectForPK(childPeer, b.getObjectId());
-        childP1.setTable1(null);
-
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                child.commitChangesToParent();
-                assertEquals(PersistenceState.COMMITTED, childP1.getPersistenceState());
-
-                ClientMtTable2 parentP1 = (ClientMtTable2) clientContext
-                        .getGraphManager()
-                        .getNode(childP1.getObjectId());
-
-                assertNotNull(parentP1);
-                assertEquals(PersistenceState.MODIFIED, parentP1.getPersistenceState());
-                assertNull(parentP1.getTable1());
-
-                // check that arc changes got recorded in the parent context
-                GraphDiff diffs = clientContext.internalGraphManager().getDiffs();
-                final int[] arcDiffs = new int[1];
-
-                diffs.apply(new GraphChangeHandler() {
-
-                    public void arcCreated(
-                            Object nodeId,
-                            Object targetNodeId,
-                            Object arcId) {
-                        arcDiffs[0]++;
-                    }
-
-                    public void arcDeleted(
-                            Object nodeId,
-                            Object targetNodeId,
-                            Object arcId) {
-                        arcDiffs[0]--;
-                    }
-
-                    public void nodeCreated(Object nodeId) {
-
-                    }
-
-                    public void nodeIdChanged(Object nodeId, Object newId) {
-                    }
-
-                    public void nodePropertyChanged(
-                            Object nodeId,
-                            String property,
-                            Object oldValue,
-                            Object newValue) {
-                    }
-
-                    public void nodeRemoved(Object nodeId) {
-
-                    }
-                });
-
-                assertEquals(-2, arcDiffs[0]);
-            }
-        });
-    }
-
-    public void testCommitChangesToParent() throws Exception {
-        clientContext.newObject(ClientMtTable1.class);
-        clientContext.newObject(ClientMtTable1.class);
-        clientContext.newObject(ClientMtTable1.class);
-        clientContext.newObject(ClientMtTable1.class);
-        clientContext.commitChanges();
-
-        final ObjectContext child = runtime.newContext(clientContext);
-
-        SelectQuery query = new SelectQuery(ClientMtTable1.class);
-        List<?> objects = child.performQuery(query);
-
-        assertEquals(4, objects.size());
-
-        final ClientMtTable1 childNew = child.newObject(ClientMtTable1.class);
-        childNew.setGlobalAttribute1("NNN");
-
-        final ClientMtTable1 childModified = (ClientMtTable1) objects.get(0);
-        childModified.setGlobalAttribute1("MMM");
-
-        final ClientMtTable1 childCommitted = (ClientMtTable1) objects.get(1);
-
-        final ClientMtTable1 childHollow = (ClientMtTable1) objects.get(3);
-        child.invalidateObjects(childHollow);
-
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                child.commitChangesToParent();
-
-                // * all modified child objects must be in committed state now
-                // * all modifications should be propagated to the parent
-                // * no actual commit should occur.
-
-                assertEquals(PersistenceState.COMMITTED, childNew.getPersistenceState());
-                assertEquals(
-                        PersistenceState.COMMITTED,
-                        childModified.getPersistenceState());
-                assertEquals(
-                        PersistenceState.COMMITTED,
-                        childCommitted.getPersistenceState());
-                assertEquals(PersistenceState.HOLLOW, childHollow.getPersistenceState());
-
-                ClientMtTable1 parentNew = (ClientMtTable1) clientContext
-                        .getGraphManager()
-                        .getNode(childNew.getObjectId());
-                final ClientMtTable1 parentModified = (ClientMtTable1) clientContext
-                        .getGraphManager()
-                        .getNode(childModified.getObjectId());
-                ClientMtTable1 parentCommitted = (ClientMtTable1) clientContext
-                        .getGraphManager()
-                        .getNode(childCommitted.getObjectId());
-                ClientMtTable1 parentHollow = (ClientMtTable1) clientContext
-                        .getGraphManager()
-                        .getNode(childHollow.getObjectId());
-
-                assertNotNull(parentNew);
-                assertEquals(PersistenceState.NEW, parentNew.getPersistenceState());
-                assertEquals("NNN", parentNew.getGlobalAttribute1());
-
-                assertNotNull(parentModified);
-                assertEquals(
-                        PersistenceState.MODIFIED,
-                        parentModified.getPersistenceState());
-                assertEquals("MMM", parentModified.getGlobalAttribute1());
-
-                assertNotNull(parentCommitted);
-                assertEquals(
-                        PersistenceState.COMMITTED,
-                        parentCommitted.getPersistenceState());
-
-                assertNotNull(parentHollow);
-
-                // check that arc changes got recorded in the parent context
-                GraphDiff diffs = clientContext.internalGraphManager().getDiffs();
-
-                final int[] modifiedProperties = new int[1];
-
-                diffs.apply(new GraphChangeHandler() {
-
-                    public void arcCreated(
-                            Object nodeId,
-                            Object targetNodeId,
-                            Object arcId) {
-
-                    }
-
-                    public void arcDeleted(
-                            Object nodeId,
-                            Object targetNodeId,
-                            Object arcId) {
-
-                    }
-
-                    public void nodeCreated(Object nodeId) {
-
-                    }
-
-                    public void nodeIdChanged(Object nodeId, Object newId) {
-                    }
-
-                    public void nodePropertyChanged(
-                            Object nodeId,
-                            String property,
-                            Object oldValue,
-                            Object newValue) {
-
-                        if (nodeId.equals(parentModified.getObjectId())) {
-                            modifiedProperties[0]++;
-                        }
-                    }
-
-                    public void nodeRemoved(Object nodeId) {
-
-                    }
-                });
-
-                assertEquals(1, modifiedProperties[0]);
-            }
-        });
-    }
-
-    public void testCommitChangesToParentDeleted() throws Exception {
-        clientContext.newObject(ClientMtTable1.class);
-        clientContext.newObject(ClientMtTable1.class);
-        clientContext.newObject(ClientMtTable1.class);
-        clientContext.newObject(ClientMtTable1.class);
-        clientContext.commitChanges();
-
-        ObjectContext child = runtime.newContext(clientContext);
-
-        // make sure we fetch in predictable order
-        SelectQuery query = new SelectQuery(ClientMtTable1.class);
-        List<?> objects = child.performQuery(query);
-
-        assertEquals(4, objects.size());
-
-        // delete AND modify
-        ClientMtTable1 childDeleted = (ClientMtTable1) objects.get(2);
-        child.deleteObjects(childDeleted);
-        childDeleted.setGlobalAttribute1("DDD");
-
-        // don't block queries - on delete Cayenne may need to resolve delete rules via
-        // fetch
-        child.commitChangesToParent();
-
-        // * all modified child objects must be in committed state now
-        // * all modifications should be propagated to the parent
-        // * no actual commit should occur.
-
-        assertEquals(PersistenceState.TRANSIENT, childDeleted.getPersistenceState());
-
-        ClientMtTable1 parentDeleted = (ClientMtTable1) clientContext
-                .getGraphManager()
-                .getNode(childDeleted.getObjectId());
-
-        assertNotNull(parentDeleted);
-        assertEquals(PersistenceState.DELETED, parentDeleted.getPersistenceState());
-        assertEquals("DDD", parentDeleted.getGlobalAttribute1());
-    }
-
-    /*
-     * was added for CAY-1636
-     */
-    public void testCAY1636() throws Exception {
-
-        ClientMtTooneMaster A = clientContext.newObject(ClientMtTooneMaster.class);
-        clientContext.commitChanges();
-
-        ClientMtTooneDep B = clientContext.newObject(ClientMtTooneDep.class);
-        A.setToDependent(B);
-        clientContext.commitChanges();
-
-        ObjectContext child = runtime.newContext(clientContext);
-
-        SelectQuery query = new SelectQuery(ClientMtTooneMaster.class);
-        List<?> objects = child.performQuery(query);
-
-        assertEquals(1, objects.size());
-
-        ClientMtTooneMaster childDeleted = (ClientMtTooneMaster) objects.get(0);
-
-        child.deleteObjects(childDeleted);
-
-        child.commitChangesToParent();
-
-        ClientMtTooneMaster parentDeleted = (ClientMtTooneMaster) clientContext
-                .getGraphManager()
-                .getNode(childDeleted.getObjectId());
-
-        assertNotNull(parentDeleted);
-        assertEquals(PersistenceState.DELETED, parentDeleted.getPersistenceState());
-
-        clientContext.commitChanges();
-
-        SelectQuery query2 = new SelectQuery(ClientMtTooneMaster.class);
-        List<?> objects2 = child.performQuery(query2);
-
-        assertEquals(0, objects2.size());
-
-    }
-
-    public void testCAY1636_2() throws Exception {
-
-        ClientMtTooneMaster A = clientContext.newObject(ClientMtTooneMaster.class);
-        clientContext.commitChanges();
-
-        ClientMtTooneDep B = clientContext.newObject(ClientMtTooneDep.class);
-        A.setToDependent(B);
-        clientContext.commitChanges();
-
-        ObjectContext child = runtime.newContext(clientContext);
-
-        SelectQuery queryB = new SelectQuery(ClientMtTooneDep.class);
-        List<?> objectsB = child.performQuery(queryB);
-
-        assertEquals(1, objectsB.size());
-
-        ClientMtTooneDep childBDeleted = (ClientMtTooneDep) objectsB.get(0);
-        child.deleteObjects(childBDeleted);
-
-        SelectQuery query = new SelectQuery(ClientMtTooneMaster.class);
-        List<?> objects = child.performQuery(query);
-
-        assertEquals(1, objects.size());
-
-        ClientMtTooneMaster childDeleted = (ClientMtTooneMaster) objects.get(0);
-
-        child.deleteObjects(childDeleted);
-
-        child.commitChangesToParent();
-
-        ClientMtTooneMaster parentDeleted = (ClientMtTooneMaster) clientContext
-                .getGraphManager()
-                .getNode(childDeleted.getObjectId());
-
-        assertNotNull(parentDeleted);
-        assertEquals(PersistenceState.DELETED, parentDeleted.getPersistenceState());
-
-        clientContext.commitChanges();
-
-        SelectQuery query2 = new SelectQuery(ClientMtTooneMaster.class);
-        List<?> objects2 = child.performQuery(query2);
-
-        assertEquals(0, objects2.size());
-
-    }
-
-    public void testCommitChanges() throws Exception {
-        clientContext.newObject(ClientMtTable1.class);
-        clientContext.newObject(ClientMtTable1.class);
-        clientContext.newObject(ClientMtTable1.class);
-        clientContext.newObject(ClientMtTable1.class);
-        clientContext.commitChanges();
-
-        ObjectContext child = runtime.newContext(clientContext);
-
-        // make sure we fetch in predictable order
-        SelectQuery query = new SelectQuery(ClientMtTable1.class);
-        List<?> objects = child.performQuery(query);
-
-        assertEquals(4, objects.size());
-
-        ClientMtTable1 childNew = child.newObject(ClientMtTable1.class);
-        childNew.setGlobalAttribute1("NNN");
-
-        ClientMtTable1 childModified = (ClientMtTable1) objects.get(0);
-        childModified.setGlobalAttribute1("MMM");
-
-        ClientMtTable1 childCommitted = (ClientMtTable1) objects.get(1);
-
-        // delete AND modify
-        ClientMtTable1 childDeleted = (ClientMtTable1) objects.get(2);
-        child.deleteObjects(childDeleted);
-        childDeleted.setGlobalAttribute1("DDD");
-
-        ClientMtTable1 childHollow = (ClientMtTable1) objects.get(3);
-        child.invalidateObjects(childHollow);
-
-        child.commitChanges();
-
-        assertEquals(PersistenceState.COMMITTED, childNew.getPersistenceState());
-        assertEquals(PersistenceState.COMMITTED, childModified.getPersistenceState());
-        assertEquals(PersistenceState.COMMITTED, childCommitted.getPersistenceState());
-        assertEquals(PersistenceState.TRANSIENT, childDeleted.getPersistenceState());
-        assertEquals(PersistenceState.HOLLOW, childHollow.getPersistenceState());
-
-        ClientMtTable1 parentNew = (ClientMtTable1) clientContext
-                .getGraphManager()
-                .getNode(childNew.getObjectId());
-        ClientMtTable1 parentModified = (ClientMtTable1) clientContext
-                .getGraphManager()
-                .getNode(childModified.getObjectId());
-        ClientMtTable1 parentCommitted = (ClientMtTable1) clientContext
-                .getGraphManager()
-                .getNode(childCommitted.getObjectId());
-        ClientMtTable1 parentDeleted = (ClientMtTable1) clientContext
-                .getGraphManager()
-                .getNode(childDeleted.getObjectId());
-        ClientMtTable1 parentHollow = (ClientMtTable1) clientContext
-                .getGraphManager()
-                .getNode(childHollow.getObjectId());
-
-        assertNotNull(parentNew);
-        assertEquals(PersistenceState.COMMITTED, parentNew.getPersistenceState());
-        assertEquals("NNN", parentNew.getGlobalAttribute1());
-
-        assertNotNull(parentModified);
-        assertEquals(PersistenceState.COMMITTED, parentModified.getPersistenceState());
-        assertEquals("MMM", parentModified.getGlobalAttribute1());
-
-        assertNull("Deleted object should not be registered.", parentDeleted);
-
-        assertNotNull(parentCommitted);
-        assertEquals(PersistenceState.COMMITTED, parentCommitted.getPersistenceState());
-
-        assertNotNull(parentHollow);
-    }
-
-    public void testAddRemove() throws Exception {
-        ObjectContext child = runtime.newContext(clientContext);
-
-        ClientMtTable1 a = child.newObject(ClientMtTable1.class);
-        a.setGlobalAttribute1("X");
-        child.commitChanges();
-
-        ClientMtTable2 p1 = child.newObject(ClientMtTable2.class);
-        p1.setGlobalAttribute("P1");
-        a.addToTable2Array(p1);
-
-        ClientMtTable2 p2 = child.newObject(ClientMtTable2.class);
-        p2.setGlobalAttribute("P2");
-        a.addToTable2Array(p2);
-
-        a.removeFromTable2Array(p2);
-
-        // this causes an error on commit
-        child.deleteObjects(p2);
-
-        child.commitChangesToParent();
-
-    }
-
-    public void testChangeRel() throws Exception {
-        ObjectContext child = runtime.newContext(clientContext);
-
-        ClientMtTable1 a = child.newObject(ClientMtTable1.class);
-        ClientMtTable2 b = child.newObject(ClientMtTable2.class);
-        child.commitChanges();
-
-        assertEquals(PersistenceState.COMMITTED, a.getPersistenceState());
-
-        a.addToTable2Array(b);
-        assertEquals(PersistenceState.MODIFIED, a.getPersistenceState());
-
-        child.commitChangesToParent();
-        ClientMtTable1 parentA = (ClientMtTable1) clientContext
-                .getGraphManager()
-                .getNode(a.getObjectId());
-        assertEquals(PersistenceState.COMMITTED, a.getPersistenceState());
-        assertEquals(PersistenceState.MODIFIED, parentA.getPersistenceState());
-        assertEquals(1, parentA.getTable2Array().size());
-
-        clientContext.commitChanges();
-        assertEquals(PersistenceState.COMMITTED, parentA.getPersistenceState());
-
-        a.removeFromTable2Array(b);
-        assertEquals(PersistenceState.MODIFIED, a.getPersistenceState());
-
-        child.commitChangesToParent();
-        assertEquals(PersistenceState.COMMITTED, a.getPersistenceState());
-        assertEquals(PersistenceState.MODIFIED, parentA.getPersistenceState());
-        assertEquals(0, parentA.getTable2Array().size());
-    }
-
-    public void testCAY1183() throws Exception {
-        ClientMtTable1 parentMt = clientContext.newObject(ClientMtTable1.class);
-        clientContext.commitChanges();
-
-        ObjectContext child = runtime.newContext(clientContext);
-        ClientMtTable1 childMt = (ClientMtTable1) Cayenne.objectForPK(
-                child,
-                parentMt.getObjectId());
-        childMt.setGlobalAttribute1("1183");
-        ClientMtTable2 childMt2 = child.newObject(ClientMtTable2.class);
-        childMt2.setGlobalAttribute("1183");
-        childMt2.setTable1(childMt);
-
-        child.commitChangesToParent();
-
-        // fetching other relationship... this fails per CAY-1183
-        childMt2.getTable3();
-    }
-    
-    /**
-     * CAY1714
-     */
-    public void testQueriesOnTemporaryObject() throws Exception {
-        ObjectContext clientContext = runtime.newContext((DataChannel) this.clientContext);
-        ClientMtTable1 parentMt = clientContext.newObject(ClientMtTable1.class);
-
-        ObjectContext childContext = runtime.newContext((DataChannel) clientContext);
-        ClientMtTable1 childMt = (ClientMtTable1) Cayenne.objectForPK(childContext, parentMt.getObjectId());
-        childMt.setGlobalAttribute1("1183");
-        ClientMtTable2 childMt2 = childContext.newObject(ClientMtTable2.class);
-        childMt2.setGlobalAttribute("1183");
-        childMt2.setTable1(childMt);
-
-        childContext.commitChangesToParent();
-
-        assertNull(childMt2.getTable3());
-    }
-
-    public void testCAY1194() throws Exception {
-        ClientMtTable1 parentMt = clientContext.newObject(ClientMtTable1.class);
-        ObjectContext child = runtime.newContext(clientContext);
-
-        ClientMtTable2 childMt2 = child.newObject(ClientMtTable2.class);
-        childMt2.setGlobalAttribute("222");
-
-        ClientMtTable1 localParentMt = child.localObject(parentMt);
-        assertEquals(0, parentMt.getTable2Array().size());
-        assertEquals(0, localParentMt.getTable2Array().size());
-
-        childMt2.setTable1(localParentMt);
-
-        assertEquals(0, parentMt.getTable2Array().size());
-        assertEquals(1, localParentMt.getTable2Array().size());
-
-        assertEquals(localParentMt.getTable2Array().get(0).getObjectContext(), child);
-
-        child.commitChangesToParent();
-        assertEquals(1, parentMt.getTable2Array().size());
-        assertEquals(parentMt.getTable2Array().get(0).getObjectContext(), clientContext);
-    }
-
-    public void testCommitChangesToParentOneToMany() throws Exception {
-        ObjectContext child = runtime.newContext(clientContext);
-
-        ClientMtTable1 master = child.newObject(ClientMtTable1.class);
-        ClientMtTable2 dep = child.newObject(ClientMtTable2.class);
-        master.addToTable2Array(dep);
-
-        child.commitChangesToParent();
-
-        ClientMtTable1 masterParent = (ClientMtTable1) clientContext
-                .getGraphManager()
-                .getNode(master.getObjectId());
-        ClientMtTable2 depParent = (ClientMtTable2) clientContext
-                .getGraphManager()
-                .getNode(dep.getObjectId());
-
-        assertNotNull(masterParent);
-        assertNotNull(depParent);
-
-        assertSame(masterParent, depParent.getTable1());
-        assertTrue(masterParent.getTable2Array().contains(depParent));
-
-        // check that arc changes got recorded in the parent context
-        GraphDiff diffs = clientContext.internalGraphManager().getDiffs();
-
-        final int[] arcDiffs = new int[1];
-        final int[] newNodes = new int[1];
-
-        diffs.apply(new GraphChangeHandler() {
-
-            public void arcCreated(Object nodeId, Object targetNodeId, Object arcId) {
-                arcDiffs[0]++;
-            }
-
-            public void arcDeleted(Object nodeId, Object targetNodeId, Object arcId) {
-                arcDiffs[0]--;
-            }
-
-            public void nodeCreated(Object nodeId) {
-                newNodes[0]++;
-            }
-
-            public void nodeIdChanged(Object nodeId, Object newId) {
-            }
-
-            public void nodePropertyChanged(
-                    Object nodeId,
-                    String property,
-                    Object oldValue,
-                    Object newValue) {
-            }
-
-            public void nodeRemoved(Object nodeId) {
-                newNodes[0]--;
-            }
-        });
-
-        assertEquals(2, newNodes[0]);
-        assertEquals(2, arcDiffs[0]);
-    }
-
-    public void testCommitChangesToParentOneToOne() throws Exception {
-        ObjectContext child = runtime.newContext(clientContext);
-
-        ClientMtTooneMaster master = child.newObject(ClientMtTooneMaster.class);
-        ClientMtTooneDep dep = child.newObject(ClientMtTooneDep.class);
-        master.setToDependent(dep);
-
-        child.commitChangesToParent();
-
-        ClientMtTooneMaster masterParent = (ClientMtTooneMaster) clientContext
-                .getGraphManager()
-                .getNode(master.getObjectId());
-        ClientMtTooneDep depParent = (ClientMtTooneDep) clientContext
-                .getGraphManager()
-                .getNode(dep.getObjectId());
-
-        assertNotNull(masterParent);
-        assertNotNull(depParent);
-
-        assertSame(masterParent, depParent.getToMaster());
-        assertSame(depParent, masterParent.getToDependent());
-
-        // check that arc changes got recorded in the parent context
-        GraphDiff diffs = clientContext.internalGraphManager().getDiffs();
-
-        final int[] arcDiffs = new int[1];
-        final int[] newNodes = new int[1];
-
-        diffs.apply(new GraphChangeHandler() {
-
-            public void arcCreated(Object nodeId, Object targetNodeId, Object arcId) {
-                arcDiffs[0]++;
-            }
-
-            public void arcDeleted(Object nodeId, Object targetNodeId, Object arcId) {
-                arcDiffs[0]--;
-            }
-
-            public void nodeCreated(Object nodeId) {
-                newNodes[0]++;
-            }
-
-            public void nodeIdChanged(Object nodeId, Object newId) {
-            }
-
-            public void nodePropertyChanged(
-                    Object nodeId,
-                    String property,
-                    Object oldValue,
-                    Object newValue) {
-            }
-
-            public void nodeRemoved(Object nodeId) {
-                newNodes[0]--;
-            }
-        });
-
-        assertEquals(2, newNodes[0]);
-        assertEquals(2, arcDiffs[0]);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/PersistentObjectInContextIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/PersistentObjectInContextIT.java b/cayenne-client/src/test/java/org/apache/cayenne/PersistentObjectInContextIT.java
new file mode 100644
index 0000000..f9775a4
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/PersistentObjectInContextIT.java
@@ -0,0 +1,142 @@
+/*****************************************************************
+ *   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;
+
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.query.ObjectIdQuery;
+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.testdo.mt.MtTable1;
+import org.apache.cayenne.testdo.mt.MtTable2;
+import org.apache.cayenne.unit.di.client.ClientCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+import org.apache.cayenne.util.PersistentObjectHolder;
+
+import java.util.List;
+
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class PersistentObjectInContextIT 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");
+    }
+
+    private 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 testResolveToManyReverseResolved() throws Exception {
+        createTwoMtTable1sAnd2sDataSet();
+
+        ObjectId gid = new ObjectId(
+                "MtTable1",
+                MtTable1.TABLE1_ID_PK_COLUMN,
+                new Integer(1));
+        ClientMtTable1 t1 = (ClientMtTable1) Cayenne.objectForQuery(
+                context,
+                new ObjectIdQuery(gid));
+
+        assertNotNull(t1);
+
+        List<ClientMtTable2> t2s = t1.getTable2Array();
+        assertEquals(2, t2s.size());
+
+        for (ClientMtTable2 t2 : t2s) {
+
+            PersistentObjectHolder holder = (PersistentObjectHolder) t2.getTable1Direct();
+            assertFalse(holder.isFault());
+            assertSame(t1, holder.getValue());
+        }
+    }
+
+    public void testToOneRelationship() throws Exception {
+        createTwoMtTable1sAnd2sDataSet();
+
+        ObjectId gid = new ObjectId(
+                "MtTable2",
+                MtTable2.TABLE2_ID_PK_COLUMN,
+                new Integer(1));
+        ClientMtTable2 mtTable21 = (ClientMtTable2) Cayenne.objectForQuery(
+                context,
+                new ObjectIdQuery(gid));
+
+        assertNotNull(mtTable21);
+
+        ClientMtTable1 mtTable1 = mtTable21.getTable1();
+        assertNotNull("To one relationship incorrectly resolved to null", mtTable1);
+        assertEquals("g1", mtTable1.getGlobalAttribute1());
+    }
+
+    public void testResolveToOneReverseResolved() throws Exception {
+        createTwoMtTable1sAnd2sDataSet();
+
+        ObjectId gid = new ObjectId(
+                "MtTable2",
+                MtTable2.TABLE2_ID_PK_COLUMN,
+                new Integer(1));
+        ClientMtTable2 mtTable21 = (ClientMtTable2) Cayenne.objectForQuery(
+                context,
+                new ObjectIdQuery(gid));
+
+        assertNotNull(mtTable21);
+
+        ClientMtTable1 mtTable1 = mtTable21.getTable1();
+        assertNotNull("To one relationship incorrectly resolved to null", mtTable1);
+
+        List<ClientMtTable2> list = mtTable1.getTable2Array();
+        assertNotNull(list);
+        assertTrue(list instanceof ValueHolder);
+
+        assertTrue(((ValueHolder) list).isFault());
+
+        // resolve it here...
+        assertEquals(2, list.size());
+        for (ClientMtTable2 t2 : list) {
+            PersistentObjectHolder holder = (PersistentObjectHolder) t2.getTable1Direct();
+            assertFalse(holder.isFault());
+            assertSame(mtTable1, holder.getValue());
+        }
+
+        assertEquals("g1", mtTable1.getGlobalAttribute1());
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/PersistentObjectInContextTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/PersistentObjectInContextTest.java b/cayenne-client/src/test/java/org/apache/cayenne/PersistentObjectInContextTest.java
deleted file mode 100644
index 57c9843..0000000
--- a/cayenne-client/src/test/java/org/apache/cayenne/PersistentObjectInContextTest.java
+++ /dev/null
@@ -1,142 +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;
-
-import java.util.List;
-
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.query.ObjectIdQuery;
-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.testdo.mt.MtTable1;
-import org.apache.cayenne.testdo.mt.MtTable2;
-import org.apache.cayenne.unit.di.client.ClientCase;
-import org.apache.cayenne.unit.di.server.UseServerRuntime;
-import org.apache.cayenne.util.PersistentObjectHolder;
-
-@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
-public class PersistentObjectInContextTest 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");
-    }
-
-    private 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 testResolveToManyReverseResolved() throws Exception {
-        createTwoMtTable1sAnd2sDataSet();
-
-        ObjectId gid = new ObjectId(
-                "MtTable1",
-                MtTable1.TABLE1_ID_PK_COLUMN,
-                new Integer(1));
-        ClientMtTable1 t1 = (ClientMtTable1) Cayenne.objectForQuery(
-                context,
-                new ObjectIdQuery(gid));
-
-        assertNotNull(t1);
-
-        List<ClientMtTable2> t2s = t1.getTable2Array();
-        assertEquals(2, t2s.size());
-
-        for (ClientMtTable2 t2 : t2s) {
-
-            PersistentObjectHolder holder = (PersistentObjectHolder) t2.getTable1Direct();
-            assertFalse(holder.isFault());
-            assertSame(t1, holder.getValue());
-        }
-    }
-
-    public void testToOneRelationship() throws Exception {
-        createTwoMtTable1sAnd2sDataSet();
-
-        ObjectId gid = new ObjectId(
-                "MtTable2",
-                MtTable2.TABLE2_ID_PK_COLUMN,
-                new Integer(1));
-        ClientMtTable2 mtTable21 = (ClientMtTable2) Cayenne.objectForQuery(
-                context,
-                new ObjectIdQuery(gid));
-
-        assertNotNull(mtTable21);
-
-        ClientMtTable1 mtTable1 = mtTable21.getTable1();
-        assertNotNull("To one relationship incorrectly resolved to null", mtTable1);
-        assertEquals("g1", mtTable1.getGlobalAttribute1());
-    }
-
-    public void testResolveToOneReverseResolved() throws Exception {
-        createTwoMtTable1sAnd2sDataSet();
-
-        ObjectId gid = new ObjectId(
-                "MtTable2",
-                MtTable2.TABLE2_ID_PK_COLUMN,
-                new Integer(1));
-        ClientMtTable2 mtTable21 = (ClientMtTable2) Cayenne.objectForQuery(
-                context,
-                new ObjectIdQuery(gid));
-
-        assertNotNull(mtTable21);
-
-        ClientMtTable1 mtTable1 = mtTable21.getTable1();
-        assertNotNull("To one relationship incorrectly resolved to null", mtTable1);
-
-        List<ClientMtTable2> list = mtTable1.getTable2Array();
-        assertNotNull(list);
-        assertTrue(list instanceof ValueHolder);
-
-        assertTrue(((ValueHolder) list).isFault());
-
-        // resolve it here...
-        assertEquals(2, list.size());
-        for (ClientMtTable2 t2 : list) {
-            PersistentObjectHolder holder = (PersistentObjectHolder) t2.getTable1Direct();
-            assertFalse(holder.isFault());
-            assertSame(mtTable1, holder.getValue());
-        }
-
-        assertEquals("g1", mtTable1.getGlobalAttribute1());
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/fcb1d536/cayenne-client/src/test/java/org/apache/cayenne/access/ClientServerChannelIT.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/access/ClientServerChannelIT.java b/cayenne-client/src/test/java/org/apache/cayenne/access/ClientServerChannelIT.java
new file mode 100644
index 0000000..f5cd8f1
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/access/ClientServerChannelIT.java
@@ -0,0 +1,260 @@
+/*****************************************************************
+ *   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.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;
+
+import java.util.List;
+
+@UseServerRuntime(ClientCase.MULTI_TIER_PROJECT)
+public class ClientServerChannelIT 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());
+            }
+        });
+    }
+}