public static <K extends Serializable, V extends Serializable> Set<K> removeValueFromCache( Cache<K, V> cache, V element )
    {
        // In some cache implementations, the entry-set is unmodifiable. To guard against potential
        // future changes of this implementation (that would make the implementation incompatible with
        // these cache implementations), the entry-set that's operated on in this implementation is
        // explicitly wrapped in an unmodifiable collection. That forces this implementation to be
        // compatible with the 'lowest common denominator'.
        final Set<Map.Entry<K, V>> entries = Collections.unmodifiableSet( cache.entrySet() );

        // contains all entries that were somehow changed.
        final Set<K> result = new HashSet<>();

        for ( final Map.Entry<K, V> entry : entries )
        {
            final K key = entry.getKey();

            final Lock lock = cache.getLock( key );
            lock.lock();
            try
            {
                if ( entry.getValue().equals( element ) )
                {
                    cache.remove( entry.getKey() );
                    result.add( entry.getKey() );
                }
            }
            finally
            {
                lock.unlock();
            }
        }
        return result;
    }
Removes all entries of a cache that map to the provided value.

The implementation of this method is designed to be compatible with both clustered as well as non-clustered caches.

@param cache   The cache from which to remove the element (cannot be null).
@param element The element to be removed (can not be null ).
@param <K> the type of key contained by the cache
@param <V> the type of value contained by the cache
@return a Set containing the keys of all affected cache entries (never null)
xmppserver/src/main/java/org/jivesoftware/util/cache/CacheUtil.java