private Map<CacheCategory, CacheService> createCaches(CacheInfo cacheInfo) {
   Map<CacheCategory, CacheService> ciCaches = new HashMap<CacheCategory, CacheService>();
   for (Map.Entry<CacheCategory, CacheConfiguration> entry :
       cacheInfo.getConfiguration().entrySet()) {
     if (entry.getValue() instanceof InfinispanConfiguration) {
       CacheService cacheService;
       CacheCategory category = entry.getKey();
       InfinispanConfiguration config = (InfinispanConfiguration) entry.getValue();
       if (config.isCacheEnabled()) {
         String configurationName = config.getConfigurationName();
         if (null == configurationName) {
           Configuration dcc = manager.getDefaultCacheConfiguration();
           Configuration infinispan =
               config.getInfinispanConfiguration(new ConfigurationBuilder().read(dcc));
           configurationName = "$" + category.getName() + "$" + cacheInfo.getId();
           manager.defineConfiguration(configurationName, infinispan);
         }
         recorder.record("infinispan", "configuration name " + configurationName);
         cacheService =
             new InfinispanCacheService(manager.<String, Object>getCache(configurationName));
       } else {
         cacheService = noCacheFactory.create(null, category);
       }
       ciCaches.put(category, cacheService);
     }
   }
   return ciCaches;
 }
 public void invalidateLayer(Layer layer) throws GeomajasException {
   String layerId = "--null-layer--";
   if (null != layer) {
     layerId = layer.getId();
   }
   recorder.record(layerId, "Layer invalidated");
   cacheManager.drop(layer);
 }
 @Override
 public void afterSteps(PipelineContext context, GetFeaturesContainer response)
     throws GeomajasException {
   // do not cache features which are converted lazily, this would put detached objects in cache
   if (isCacheable(context)) {
     recorder.record(CacheCategory.FEATURE, "Put item in cache");
     putContainer(
         context,
         CacheCategory.FEATURE,
         KEYS,
         CacheStepConstant.CACHE_FEATURES_KEY,
         CacheStepConstant.CACHE_FEATURES_CONTEXT,
         new FeaturesCacheContainer(response.getFeatures(), response.getBounds()),
         response.getBounds());
   }
 }
 @Override
 public ExecutionMode beforeSteps(PipelineContext context, GetFeaturesContainer response)
     throws GeomajasException {
   // do not cache features which are converted lazily, this would put detached objects in cache
   if (isCacheable(context)) {
     FeaturesCacheContainer cc =
         getContainer(
             CacheStepConstant.CACHE_FEATURES_KEY,
             CacheStepConstant.CACHE_FEATURES_CONTEXT,
             KEYS,
             CacheCategory.FEATURE,
             context,
             FeaturesCacheContainer.class);
     if (cc != null) {
       recorder.record(CacheCategory.FEATURE, "Got item from cache");
       response.setBounds(cc.getBounds());
       response.setFeatures(cc.getFeatures());
       return ExecutionMode.EXECUTE_NONE;
     }
   }
   return ExecutionMode.EXECUTE_ALL;
 }