private void registerClusterListenerCallablesToInstall(
     Set<Object> enlistedAlready,
     Set<DistributedCallable> callables,
     List<CacheEntryListenerInvocation<K, V>> listenerInvocations) {
   for (CacheEntryListenerInvocation<K, V> listener : listenerInvocations) {
     if (!enlistedAlready.contains(listener.getTarget())) {
       // If clustered means it is local - so use our address
       if (listener.isClustered()) {
         callables.add(
             new ClusterListenerReplicateCallable(
                 listener.getIdentifier(),
                 cache.getCacheManager().getAddress(),
                 listener.getFilter(),
                 listener.getConverter(),
                 listener.isSync()));
         enlistedAlready.add(listener.getTarget());
       } else if (listener.getTarget() instanceof RemoteClusterListener) {
         RemoteClusterListener lcl = (RemoteClusterListener) listener.getTarget();
         callables.add(
             new ClusterListenerReplicateCallable(
                 lcl.getId(),
                 lcl.getOwnerAddress(),
                 listener.getFilter(),
                 listener.getConverter(),
                 listener.isSync()));
         enlistedAlready.add(listener.getTarget());
       }
     }
   }
 }
  private void raiseEventForInitialTransfer(UUID identifier, CacheEntry entry, boolean clustered) {
    EventImpl preEvent;
    if (clustered) {
      // In clustered mode we only send post event
      preEvent = null;
    } else {
      preEvent = EventImpl.createEvent(cache, CACHE_ENTRY_CREATED);
      preEvent.setKey(entry.getKey());
      preEvent.setPre(true);
    }

    EventImpl postEvent = EventImpl.createEvent(cache, CACHE_ENTRY_CREATED);
    postEvent.setKey(entry.getKey());
    postEvent.setValue(entry.getValue());
    postEvent.setMetadata(entry.getMetadata());
    postEvent.setPre(false);

    for (CacheEntryListenerInvocation<K, V> invocation : cacheEntryCreatedListeners) {
      // Now notify all our methods of the creates
      if (invocation.getIdentifier() == identifier) {
        if (preEvent != null) {
          // Non clustered notifications are done twice
          invocation.invokeNoChecks(preEvent, true, true);
        }
        invocation.invokeNoChecks(postEvent, true, true);
      }
    }
  }
 @Override
 public void notifyClusterListeners(
     Collection<? extends CacheEntryEvent<K, V>> events, UUID uuid) {
   for (CacheEntryEvent<K, V> event : events) {
     if (event.isPre()) {
       throw new IllegalArgumentException(
           "Events for cluster listener should never be pre change");
     }
     switch (event.getType()) {
       case CACHE_ENTRY_MODIFIED:
         for (CacheEntryListenerInvocation<K, V> listener : cacheEntryModifiedListeners) {
           if (listener.isClustered() && uuid.equals(listener.getIdentifier())) {
             // We force invocation, since it means the owning node passed filters already and they
             // already converted so don't run converter either
             listener.invokeNoChecks(event, false, true);
           }
         }
         break;
       case CACHE_ENTRY_CREATED:
         for (CacheEntryListenerInvocation<K, V> listener : cacheEntryCreatedListeners) {
           if (listener.isClustered() && uuid.equals(listener.getIdentifier())) {
             // We force invocation, since it means the owning node passed filters already and they
             // already converted so don't run converter either
             listener.invokeNoChecks(event, false, true);
           }
         }
         break;
       case CACHE_ENTRY_REMOVED:
         for (CacheEntryListenerInvocation<K, V> listener : cacheEntryRemovedListeners) {
           if (listener.isClustered() && uuid.equals(listener.getIdentifier())) {
             // We force invocation, since it means the owning node passed filters already and they
             // already converted so don't run converter either
             listener.invokeNoChecks(event, false, true);
           }
         }
         break;
       default:
         throw new IllegalArgumentException("Unexpected event type encountered!");
     }
   }
 }