@Override
  protected void doInitializeChanged() {
    assignedLabels = new HashMap<>();
    removedLabels = new HashMap<>();
    deletedNodeLabels = new HashMap<>();

    Map<Long, Node> potentiallyChangedNodes = new HashMap<>();

    for (LabelEntry labelEntry : transactionData.assignedLabels()) {
      Node node = labelEntry.node();

      if (hasBeenCreated(node)) {
        continue;
      }

      if (!assignedLabels.containsKey(node.getId())) {
        assignedLabels.put(node.getId(), new HashSet<Label>());
      }

      assignedLabels.get(node.getId()).add(labelEntry.label());

      potentiallyChangedNodes.put(node.getId(), node);
    }

    for (LabelEntry labelEntry : transactionData.removedLabels()) {
      Node node = labelEntry.node();

      if (hasBeenDeleted(node)) {
        if (!deletedNodeLabels.containsKey(node.getId())) {
          deletedNodeLabels.put(node.getId(), new HashSet<Label>());
        }
        deletedNodeLabels.get(node.getId()).add(labelEntry.label());
        continue;
      }

      if (!removedLabels.containsKey(node.getId())) {
        removedLabels.put(node.getId(), new HashSet<Label>());
      }
      removedLabels.get(node.getId()).add(labelEntry.label());

      potentiallyChangedNodes.put(node.getId(), node);
    }

    for (Long nodeId : assignedLabels.keySet()) {
      registerChange(potentiallyChangedNodes.get(nodeId));
    }

    for (Long nodeId : removedLabels.keySet()) {
      registerChange(potentiallyChangedNodes.get(nodeId));
    }
  }
 private void check(
     Map<Node, Set<String>> expected, String change, Iterable<LabelEntry> changes) {
   for (LabelEntry entry : changes) {
     Set<String> labels = expected.get(entry.node());
     String message =
         String.format("':%s' should not be %s %s", entry.label().name(), change, entry.node());
     assertNotNull(message, labels);
     assertTrue(message, labels.remove(entry.label().name()));
     if (labels.isEmpty()) {
       expected.remove(entry.node());
     }
   }
   assertTrue(
       String.format("Expected more labels %s nodes: %s", change, expected), expected.isEmpty());
 }
  @Test
  public void shouldListRemovedLabels() throws Exception {
    // Given
    state.nodeDoRemoveLabel(2, 1l);
    when(ops.labelGetName(2)).thenReturn("theLabel");

    // When
    Iterable<LabelEntry> labelEntries = snapshot().removedLabels();

    // Then
    LabelEntry entry = single(labelEntries);
    assertThat(entry.label().name(), equalTo("theLabel"));
    assertThat(entry.node().getId(), equalTo(1l));
  }
  @Test
  public void shouldListAddedLabels() throws Exception {
    // Given
    state.nodeDoAddLabel(2, 1l);
    when(ops.labelGetName(2)).thenReturn("theLabel");
    when(ops.nodeGetLabels(1l)).thenReturn(PrimitiveIntCollections.emptyIterator());

    // When
    Iterable<LabelEntry> labelEntries = snapshot().assignedLabels();

    // Then
    LabelEntry entry = single(labelEntries);
    assertThat(entry.label().name(), equalTo("theLabel"));
    assertThat(entry.node().getId(), equalTo(1l));
  }