// Path: src/main/java/com/optimaize/command4j/cache/ExecutorCache.java
// public final class ExecutorCache {
// 
//     private final Cache<ExecutorCacheKey, Object> cache;
// 
//     /**
//      * Creates a cache with the given Guava cache.
//      */
//     public ExecutorCache(@NotNull Cache<ExecutorCacheKey, Object> cache) {
//         this.cache = cache;
//     }
// 
//     /**
//      * Creates a cache with a default Guava cache that works for most scenarios.
//      */
//     public ExecutorCache() {
//         this.cache = CacheBuilder
//                 .newBuilder()
//                 .softValues() //disputable.
//                 .maximumSize(500)
//                 .build();
//     }
// 
//     @Nullable
//     public <V> V getIfPresent(@NotNull ExecutorCacheKey<V> key) {
//         //noinspection unchecked
//         return (V) cache.getIfPresent(key);
//     }
// 
//     public <V> V get(@NotNull ExecutorCacheKey<V> key, @NotNull Callable<? extends V> valueLoader) throws Exception {
//         //to understand this, see what cache.get() throws. we want to unwrap the throwable, whatever it was.
//         try {
//             //noinspection unchecked
//             return (V) cache.get(key, valueLoader);
//         } catch (UncheckedExecutionException | ExecutionError e) {
//             throw Throwables.propagate(e.getCause());
//         } catch (ExecutionException e) {
//             Throwables.propagateIfInstanceOf(e.getCause(), Exception.class);
//             throw Throwables.propagate(e.getCause());
//         }
//     }
// 
//     public <V> void put(@NotNull ExecutorCacheKey<V> key, V value) {
//         cache.put(key, value);
//     }
// 
//     public void invalidate(@NotNull ExecutorCacheKey<?> key) {
//         cache.invalidate(key);
//     }
// 
//     public long size() {
//         return cache.size();
//     }
// 
//     public void invalidateAll() {
//         cache.invalidateAll();
//     }
// 
//     public ImmutableMap<ExecutorCacheKey, Object> getAllPresent(@NotNull Iterable<?> keys) {
//         return cache.getAllPresent(keys);
//     }
// }


import com.google.common.base.Optional;
import com.optimaize.command4j.cache.ExecutorCache;
import org.jetbrains.annotations.NotNull;
package com.optimaize.command4j;


/**
 * The execution context is an object created by the executor that lives
 * as long as the command is executing. It gives the command implementation
 * access to the command framework and a global {@link ExecutorCache cache}.
 *
 * @author Eike Kettner
 * @author Fabian Kessler
 */
public interface ExecutionContext {

    /**
     * @return the mode that was supplied to the initial invocation.
     */
    @NotNull
    Mode getMode();

    /**
     * @return the global cache to store/retrieve objects to/from.
     */
    @NotNull
// Path: src/main/java/com/optimaize/command4j/cache/ExecutorCache.java
// public final class ExecutorCache {
// 
//     private final Cache<ExecutorCacheKey, Object> cache;
// 
//     /**
//      * Creates a cache with the given Guava cache.
//      */
//     public ExecutorCache(@NotNull Cache<ExecutorCacheKey, Object> cache) {
//         this.cache = cache;
//     }
// 
//     /**
//      * Creates a cache with a default Guava cache that works for most scenarios.
//      */
//     public ExecutorCache() {
//         this.cache = CacheBuilder
//                 .newBuilder()
//                 .softValues() //disputable.
//                 .maximumSize(500)
//                 .build();
//     }
// 
//     @Nullable
//     public <V> V getIfPresent(@NotNull ExecutorCacheKey<V> key) {
//         //noinspection unchecked
//         return (V) cache.getIfPresent(key);
//     }
// 
//     public <V> V get(@NotNull ExecutorCacheKey<V> key, @NotNull Callable<? extends V> valueLoader) throws Exception {
//         //to understand this, see what cache.get() throws. we want to unwrap the throwable, whatever it was.
//         try {
//             //noinspection unchecked
//             return (V) cache.get(key, valueLoader);
//         } catch (UncheckedExecutionException | ExecutionError e) {
//             throw Throwables.propagate(e.getCause());
//         } catch (ExecutionException e) {
//             Throwables.propagateIfInstanceOf(e.getCause(), Exception.class);
//             throw Throwables.propagate(e.getCause());
//         }
//     }
// 
//     public <V> void put(@NotNull ExecutorCacheKey<V> key, V value) {
//         cache.put(key, value);
//     }
// 
//     public void invalidate(@NotNull ExecutorCacheKey<?> key) {
//         cache.invalidate(key);
//     }
// 
//     public long size() {
//         return cache.size();
//     }
// 
//     public void invalidateAll() {
//         cache.invalidateAll();
//     }
// 
//     public ImmutableMap<ExecutorCacheKey, Object> getAllPresent(@NotNull Iterable<?> keys) {
//         return cache.getAllPresent(keys);
//     }
// }


// Path: src/main/java/com/optimaize/command4j/ExecutionContext.java
import com.google.common.base.Optional;
import com.optimaize.command4j.cache.ExecutorCache;
import org.jetbrains.annotations.NotNull;

package com.optimaize.command4j;


/**
 * The execution context is an object created by the executor that lives
 * as long as the command is executing. It gives the command implementation
 * access to the command framework and a global {@link ExecutorCache cache}.
 *
 * @author Eike Kettner
 * @author Fabian Kessler
 */
public interface ExecutionContext {

    /**
     * @return the mode that was supplied to the initial invocation.
     */
    @NotNull
    Mode getMode();

    /**
     * @return the global cache to store/retrieve objects to/from.
     */
    @NotNull
    ExecutorCache getCache();