/**
   * Create a cache given a cache configuration
   *
   * @param cacheConfiguration
   */
  final Ehcache createCache(CacheConfiguration cacheConfiguration) {
    boolean terracottaClustered = false;
    String terracottaValueMode = null;
    boolean terracottaCoherentReads = true;
    TerracottaConfiguration tcConfiguration = cacheConfiguration.getTerracottaConfiguration();
    if (tcConfiguration != null) {
      terracottaClustered = tcConfiguration.isClustered();
      terracottaValueMode = tcConfiguration.getValueMode().name();
      terracottaCoherentReads = tcConfiguration.getCoherentReads();
    }

    Ehcache cache =
        new Cache(
            cacheConfiguration.name,
            cacheConfiguration.maxElementsInMemory,
            cacheConfiguration.memoryStoreEvictionPolicy,
            cacheConfiguration.overflowToDisk,
            getDiskStorePath(),
            cacheConfiguration.eternal,
            cacheConfiguration.timeToLiveSeconds,
            cacheConfiguration.timeToIdleSeconds,
            cacheConfiguration.diskPersistent,
            cacheConfiguration.diskExpiryThreadIntervalSeconds,
            null,
            null,
            cacheConfiguration.maxElementsOnDisk,
            cacheConfiguration.diskSpoolBufferSizeMB,
            cacheConfiguration.clearOnFlush,
            terracottaClustered,
            terracottaValueMode,
            terracottaCoherentReads);
    RegisteredEventListeners listeners = cache.getCacheEventNotificationService();
    registerCacheListeners(cacheConfiguration, listeners);
    registerCacheExtensions(cacheConfiguration, cache);
    BootstrapCacheLoader bootstrapCacheLoader =
        createBootstrapCacheLoader(
            cacheConfiguration.getBootstrapCacheLoaderFactoryConfiguration());
    cache.setBootstrapCacheLoader(bootstrapCacheLoader);
    registerCacheLoaders(cacheConfiguration, cache);
    cache = applyCacheExceptionHandler(cacheConfiguration, cache);
    return cache;
  }
 private void init() {
   if (tcConfiguration == null) {
     return;
   }
   if (!TerracottaConfiguration.DEFAULT_NON_STOP_CONFIGURATION.equals(
       tcConfiguration.getNonstopConfiguration())) {
     this.addChildElement(
         new NonstopConfigurationElement(this, tcConfiguration.getNonstopConfiguration()));
   }
   addAttribute(
       new SimpleNodeAttribute("clustered", tcConfiguration.isClustered())
           .optional(true)
           .defaultValue(TerracottaConfiguration.DEFAULT_CLUSTERED));
   addAttribute(
       new SimpleNodeAttribute("valueMode", tcConfiguration.getValueMode())
           .optional(true)
           .defaultValue(TerracottaConfiguration.DEFAULT_VALUE_MODE));
   addAttribute(
       new SimpleNodeAttribute("consistency", tcConfiguration.getConsistency().name())
           .optional(true)
           .defaultValue(TerracottaConfiguration.DEFAULT_CONSISTENCY_TYPE.name()));
   addAttribute(
       new SimpleNodeAttribute("synchronousWrites", tcConfiguration.isSynchronousWrites())
           .optional(true)
           .defaultValue(TerracottaConfiguration.DEFAULT_SYNCHRONOUS_WRITES));
   addAttribute(
       new SimpleNodeAttribute("copyOnRead", tcConfiguration.isCopyOnRead())
           .optional(true)
           .defaultValue(TerracottaConfiguration.DEFAULT_COPY_ON_READ));
   addAttribute(
       new SimpleNodeAttribute("localKeyCache", tcConfiguration.getLocalKeyCache())
           .optional(true)
           .defaultValue(TerracottaConfiguration.DEFAULT_LOCAL_KEY_CACHE));
   addAttribute(
       new SimpleNodeAttribute("localKeyCacheSize", tcConfiguration.getLocalKeyCacheSize())
           .optional(true)
           .defaultValue(TerracottaConfiguration.DEFAULT_LOCAL_KEY_CACHE_SIZE));
   addAttribute(
       new SimpleNodeAttribute("orphanEviction", tcConfiguration.getOrphanEviction())
           .optional(true)
           .defaultValue(TerracottaConfiguration.DEFAULT_ORPHAN_EVICTION));
   addAttribute(
       new SimpleNodeAttribute("orphanEvictionPeriod", tcConfiguration.getOrphanEvictionPeriod())
           .optional(true)
           .defaultValue(TerracottaConfiguration.DEFAULT_ORPHAN_EVICTION_PERIOD));
   addAttribute(
       new SimpleNodeAttribute("coherentReads", tcConfiguration.getCoherentReads())
           .optional(true)
           .defaultValue(TerracottaConfiguration.DEFAULT_COHERENT_READS));
   addAttribute(
       new SimpleNodeAttribute("concurrency", tcConfiguration.getConcurrency())
           .optional(true)
           .defaultValue(TerracottaConfiguration.DEFAULT_CONCURRENCY));
   addAttribute(
       new SimpleNodeAttribute("localCacheEnabled", tcConfiguration.isLocalCacheEnabled())
           .optional(true)
           .defaultValue(TerracottaConfiguration.DEFAULT_LOCAL_CACHE_ENABLED));
   addAttribute(
       new SimpleNodeAttribute("compressionEnabled", tcConfiguration.isCompressionEnabled())
           .optional(true)
           .defaultValue(TerracottaConfiguration.DEFAULT_COMPRESSION_ENABLED));
 }