private void add(K key, Set<NodeID> newNodesWithThisKey)
    {
        // Step 1 : update existing entries to the updated situation
        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 (newNodesWithThisKey.contains(existingEntryNodeID)) {
                existingEntry.getValue().add(key);
            }
        }
        // Step 2 : add entries for node ids that were not in the reverse lookup before
        for (final NodeID nodeIdForWhichTheValueExists : newNodesWithThisKey) {
            if (!reverseCacheRepresentation.containsKey(nodeIdForWhichTheValueExists)) {
                reverseCacheRepresentation.computeIfAbsent(nodeIdForWhichTheValueExists, k -> new HashSet<>()).add(key);
            }
        }
    }
@Test
    public void testAdd() throws Exception
    {
        // Setup text fixture, Simulating things for a cache with this signature: Cache<String, Set<NodeID>> cache;
        final Map<NodeID, Set<String>> reverseLookupMap = new HashMap<>();
        final Function<Set<NodeID>, Set<NodeID>> deducer = nodeIDS -> nodeIDS;
        final ReverseLookupComputingCacheEntryListener<String, Set<NodeID>> listener = new ReverseLookupComputingCacheEntryListener<>(reverseLookupMap, deducer);
        final NodeID clusterNode = NodeID.getInstance(UUID.randomUUID().toString().getBytes());

        // Execute system under test.
        listener.entryAdded("somekey", Collections.singleton(clusterNode), clusterNode);

        // Assert result
        assertTrue(reverseLookupMap.containsKey(clusterNode));
        assertTrue(reverseLookupMap.get(clusterNode).contains("somekey"));
    }