Optimize IMDT tests
[yangtools.git] / yang / yang-data-impl / src / test / java / org / opendaylight / yangtools / yang / data / impl / schema / tree / ConcurrentTreeModificationTest.java
index 48a6761e3e02746a7db2c0fbcfcc051d6e566642..86434523ea61bb3b71f8beeb899ce4a8c70a55f9 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
 
 import static org.junit.Assert.assertFalse;
@@ -7,7 +14,7 @@ import static org.junit.Assert.fail;
 import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntryBuilder;
 import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapNodeBuilder;
 
-import com.google.common.base.Optional;
+import java.util.Optional;
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
@@ -15,56 +22,52 @@ import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.ConflictingModificationAppliedException;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.TreeType;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class ConcurrentTreeModificationTest {
+public class ConcurrentTreeModificationTest extends AbstractTestModelTest {
     private static final Logger LOG = LoggerFactory.getLogger(ConcurrentTreeModificationTest.class);
 
     private static final Short ONE_ID = 1;
     private static final Short TWO_ID = 2;
 
-    private static final YangInstanceIdentifier OUTER_LIST_1_PATH = YangInstanceIdentifier.builder(TestModel.OUTER_LIST_PATH)
-            .nodeWithKey(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, ONE_ID) //
+    private static final YangInstanceIdentifier OUTER_LIST_1_PATH = YangInstanceIdentifier.builder(
+        TestModel.OUTER_LIST_PATH)
+            .nodeWithKey(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, ONE_ID)
             .build();
 
-    private static final YangInstanceIdentifier OUTER_LIST_2_PATH = YangInstanceIdentifier.builder(TestModel.OUTER_LIST_PATH)
-            .nodeWithKey(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, TWO_ID) //
+    private static final YangInstanceIdentifier OUTER_LIST_2_PATH = YangInstanceIdentifier.builder(
+        TestModel.OUTER_LIST_PATH)
+            .nodeWithKey(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, TWO_ID)
             .build();
 
-    private static final MapEntryNode FOO_NODE = mapEntryBuilder(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, ONE_ID) //
-            .withChild(mapNodeBuilder(TestModel.INNER_LIST_QNAME) //
-                    .build()) //
+    private static final MapEntryNode FOO_NODE = mapEntryBuilder(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, ONE_ID)
+            .withChild(mapNodeBuilder(TestModel.INNER_LIST_QNAME).build())
             .build();
 
-    private static final MapEntryNode BAR_NODE = mapEntryBuilder(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, TWO_ID) //
-            .withChild(mapNodeBuilder(TestModel.INNER_LIST_QNAME) //
-                    .build()) //
+    private static final MapEntryNode BAR_NODE = mapEntryBuilder(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, TWO_ID)
+            .withChild(mapNodeBuilder(TestModel.INNER_LIST_QNAME).build())
             .build();
 
-    private SchemaContext schemaContext;
-    private RootModificationApplyOperation rootOper;
-    private InMemoryDataTree inMemoryDataTree;
+    private DataTree inMemoryDataTree;
+
 
     @Before
     public void prepare() {
-        schemaContext = TestModel.createTestContext();
-        assertNotNull("Schema context must not be null.", schemaContext);
-        rootOper = RootModificationApplyOperation.from(SchemaAwareApplyOperation.from(schemaContext,TreeType.OPERATIONAL));
-        inMemoryDataTree = (InMemoryDataTree) InMemoryDataTreeFactory.getInstance().create();
-        inMemoryDataTree.setSchemaContext(schemaContext);
+        inMemoryDataTree = new InMemoryDataTreeFactory().create(DataTreeConfiguration.DEFAULT_OPERATIONAL,
+            SCHEMA_CONTEXT);
     }
 
     private static ContainerNode createFooTestContainerNode() {
-        return ImmutableContainerNodeBuilder
-                .create()
+        return ImmutableContainerNodeBuilder.create()
                 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(TestModel.TEST_QNAME))
                 .withChild(
                         mapNodeBuilder(TestModel.OUTER_LIST_QNAME)
@@ -89,16 +92,16 @@ public class ConcurrentTreeModificationTest {
 
     @Test
     public void writeWrite1stLevelEmptyTreeTest() throws DataValidationFailedException {
-        final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
 
-        final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
-        final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
+        final DataTreeModification modificationTree1 = initialDataTreeSnapshot.newModification();
+        final DataTreeModification modificationTree2 = initialDataTreeSnapshot.newModification();
 
         modificationTree1.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
         modificationTree2.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
 
+        modificationTree1.ready();
+        modificationTree2.ready();
         inMemoryDataTree.validate(modificationTree1);
         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
         inMemoryDataTree.commit(prepare1);
@@ -107,7 +110,7 @@ public class ConcurrentTreeModificationTest {
             inMemoryDataTree.validate(modificationTree2);
             fail("Exception should have been thrown.");
         } catch (final ConflictingModificationAppliedException ex) {
-            LOG.debug("ConflictingModificationAppliedException - '{}' was thrown as expected.");
+            LOG.debug("ConflictingModificationAppliedException - was thrown as expected", ex);
         }
         final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
         inMemoryDataTree.commit(prepare2);
@@ -118,16 +121,17 @@ public class ConcurrentTreeModificationTest {
 
     @Test
     public void writeMerge1stLevelEmptyTreeTest() throws DataValidationFailedException {
-        final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
 
-        final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
-        final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
+        final DataTreeModification modificationTree1 = initialDataTreeSnapshot.newModification();
+        final DataTreeModification modificationTree2 = initialDataTreeSnapshot.newModification();
 
         modificationTree1.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
         modificationTree2.merge(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
 
+        modificationTree1.ready();
+        modificationTree2.ready();
+
         inMemoryDataTree.validate(modificationTree1);
         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
         inMemoryDataTree.commit(prepare1);
@@ -142,15 +146,15 @@ public class ConcurrentTreeModificationTest {
 
     @Test
     public void writeWriteFooBar1stLevelEmptyTreeTest() throws DataValidationFailedException {
-        final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
 
-        final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
-        final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
+        final DataTreeModification modificationTree1 = initialDataTreeSnapshot.newModification();
+        final DataTreeModification modificationTree2 = initialDataTreeSnapshot.newModification();
 
         modificationTree1.write(TestModel.TEST_PATH, createFooTestContainerNode());
         modificationTree2.write(TestModel.TEST_PATH, createBarTestContainerNode());
+        modificationTree1.ready();
+        modificationTree2.ready();
 
         inMemoryDataTree.validate(modificationTree1);
         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
@@ -162,25 +166,25 @@ public class ConcurrentTreeModificationTest {
             final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
             inMemoryDataTree.commit(prepare2);
         } catch (final ConflictingModificationAppliedException ex) {
-            LOG.debug("ConflictingModificationAppliedException - '{}' was thrown as expected.");
+            LOG.debug("ConflictingModificationAppliedException - was thrown as expected", ex);
         }
 
-        final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
         assertFalse(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH).isPresent());
     }
 
     @Test
     public void writeMergeFooBar1stLevelEmptyTreeTest() throws DataValidationFailedException {
-        final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
 
-        final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
-        final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
+        final DataTreeModification modificationTree1 = initialDataTreeSnapshot.newModification();
+        final DataTreeModification modificationTree2 = initialDataTreeSnapshot.newModification();
 
         modificationTree1.write(TestModel.TEST_PATH, createFooTestContainerNode());
         modificationTree2.merge(TestModel.TEST_PATH, createBarTestContainerNode());
+        modificationTree1.ready();
+        modificationTree2.ready();
 
         inMemoryDataTree.validate(modificationTree1);
         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
@@ -190,22 +194,22 @@ public class ConcurrentTreeModificationTest {
         final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
         inMemoryDataTree.commit(prepare2);
 
-        final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH), MapEntryNode.class);
     }
 
     @Test
     public void mergeWriteFooBar1stLevelEmptyTreeTest() throws DataValidationFailedException {
-        final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
 
-        final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
-        final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
+        final DataTreeModification modificationTree1 = initialDataTreeSnapshot.newModification();
+        final DataTreeModification modificationTree2 = initialDataTreeSnapshot.newModification();
 
         modificationTree1.merge(TestModel.TEST_PATH, createFooTestContainerNode());
         modificationTree2.write(TestModel.TEST_PATH, createBarTestContainerNode());
+        modificationTree1.ready();
+        modificationTree2.ready();
 
         inMemoryDataTree.validate(modificationTree1);
         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
@@ -217,25 +221,25 @@ public class ConcurrentTreeModificationTest {
             final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
             inMemoryDataTree.commit(prepare2);
         } catch (final ConflictingModificationAppliedException ex) {
-            LOG.debug("ConflictingModificationAppliedException - '{}' was thrown as expected.");
+            LOG.debug("ConflictingModificationAppliedException - was thrown as expected", ex);
         }
 
-        final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
         assertFalse(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH).isPresent());
     }
 
     @Test
     public void mergeMergeFooBar1stLevelEmptyTreeTest() throws DataValidationFailedException {
-        final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
 
-        final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
-        final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
+        final DataTreeModification modificationTree1 = initialDataTreeSnapshot.newModification();
+        final DataTreeModification modificationTree2 = initialDataTreeSnapshot.newModification();
 
         modificationTree1.merge(TestModel.TEST_PATH, createFooTestContainerNode());
         modificationTree2.merge(TestModel.TEST_PATH, createBarTestContainerNode());
+        modificationTree1.ready();
+        modificationTree2.ready();
 
         inMemoryDataTree.validate(modificationTree1);
         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
@@ -245,7 +249,7 @@ public class ConcurrentTreeModificationTest {
         final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
         inMemoryDataTree.commit(prepare2);
 
-        final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH), MapEntryNode.class);
     }
@@ -254,16 +258,17 @@ public class ConcurrentTreeModificationTest {
     public void writeWriteFooBar1stLevelEmptyContainerTest() throws DataValidationFailedException {
         final DataTreeModification initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
         initialDataTreeModification.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
+        initialDataTreeModification.ready();
         inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
-        final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
 
-        final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
-        final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
+        final DataTreeModification modificationTree1 = initialDataTreeSnapshot.newModification();
+        final DataTreeModification modificationTree2 = initialDataTreeSnapshot.newModification();
 
         modificationTree1.write(TestModel.TEST_PATH, createFooTestContainerNode());
         modificationTree2.write(TestModel.TEST_PATH, createBarTestContainerNode());
+        modificationTree1.ready();
+        modificationTree2.ready();
 
         inMemoryDataTree.validate(modificationTree1);
         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
@@ -275,10 +280,10 @@ public class ConcurrentTreeModificationTest {
             final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
             inMemoryDataTree.commit(prepare2);
         } catch (final ConflictingModificationAppliedException ex) {
-            LOG.debug("ConflictingModificationAppliedException - '{}' was thrown as expected.");
+            LOG.debug("ConflictingModificationAppliedException was thrown as expected", ex);
         }
 
-        final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
         assertFalse(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH).isPresent());
     }
@@ -287,16 +292,17 @@ public class ConcurrentTreeModificationTest {
     public void writeMergeFooBar1stLevelEmptyContainerTest() throws DataValidationFailedException {
         final DataTreeModification initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
         initialDataTreeModification.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
+        initialDataTreeModification.ready();
         inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
-        final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
 
-        final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
-        final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
+        final DataTreeModification modificationTree1 = initialDataTreeSnapshot.newModification();
+        final DataTreeModification modificationTree2 = initialDataTreeSnapshot.newModification();
 
         modificationTree1.write(TestModel.TEST_PATH, createFooTestContainerNode());
         modificationTree2.merge(TestModel.TEST_PATH, createBarTestContainerNode());
+        modificationTree1.ready();
+        modificationTree2.ready();
 
         inMemoryDataTree.validate(modificationTree1);
         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
@@ -306,26 +312,26 @@ public class ConcurrentTreeModificationTest {
         final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
         inMemoryDataTree.commit(prepare2);
 
-        final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH), MapEntryNode.class);
     }
 
-
     @Test
     public void mergeWriteFooBar1stLevelEmptyContainerTest() throws DataValidationFailedException {
         final DataTreeModification initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
         initialDataTreeModification.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
+        initialDataTreeModification.ready();
         inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
-        final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
 
-        final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
-        final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
+        final DataTreeModification modificationTree1 = initialDataTreeSnapshot.newModification();
+        final DataTreeModification modificationTree2 = initialDataTreeSnapshot.newModification();
 
         modificationTree1.merge(TestModel.TEST_PATH, createFooTestContainerNode());
         modificationTree2.write(TestModel.TEST_PATH, createBarTestContainerNode());
+        modificationTree1.ready();
+        modificationTree2.ready();
 
         inMemoryDataTree.validate(modificationTree1);
         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
@@ -337,11 +343,11 @@ public class ConcurrentTreeModificationTest {
             final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
             inMemoryDataTree.commit(prepare2);
         } catch (final ConflictingModificationAppliedException ex) {
-            LOG.debug("ConflictingModificationAppliedException - '{}' was thrown as expected.");
+            LOG.debug("ConflictingModificationAppliedException was thrown as expected", ex);
         }
 
 
-        final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
         assertFalse(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH).isPresent());
     }
@@ -350,16 +356,17 @@ public class ConcurrentTreeModificationTest {
     public void mergeMergeFooBar1stLevelEmptyContainerTest() throws DataValidationFailedException {
         final DataTreeModification initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
         initialDataTreeModification.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
+        initialDataTreeModification.ready();
         inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
-        final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
 
-        final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
-        final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
+        final DataTreeModification modificationTree1 = initialDataTreeSnapshot.newModification();
+        final DataTreeModification modificationTree2 = initialDataTreeSnapshot.newModification();
 
         modificationTree1.merge(TestModel.TEST_PATH, createFooTestContainerNode());
         modificationTree2.merge(TestModel.TEST_PATH, createBarTestContainerNode());
+        modificationTree1.ready();
+        modificationTree2.ready();
 
         inMemoryDataTree.validate(modificationTree1);
         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
@@ -369,7 +376,7 @@ public class ConcurrentTreeModificationTest {
         final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
         inMemoryDataTree.commit(prepare2);
 
-        final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH), MapEntryNode.class);
     }
@@ -378,16 +385,17 @@ public class ConcurrentTreeModificationTest {
     public void deleteWriteFooBar1stLevelEmptyContainerTest() throws DataValidationFailedException {
         final DataTreeModification initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
         initialDataTreeModification.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
+        initialDataTreeModification.ready();
         inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
-        final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
 
-        final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
-        final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
+        final DataTreeModification modificationTree1 = initialDataTreeSnapshot.newModification();
+        final DataTreeModification modificationTree2 = initialDataTreeSnapshot.newModification();
 
         modificationTree1.delete(TestModel.TEST_PATH);
         modificationTree2.write(TestModel.TEST_PATH, createBarTestContainerNode());
+        modificationTree1.ready();
+        modificationTree2.ready();
 
         inMemoryDataTree.validate(modificationTree1);
         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
@@ -399,11 +407,11 @@ public class ConcurrentTreeModificationTest {
             final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
             inMemoryDataTree.commit(prepare2);
         } catch (final ConflictingModificationAppliedException ex) {
-            LOG.debug("ConflictingModificationAppliedException - '{}' was thrown as expected.");
+            LOG.debug("ConflictingModificationAppliedException was thrown as expected", ex);
         }
 
 
-        final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
         assertFalse(snapshotAfterCommits.readNode(TestModel.TEST_PATH).isPresent());
     }
 
@@ -411,16 +419,17 @@ public class ConcurrentTreeModificationTest {
     public void deleteMergeFooBar1stLevelEmptyContainerTest() throws DataValidationFailedException {
         final DataTreeModification initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
         initialDataTreeModification.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
+        initialDataTreeModification.ready();
         inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
-        final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
 
-        final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
-        final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
+        final DataTreeModification modificationTree1 = initialDataTreeSnapshot.newModification();
+        final DataTreeModification modificationTree2 = initialDataTreeSnapshot.newModification();
 
         modificationTree1.delete(TestModel.TEST_PATH);
         modificationTree2.merge(TestModel.TEST_PATH, createBarTestContainerNode());
+        modificationTree1.ready();
+        modificationTree2.ready();
 
         inMemoryDataTree.validate(modificationTree1);
         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
@@ -430,7 +439,7 @@ public class ConcurrentTreeModificationTest {
         final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
         inMemoryDataTree.commit(prepare2);
 
-        final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH), MapEntryNode.class);
     }
 
@@ -438,17 +447,19 @@ public class ConcurrentTreeModificationTest {
     public void writeWriteFooBar2ndLevelEmptyContainerTest() throws DataValidationFailedException {
         final DataTreeModification initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
         initialDataTreeModification.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
-        initialDataTreeModification.write(TestModel.OUTER_LIST_PATH, mapNodeBuilder(TestModel.OUTER_LIST_QNAME).build());
+        initialDataTreeModification.write(TestModel.OUTER_LIST_PATH, mapNodeBuilder(TestModel.OUTER_LIST_QNAME)
+            .build());
+        initialDataTreeModification.ready();
         inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
-        final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
 
-        final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
-        final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
+        final DataTreeModification modificationTree1 = initialDataTreeSnapshot.newModification();
+        final DataTreeModification modificationTree2 = initialDataTreeSnapshot.newModification();
 
         modificationTree1.write(OUTER_LIST_1_PATH, FOO_NODE);
         modificationTree2.write(OUTER_LIST_2_PATH, BAR_NODE);
+        modificationTree1.ready();
+        modificationTree2.ready();
 
         inMemoryDataTree.validate(modificationTree1);
         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
@@ -458,7 +469,7 @@ public class ConcurrentTreeModificationTest {
         final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
         inMemoryDataTree.commit(prepare2);
 
-        final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH), MapEntryNode.class);
     }
@@ -467,17 +478,19 @@ public class ConcurrentTreeModificationTest {
     public void writeMergeFooBar2ndLevelEmptyContainerTest() throws DataValidationFailedException {
         final DataTreeModification initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
         initialDataTreeModification.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
-        initialDataTreeModification.write(TestModel.OUTER_LIST_PATH, mapNodeBuilder(TestModel.OUTER_LIST_QNAME).build());
+        initialDataTreeModification.write(TestModel.OUTER_LIST_PATH, mapNodeBuilder(TestModel.OUTER_LIST_QNAME)
+            .build());
+        initialDataTreeModification.ready();
         inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
-        final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
 
-        final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
-        final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
+        final DataTreeModification modificationTree1 = initialDataTreeSnapshot.newModification();
+        final DataTreeModification modificationTree2 = initialDataTreeSnapshot.newModification();
 
         modificationTree1.write(OUTER_LIST_1_PATH, FOO_NODE);
         modificationTree2.merge(OUTER_LIST_2_PATH, BAR_NODE);
+        modificationTree1.ready();
+        modificationTree2.ready();
 
         inMemoryDataTree.validate(modificationTree1);
         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
@@ -487,7 +500,7 @@ public class ConcurrentTreeModificationTest {
         final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
         inMemoryDataTree.commit(prepare2);
 
-        final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH), MapEntryNode.class);
     }
@@ -496,17 +509,19 @@ public class ConcurrentTreeModificationTest {
     public void mergeWriteFooBar2ndLevelEmptyContainerTest() throws DataValidationFailedException {
         final DataTreeModification initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
         initialDataTreeModification.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
-        initialDataTreeModification.write(TestModel.OUTER_LIST_PATH, mapNodeBuilder(TestModel.OUTER_LIST_QNAME).build());
+        initialDataTreeModification.write(TestModel.OUTER_LIST_PATH, mapNodeBuilder(TestModel.OUTER_LIST_QNAME)
+            .build());
+        initialDataTreeModification.ready();
         inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
-        final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
 
-        final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
-        final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
+        final DataTreeModification modificationTree1 = initialDataTreeSnapshot.newModification();
+        final DataTreeModification modificationTree2 = initialDataTreeSnapshot.newModification();
 
         modificationTree1.merge(OUTER_LIST_1_PATH, FOO_NODE);
         modificationTree2.write(OUTER_LIST_2_PATH, BAR_NODE);
+        modificationTree1.ready();
+        modificationTree2.ready();
 
         inMemoryDataTree.validate(modificationTree1);
         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
@@ -516,7 +531,7 @@ public class ConcurrentTreeModificationTest {
         final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
         inMemoryDataTree.commit(prepare2);
 
-        final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH), MapEntryNode.class);
     }
@@ -525,17 +540,19 @@ public class ConcurrentTreeModificationTest {
     public void mergeMergeFooBar2ndLevelEmptyContainerTest() throws DataValidationFailedException {
         final DataTreeModification initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
         initialDataTreeModification.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
-        initialDataTreeModification.write(TestModel.OUTER_LIST_PATH, mapNodeBuilder(TestModel.OUTER_LIST_QNAME).build());
+        initialDataTreeModification.write(TestModel.OUTER_LIST_PATH, mapNodeBuilder(TestModel.OUTER_LIST_QNAME)
+            .build());
+        initialDataTreeModification.ready();
         inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
-        final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
 
-        final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
-        final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
+        final DataTreeModification modificationTree1 = initialDataTreeSnapshot.newModification();
+        final DataTreeModification modificationTree2 = initialDataTreeSnapshot.newModification();
 
         modificationTree1.merge(OUTER_LIST_1_PATH, FOO_NODE);
         modificationTree2.merge(OUTER_LIST_2_PATH, BAR_NODE);
+        modificationTree1.ready();
+        modificationTree2.ready();
 
         inMemoryDataTree.validate(modificationTree1);
         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
@@ -545,7 +562,7 @@ public class ConcurrentTreeModificationTest {
         final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
         inMemoryDataTree.commit(prepare2);
 
-        final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH), MapEntryNode.class);
     }
@@ -554,17 +571,19 @@ public class ConcurrentTreeModificationTest {
     public void deleteWriteFooBar2ndLevelEmptyContainerTest() throws DataValidationFailedException {
         final DataTreeModification initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
         initialDataTreeModification.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
-        initialDataTreeModification.write(TestModel.OUTER_LIST_PATH, mapNodeBuilder(TestModel.OUTER_LIST_QNAME).build());
+        initialDataTreeModification.write(TestModel.OUTER_LIST_PATH, mapNodeBuilder(TestModel.OUTER_LIST_QNAME)
+            .build());
+        initialDataTreeModification.ready();
         inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
-        final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
 
-        final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
-        final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
+        final DataTreeModification modificationTree1 = initialDataTreeSnapshot.newModification();
+        final DataTreeModification modificationTree2 = initialDataTreeSnapshot.newModification();
 
         modificationTree1.delete(TestModel.TEST_PATH);
-        modificationTree2.merge(OUTER_LIST_2_PATH, BAR_NODE);
+        modificationTree2.write(OUTER_LIST_2_PATH, BAR_NODE);
+        modificationTree1.ready();
+        modificationTree2.ready();
 
         inMemoryDataTree.validate(modificationTree1);
         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
@@ -575,11 +594,11 @@ public class ConcurrentTreeModificationTest {
             final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
             inMemoryDataTree.commit(prepare2);
             fail("Exception should have been thrown");
-        } catch (final Exception e) {
-            LOG.debug("Exception was thrown because path no longer exist in tree");
+        } catch (final ConflictingModificationAppliedException e) {
+            LOG.debug("Exception was thrown because path no longer exist in tree", e);
         }
 
-        final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
         assertFalse(snapshotAfterCommits.readNode(TestModel.TEST_PATH).isPresent());
     }
 
@@ -587,17 +606,19 @@ public class ConcurrentTreeModificationTest {
     public void deleteMergeFooBar2ndLevelEmptyContainerTest() throws DataValidationFailedException {
         final DataTreeModification initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
         initialDataTreeModification.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
-        initialDataTreeModification.write(TestModel.OUTER_LIST_PATH, mapNodeBuilder(TestModel.OUTER_LIST_QNAME).build());
+        initialDataTreeModification.write(TestModel.OUTER_LIST_PATH, mapNodeBuilder(TestModel.OUTER_LIST_QNAME)
+            .build());
+        initialDataTreeModification.ready();
         inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
-        final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
 
-        final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
-        final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
-                rootOper);
+        final DataTreeModification modificationTree1 = initialDataTreeSnapshot.newModification();
+        final DataTreeModification modificationTree2 = initialDataTreeSnapshot.newModification();
 
         modificationTree1.delete(TestModel.TEST_PATH);
         modificationTree2.merge(OUTER_LIST_2_PATH, BAR_NODE);
+        modificationTree1.ready();
+        modificationTree2.ready();
 
         inMemoryDataTree.validate(modificationTree1);
         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
@@ -608,11 +629,11 @@ public class ConcurrentTreeModificationTest {
             final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
             inMemoryDataTree.commit(prepare2);
             fail("Exception should have been thrown");
-        } catch (final Exception e) {
-            LOG.debug("Exception was thrown because path no longer exist in tree");
+        } catch (final ConflictingModificationAppliedException e) {
+            LOG.debug("Exception was thrown because path no longer exist in tree", e);
         }
 
-        final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
+        final DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
         assertFalse(snapshotAfterCommits.readNode(TestModel.TEST_PATH).isPresent());
     }
 }