class CandidateListChangeListener implements DOMDataTreeChangeListener {

    @Override
    public void onDataTreeChanged(final Collection<DataTreeCandidate> changes) {
        for (DataTreeCandidate change: changes) {
            DataTreeCandidateNode changeRoot = change.getRootNode();
            ModificationType type = changeRoot.getModificationType();

            LOG.debug("{}: Candidate node changed: {}, {}", logId, type, change.getRootPath());

            NodeIdentifierWithPredicates candidateKey =
                    (NodeIdentifierWithPredicates) change.getRootPath().getLastPathArgument();
            String candidate = candidateKey.getValue(CANDIDATE_NAME_QNAME).toString();

            YangInstanceIdentifier entityId = extractEntityPath(change.getRootPath());

            if (type == ModificationType.WRITE || type == ModificationType.APPEARED) {
                LOG.debug("{}: Candidate {} was added for entity {}", logId, candidate, entityId);

                Collection<String> newCandidates = addToCurrentCandidates(entityId, candidate);
                shard.tell(new CandidateAdded(entityId, candidate, new ArrayList<>(newCandidates)), shard);
            } else if (type == ModificationType.DELETE || type == ModificationType.DISAPPEARED) {
                LOG.debug("{}: Candidate {} was removed for entity {}", logId, candidate, entityId);

                Collection<String> newCandidates = removeFromCurrentCandidates(entityId, candidate);
                shard.tell(new CandidateRemoved(entityId, candidate, new ArrayList<>(newCandidates)), shard);
            }
        }
    }

      CandidateListChangeListener(final ActorRef shard, final String logId);

}