class SelfPopulatingCache extends BlockingCache {

    public void refresh() throws CacheException {
        Exception exception = null;
        Object keyWithException = null;

        // Refetch the entries
        final Collection keys = getKeys();

        if (LOG.isTraceEnabled()) {
            LOG.trace(getName() + ": found " + keys.size() + " keys to refresh");
        }

        // perform the refresh
        for (Iterator iterator = keys.iterator(); iterator.hasNext();) {
            final Object key = iterator.next();

            try {
                Ehcache backingCache = getCache();
                final Element element = backingCache.getQuiet(key);

                if (element == null) {
                    if (LOG.isTraceEnabled()) {
                        LOG.trace(getName() + ": entry with key " + key + " has been removed - skipping it");
                    }

                    continue;
                }

                refreshElement(element, backingCache);
            } catch (final Exception e) {
                // Collect the exception and keep going.
                // Throw the exception once all the entries have been refreshed
                // If the refresh fails, keep the old element. It will simply become staler.
                LOG.warn(getName() + "Could not refresh element " + key, e);
                exception = e;
            }
        }

        if (exception != null) {
            throw new CacheException(exception.getMessage() + " on refresh with key " + keyWithException);
        }
    }

    public  SelfPopulatingCache(final Ehcache cache, final CacheEntryFactory factory);

}