// Path: core/src/main/java/org/projectodd/wunderboss/Options.java
// public class Options<T> extends HashMap<T, Object> {
// 
//     public Options() {
//         this(null);
//     }
// 
//     public Options(Map<T, Object> options) {
//         if (options != null) {
//             putAll(options);
//         }
//     }
// 
//     /**
//      * Looks up key in the options.
//      *
//      * If key is an Option, its default value will be returned if the key
//      * isn't found.
//      *
//      * @param key
//      * @return
//      */
//     public Object get(Object key) {
//         Object val = super.get(key);
//         if (val == null && key instanceof Option) {
//             val = ((Option)key).defaultValue;
//         }
// 
//         return val;
//     }
// 
//     public Object get(T key, Object defaultValue) {
//         return get(key) != null ? get(key) : defaultValue;
//     }
// 
//     public Boolean getBoolean(T key) {
//         return getBoolean(key, null);
//     }
// 
//     public Boolean getBoolean(T key, Boolean defaultValue) {
//         Object value = get(key);
//         if (value == null) {
//             value = defaultValue;
//         } else if (!(value instanceof Boolean)) {
//             value = Boolean.parseBoolean(value.toString());
//         }
// 
//         return (Boolean)value;
//     }
// 
//     public Integer getInt(T key) {
//         return getInt(key, null);
//     }
// 
//     public Integer getInt(T key, Integer defaultValue) {
//         Object value = get(key);
//         if (value == null) {
//             value = defaultValue;
//         } else if (!(value instanceof Integer)) {
//             value = Integer.parseInt(value.toString());
//         }
// 
//         return (Integer)value;
//     }
// 
//     public Long getLong(T key) {
//         return getLong(key, null);
//     }
// 
//     public Long getLong(T key, Long defaultValue) {
//         Object value = get(key);
//         if (value == null) {
//             value = defaultValue;
//         } else if (!(value instanceof Long)) {
//             value = Long.parseLong(value.toString());
//         }
// 
//         return (Long)value;
//     }
// 
//     public Double getDouble(T key) {
//         return getDouble(key, null);
//     }
// 
//     public Double getDouble(T key, Double defaultValue) {
//         Object value = get(key);
//         if (value == null) {
//             value = defaultValue;
//         } else if (!(value instanceof Double)) {
//             value = Double.parseDouble(value.toString());
//         }
// 
//         return (Double)value;
//     }
// 
//     public String getString(T key) {
//         return getString(key, null);
//     }
// 
//     public String getString(T key, String defaultValue) {
//         return get(key) != null ? get(key).toString() : defaultValue;
//     }
// 
//     public Date getDate(T key) {
//         return getDate(key, null);
//     }
// 
//     public Date getDate(T key, Date defaultValue) {
//         return get(key) != null ? (Date)get(key) : defaultValue;
//     }
// 
//     public List getList(T key) {
//         Object v = get(key);
//         if (v instanceof List || v == null) {
//             return (List) v;
//         }
//         return Arrays.asList(v);
//     }
// 
//     public Options put(T key, Object value) {
//         super.put(key, value);
// 
//         return this;
//     }
// 
//     /**
//      * Returns true if key resolves to a *non-null value* (considering
//      * a possible default), false otherwise.
//      */
//     public boolean has(T key) {
//         return get(key) != null;
//     }
// 
//     public Options<T> merge(Options<T> otherOptions) {
//         Options mergedOptions = new Options();
//         for (T key : this.keySet()) {
//             mergedOptions.put(key, this.get(key));
//         }
//         for (T key : otherOptions.keySet()) {
//             mergedOptions.put(key, otherOptions.get(key));
//         }
//         return mergedOptions;
//     }
// }
// 
// Path: core/src/main/java/org/projectodd/wunderboss/codecs/Codec.java
// public interface Codec<E,D> {
// 
//     E encode(D data);
// 
//     D decode(E encoded);
// 
//     Class<E> encodesTo();
// 
//     String name();
// 
//     String contentType();
// }


import org.infinispan.Cache;
import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.manager.EmbeddedCacheManager;
import org.jboss.logging.Logger;
import org.projectodd.wunderboss.Options;
import org.projectodd.wunderboss.codecs.Codec;
import java.util.Map;
        Cache result = null;
        if (manager().isRunning(name)) {
            result = manager().getCache(name);
            if (!result.getStatus().allowInvocations()) {
                result.start();
            }
        }
        return result;
    }
    
    @Override
    public Cache findOrCreate(String name, Map<CreateOption,Object> options) {
        Cache result = find(name);
        if (result == null) {
            manager().defineConfiguration(name, Config.uration(validate(options)));
            log.info("Creating cache: "+name);
            result = manager().getCache(name);
        }
        return result;
    }

    @Override
    public boolean stop(String name) {
        EmbeddedCacheManager mgr = manager();
        boolean before = mgr.isRunning(name);
        mgr.removeCache(name);
        return before != mgr.isRunning(name);
    }

    @Override
// Path: core/src/main/java/org/projectodd/wunderboss/Options.java
// public class Options<T> extends HashMap<T, Object> {
// 
//     public Options() {
//         this(null);
//     }
// 
//     public Options(Map<T, Object> options) {
//         if (options != null) {
//             putAll(options);
//         }
//     }
// 
//     /**
//      * Looks up key in the options.
//      *
//      * If key is an Option, its default value will be returned if the key
//      * isn't found.
//      *
//      * @param key
//      * @return
//      */
//     public Object get(Object key) {
//         Object val = super.get(key);
//         if (val == null && key instanceof Option) {
//             val = ((Option)key).defaultValue;
//         }
// 
//         return val;
//     }
// 
//     public Object get(T key, Object defaultValue) {
//         return get(key) != null ? get(key) : defaultValue;
//     }
// 
//     public Boolean getBoolean(T key) {
//         return getBoolean(key, null);
//     }
// 
//     public Boolean getBoolean(T key, Boolean defaultValue) {
//         Object value = get(key);
//         if (value == null) {
//             value = defaultValue;
//         } else if (!(value instanceof Boolean)) {
//             value = Boolean.parseBoolean(value.toString());
//         }
// 
//         return (Boolean)value;
//     }
// 
//     public Integer getInt(T key) {
//         return getInt(key, null);
//     }
// 
//     public Integer getInt(T key, Integer defaultValue) {
//         Object value = get(key);
//         if (value == null) {
//             value = defaultValue;
//         } else if (!(value instanceof Integer)) {
//             value = Integer.parseInt(value.toString());
//         }
// 
//         return (Integer)value;
//     }
// 
//     public Long getLong(T key) {
//         return getLong(key, null);
//     }
// 
//     public Long getLong(T key, Long defaultValue) {
//         Object value = get(key);
//         if (value == null) {
//             value = defaultValue;
//         } else if (!(value instanceof Long)) {
//             value = Long.parseLong(value.toString());
//         }
// 
//         return (Long)value;
//     }
// 
//     public Double getDouble(T key) {
//         return getDouble(key, null);
//     }
// 
//     public Double getDouble(T key, Double defaultValue) {
//         Object value = get(key);
//         if (value == null) {
//             value = defaultValue;
//         } else if (!(value instanceof Double)) {
//             value = Double.parseDouble(value.toString());
//         }
// 
//         return (Double)value;
//     }
// 
//     public String getString(T key) {
//         return getString(key, null);
//     }
// 
//     public String getString(T key, String defaultValue) {
//         return get(key) != null ? get(key).toString() : defaultValue;
//     }
// 
//     public Date getDate(T key) {
//         return getDate(key, null);
//     }
// 
//     public Date getDate(T key, Date defaultValue) {
//         return get(key) != null ? (Date)get(key) : defaultValue;
//     }
// 
//     public List getList(T key) {
//         Object v = get(key);
//         if (v instanceof List || v == null) {
//             return (List) v;
//         }
//         return Arrays.asList(v);
//     }
// 
//     public Options put(T key, Object value) {
//         super.put(key, value);
// 
//         return this;
//     }
// 
//     /**
//      * Returns true if key resolves to a *non-null value* (considering
//      * a possible default), false otherwise.
//      */
//     public boolean has(T key) {
//         return get(key) != null;
//     }
// 
//     public Options<T> merge(Options<T> otherOptions) {
//         Options mergedOptions = new Options();
//         for (T key : this.keySet()) {
//             mergedOptions.put(key, this.get(key));
//         }
//         for (T key : otherOptions.keySet()) {
//             mergedOptions.put(key, otherOptions.get(key));
//         }
//         return mergedOptions;
//     }
// }
// 
// Path: core/src/main/java/org/projectodd/wunderboss/codecs/Codec.java
// public interface Codec<E,D> {
// 
//     E encode(D data);
// 
//     D decode(E encoded);
// 
//     Class<E> encodesTo();
// 
//     String name();
// 
//     String contentType();
// }


// Path: caching/src/main/java/org/projectodd/wunderboss/caching/InfinispanCaching.java
import org.infinispan.Cache;
import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.manager.EmbeddedCacheManager;
import org.jboss.logging.Logger;
import org.projectodd.wunderboss.Options;
import org.projectodd.wunderboss.codecs.Codec;
import java.util.Map;

        Cache result = null;
        if (manager().isRunning(name)) {
            result = manager().getCache(name);
            if (!result.getStatus().allowInvocations()) {
                result.start();
            }
        }
        return result;
    }
    
    @Override
    public Cache findOrCreate(String name, Map<CreateOption,Object> options) {
        Cache result = find(name);
        if (result == null) {
            manager().defineConfiguration(name, Config.uration(validate(options)));
            log.info("Creating cache: "+name);
            result = manager().getCache(name);
        }
        return result;
    }

    @Override
    public boolean stop(String name) {
        EmbeddedCacheManager mgr = manager();
        boolean before = mgr.isRunning(name);
        mgr.removeCache(name);
        return before != mgr.isRunning(name);
    }

    @Override
    public Cache withCodec(Cache cache, Codec codec) {