/**
  * @param underlying The provider to wrap
  * @param manager The cache manager
  */
 public EHCachingSecurityMasterDetailProvider(
     SecurityMasterDetailProvider underlying, CacheManager manager) {
   super();
   _underlying = underlying;
   _manager = manager;
   EHCacheUtils.addCache(_manager, SECURITY_CACHE);
   _detailsCache = EHCacheUtils.getCacheFromManager(_manager, SECURITY_CACHE);
 }
  /**
   * Creates an instance over an underlying source specifying the cache manager.
   *
   * @param underlying the underlying security source, not null
   * @param cacheManager the cache manager, not null
   */
  public AbstractEHCachingSourceWithExternalBundle(
      final S underlying, final CacheManager cacheManager) {
    super(underlying, cacheManager);
    EHCacheUtils.addCache(cacheManager, this.getClass().getName() + EID_TO_UID_CACHE);
    _eidToUidCache =
        EHCacheUtils.getCacheFromManager(
            cacheManager, this.getClass().getName() + EID_TO_UID_CACHE);

    // this is crude but it allows caching of lookups that use VersionCorrection.LATEST.
    // VersionCorrection.LATEST can refer to different versions of the same object, but by clearing
    // the caches
    // when anything in the underlying source changes we ensure we never see stale data.
    // this won't work well if the data changes frequently.
    getUnderlying()
        .changeManager()
        .addChangeListener(
            new ChangeListener() {
              @Override
              public void entityChanged(ChangeEvent event) {
                _eidToUidCache.flush();
              }
            });
  }