@Test
  public void writeContainerEmptyTreeTest() throws InterruptedException {
    CountDownLatch latch = new CountDownLatch(1);

    DOMDataTreeChangeService dataTreeChangeService = getDOMDataTreeChangeService();
    assertNotNull(
        "DOMDataTreeChangeService not found, cannot continue with test!", dataTreeChangeService);

    final TestDataTreeListener listener = new TestDataTreeListener(latch);
    final ListenerRegistration<TestDataTreeListener> listenerReg =
        dataTreeChangeService.registerDataTreeChangeListener(ROOT_DATA_TREE_ID, listener);

    final DOMDataTreeWriteTransaction writeTx = domBroker.newWriteOnlyTransaction();
    writeTx.put(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH, TEST_CONTAINER);
    writeTx.submit();

    latch.await(5, TimeUnit.SECONDS);

    assertEquals(1, listener.getReceivedChanges().size());
    final Collection<DataTreeCandidate> changes = listener.getReceivedChanges().get(0);
    assertEquals(1, changes.size());

    DataTreeCandidate candidate = changes.iterator().next();
    assertNotNull(candidate);
    DataTreeCandidateNode candidateRoot = candidate.getRootNode();
    checkChange(null, TEST_CONTAINER, ModificationType.WRITE, candidateRoot);
    listenerReg.close();
  }
  @Test
  public void replaceChildListContainerInTreeTest()
      throws InterruptedException, TransactionCommitFailedException {
    CountDownLatch latch = new CountDownLatch(2);

    DOMDataTreeChangeService dataTreeChangeService = getDOMDataTreeChangeService();
    assertNotNull(
        "DOMDataTreeChangeService not found, cannot continue with test!", dataTreeChangeService);

    DOMDataTreeWriteTransaction writeTx = domBroker.newWriteOnlyTransaction();
    writeTx.put(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH, TEST_CONTAINER);
    writeTx.submit().checkedGet();

    final TestDataTreeListener listener = new TestDataTreeListener(latch);
    final ListenerRegistration<TestDataTreeListener> listenerReg =
        dataTreeChangeService.registerDataTreeChangeListener(ROOT_DATA_TREE_ID, listener);

    writeTx = domBroker.newWriteOnlyTransaction();
    writeTx.put(LogicalDatastoreType.CONFIGURATION, TestModel.OUTER_LIST_PATH, OUTER_LIST_2);
    writeTx.submit();

    latch.await(5, TimeUnit.SECONDS);

    assertEquals(2, listener.getReceivedChanges().size());
    Collection<DataTreeCandidate> changes = listener.getReceivedChanges().get(0);
    assertEquals(1, changes.size());

    DataTreeCandidate candidate = changes.iterator().next();
    assertNotNull(candidate);
    DataTreeCandidateNode candidateRoot = candidate.getRootNode();
    checkChange(null, TEST_CONTAINER, ModificationType.WRITE, candidateRoot);

    changes = listener.getReceivedChanges().get(1);
    assertEquals(1, changes.size());

    candidate = changes.iterator().next();
    assertNotNull(candidate);
    candidateRoot = candidate.getRootNode();
    checkChange(TEST_CONTAINER, TEST_CONTAINER_2, ModificationType.SUBTREE_MODIFIED, candidateRoot);
    final DataTreeCandidateNode modifiedChild =
        candidateRoot.getModifiedChild(
            new YangInstanceIdentifier.NodeIdentifier(TestModel.OUTER_LIST_QNAME));
    assertNotNull(modifiedChild);
    checkChange(OUTER_LIST, OUTER_LIST_2, ModificationType.WRITE, modifiedChild);
    listenerReg.close();
  }
  @Test
  public void listEntryChangeNonRootRegistrationTest()
      throws InterruptedException, TransactionCommitFailedException {
    CountDownLatch latch = new CountDownLatch(2);

    DOMDataTreeChangeService dataTreeChangeService = getDOMDataTreeChangeService();
    assertNotNull(
        "DOMDataTreeChangeService not found, cannot continue with test!", dataTreeChangeService);

    DOMDataTreeWriteTransaction writeTx = domBroker.newWriteOnlyTransaction();
    writeTx.put(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH, TEST_CONTAINER);
    writeTx.submit().checkedGet();

    final TestDataTreeListener listener = new TestDataTreeListener(latch);
    final ListenerRegistration<TestDataTreeListener> listenerReg =
        dataTreeChangeService.registerDataTreeChangeListener(OUTER_LIST_DATA_TREE_ID, listener);

    final YangInstanceIdentifier.NodeIdentifierWithPredicates outerListEntryId1 =
        new YangInstanceIdentifier.NodeIdentifierWithPredicates(
            TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 1);
    final YangInstanceIdentifier.NodeIdentifierWithPredicates outerListEntryId2 =
        new YangInstanceIdentifier.NodeIdentifierWithPredicates(
            TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 2);
    final YangInstanceIdentifier.NodeIdentifierWithPredicates outerListEntryId3 =
        new YangInstanceIdentifier.NodeIdentifierWithPredicates(
            TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 3);

    final MapEntryNode outerListEntry1 =
        ImmutableNodes.mapEntry(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 1);
    final MapEntryNode outerListEntry2 =
        ImmutableNodes.mapEntry(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 2);
    final MapEntryNode outerListEntry3 =
        ImmutableNodes.mapEntry(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 3);

    final MapNode listAfter =
        ImmutableNodes.mapNodeBuilder(TestModel.OUTER_LIST_QNAME)
            .withChild(outerListEntry2)
            .withChild(outerListEntry3)
            .build();

    writeTx = domBroker.newWriteOnlyTransaction();
    writeTx.delete(
        LogicalDatastoreType.CONFIGURATION, TestModel.OUTER_LIST_PATH.node(outerListEntryId1));
    writeTx.put(
        LogicalDatastoreType.CONFIGURATION,
        TestModel.OUTER_LIST_PATH.node(outerListEntryId2),
        outerListEntry2);
    writeTx.put(
        LogicalDatastoreType.CONFIGURATION,
        TestModel.OUTER_LIST_PATH.node(outerListEntryId3),
        outerListEntry3);
    writeTx.submit();

    latch.await(5, TimeUnit.SECONDS);

    assertEquals(2, listener.getReceivedChanges().size());
    Collection<DataTreeCandidate> changes = listener.getReceivedChanges().get(0);
    assertEquals(1, changes.size());

    DataTreeCandidate candidate = changes.iterator().next();
    assertNotNull(candidate);
    DataTreeCandidateNode candidateRoot = candidate.getRootNode();
    checkChange(null, OUTER_LIST, ModificationType.WRITE, candidateRoot);

    changes = listener.getReceivedChanges().get(1);
    assertEquals(1, changes.size());

    candidate = changes.iterator().next();
    assertNotNull(candidate);
    candidateRoot = candidate.getRootNode();
    checkChange(OUTER_LIST, listAfter, ModificationType.SUBTREE_MODIFIED, candidateRoot);
    final DataTreeCandidateNode entry1Canditate = candidateRoot.getModifiedChild(outerListEntryId1);
    checkChange(outerListEntry1, null, ModificationType.DELETE, entry1Canditate);
    final DataTreeCandidateNode entry2Canditate = candidateRoot.getModifiedChild(outerListEntryId2);
    checkChange(null, outerListEntry2, ModificationType.WRITE, entry2Canditate);
    final DataTreeCandidateNode entry3Canditate = candidateRoot.getModifiedChild(outerListEntryId3);
    checkChange(null, outerListEntry3, ModificationType.WRITE, entry3Canditate);
    listenerReg.close();
  }