@Override
    public void entryUpdated(@Nonnull final K key, @Nullable final V oldValue, @Nullable final V newValue, @Nonnull final NodeID nodeID) {
        final Set<NodeID> nodesToAdd = ownageDeducer.apply(newValue);

        // Remove all entries for the key.
        final Iterator<Map.Entry<NodeID, Set<K>>> iter = reverseCacheRepresentation.entrySet().iterator();
        while (iter.hasNext()) {
            final Map.Entry<NodeID, Set<K>> existingEntry = iter.next();
            final NodeID existingEntryNodeID = existingEntry.getKey();
            if (!nodesToAdd.contains(existingEntryNodeID)) {
                existingEntry.getValue().remove(key);
                if (existingEntry.getValue().isEmpty()) {
                    iter.remove();
                }
            }
        }

        // Add entries for only the latest state of the value.
        add(key, nodesToAdd);
    }
Cache entry listener implementation that maintains a reverse lookup map for the cache that is being observed, which
is used to identify what cluster nodes are the logical owner of a particular cache entry. This information is typically
useful in scenarios where a cluster node drops out of the cluster requiring the remaining nodes to have to inform
their connected entities of what resources have become unavailable.

This implementation uses a function (to be provided in the constructor) to calculate what cluster nodes 'own' a
corresponding entry. The function operates on the value of the cache. It is therefor required that listeners of this
type are registered using a configuration that includes entry values to be included in the event invocation. Null
values are not supported.
xmppserver/src/main/java/org/jivesoftware/util/cache/ReverseLookupComputingCacheEntryListener.java