// Path: src/main/java/com/optimaize/command4j/Command.java
// public interface Command<A, R> {
// 
//     /**
//      * Runs the remote command.
//      *
//      * <p>This method always blocks until either the command finishes successfully, aborts by throwing an
//      * exception, or is cancelled early. (The {@link CommandExecutorService} allows you to execute
//      * commands in a non-blocking way.)</p>
//      *
//      * @param arg The {@link Optional} argument. If you need more than 1 argument then you may create a
//      *            request class as container, or maybe it's enough to just use {@link Tuples tuples}.
//      * @param ec
//      * @return Commands may return null, since null values are handled by the framework in that they're wrapped
//      *         into an {@link Optional}.
//      * @throws Exception
//      *
//      * TODO Eike: The return value is nullable and the framework makes an Optional out of it.
//      *            Why not the same for the argument? We could make the interface more consistent.
//      *            Is there a reason against that?
//      */
//     @Nullable
//     R call(@NotNull Optional<A> arg, @NotNull ExecutionContext ec) throws Exception;
// 
//     /**
//      * Like Java's Thread, a Command has a name.
//      *
//      * <p>Because toString() can become long with all the interceptors wrapping a base command, this
//      * keeps it simple to what it actually does.</p>
//      *
//      * <p>Certain kinds of combined commands, like a ComposedCommand or a ConditionCommand, don't have a single
//      * name, they show the names of the contained commands.</p>
//      *
//      * @return an identifier, not unique but usually distinguishable
//      */
//     String getName();
// }
// 
// Path: src/main/java/com/optimaize/command4j/lang/Key.java
// @Immutable
// public final class Key<V> {
// 
//     @NotNull
//     private final String name;
//     @NotNull
//     private final Class<V> type;
// 
//     private Key(@NotNull String name, @NotNull Class<V> type) {
//         this.name = name;
//         this.type = type;
//     }
// 
//     /**
//      * Creates a new key of the specified name and type.
//      *
//      * @see #stringKey(String)
//      * @see #integerKey(String)
//      * @see #booleanKey(String)
//      */
//     @NotNull
//     public static <T> Key<T> create(@NotNull String name, @NotNull Class<T> type) {
//         return new Key<>(name, type);
//     }
// 
//     /**
//      * Creates a new key of type String.
//      */
//     @NotNull
//     public static Key<String> stringKey(@NotNull String name) {
//         return create(name, String.class);
//     }
// 
//     /**
//      * Creates a new key of type Integer.
//      */
//     @NotNull
//     public static Key<Integer> integerKey(@NotNull String name) {
//         return create(name, Integer.class);
//     }
// 
//     /**
//      * Creates a new key of type Boolean.
//      */
//     @NotNull
//     public static Key<Boolean> booleanKey(@NotNull String name) {
//         return create(name, Boolean.class);
//     }
// 
//     @NotNull
//     public String name() {
//         return name;
//     }
// 
//     @NotNull
//     public Class<V> type() {
//         return type;
//     }
// 
//     @Override
//     public String toString() {
//         return "Key[" + name + ":" + type.getSimpleName() + "]";
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (o == null || getClass() != o.getClass()) return false;
// 
//         Key key = (Key) o;
// 
//         if (!name.equals(key.name)) return false;
//         if (!type.equals(key.type)) return false;
// 
//         return true;
//     }
// 
//     @Override
//     public int hashCode() {
//         int result = name.hashCode();
//         result = 31 * result + type.hashCode();
//         return result;
//     }
// 
// }


import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.optimaize.command4j.Command;
import com.optimaize.command4j.lang.Key;
import org.jetbrains.annotations.NotNull;
package com.optimaize.command4j.commands;


/**
 * A base class for users wanting to implement a {@link Command}.
 *
 * @param <A> the optional Argument's data type
 * @param <R> the Result's data type
 * @author Eike Kettner
 */
public abstract class BaseCommand<A, R> implements CombinableCommand<A,R> {

    @NotNull @Override
// Path: src/main/java/com/optimaize/command4j/Command.java
// public interface Command<A, R> {
// 
//     /**
//      * Runs the remote command.
//      *
//      * <p>This method always blocks until either the command finishes successfully, aborts by throwing an
//      * exception, or is cancelled early. (The {@link CommandExecutorService} allows you to execute
//      * commands in a non-blocking way.)</p>
//      *
//      * @param arg The {@link Optional} argument. If you need more than 1 argument then you may create a
//      *            request class as container, or maybe it's enough to just use {@link Tuples tuples}.
//      * @param ec
//      * @return Commands may return null, since null values are handled by the framework in that they're wrapped
//      *         into an {@link Optional}.
//      * @throws Exception
//      *
//      * TODO Eike: The return value is nullable and the framework makes an Optional out of it.
//      *            Why not the same for the argument? We could make the interface more consistent.
//      *            Is there a reason against that?
//      */
//     @Nullable
//     R call(@NotNull Optional<A> arg, @NotNull ExecutionContext ec) throws Exception;
// 
//     /**
//      * Like Java's Thread, a Command has a name.
//      *
//      * <p>Because toString() can become long with all the interceptors wrapping a base command, this
//      * keeps it simple to what it actually does.</p>
//      *
//      * <p>Certain kinds of combined commands, like a ComposedCommand or a ConditionCommand, don't have a single
//      * name, they show the names of the contained commands.</p>
//      *
//      * @return an identifier, not unique but usually distinguishable
//      */
//     String getName();
// }
// 
// Path: src/main/java/com/optimaize/command4j/lang/Key.java
// @Immutable
// public final class Key<V> {
// 
//     @NotNull
//     private final String name;
//     @NotNull
//     private final Class<V> type;
// 
//     private Key(@NotNull String name, @NotNull Class<V> type) {
//         this.name = name;
//         this.type = type;
//     }
// 
//     /**
//      * Creates a new key of the specified name and type.
//      *
//      * @see #stringKey(String)
//      * @see #integerKey(String)
//      * @see #booleanKey(String)
//      */
//     @NotNull
//     public static <T> Key<T> create(@NotNull String name, @NotNull Class<T> type) {
//         return new Key<>(name, type);
//     }
// 
//     /**
//      * Creates a new key of type String.
//      */
//     @NotNull
//     public static Key<String> stringKey(@NotNull String name) {
//         return create(name, String.class);
//     }
// 
//     /**
//      * Creates a new key of type Integer.
//      */
//     @NotNull
//     public static Key<Integer> integerKey(@NotNull String name) {
//         return create(name, Integer.class);
//     }
// 
//     /**
//      * Creates a new key of type Boolean.
//      */
//     @NotNull
//     public static Key<Boolean> booleanKey(@NotNull String name) {
//         return create(name, Boolean.class);
//     }
// 
//     @NotNull
//     public String name() {
//         return name;
//     }
// 
//     @NotNull
//     public Class<V> type() {
//         return type;
//     }
// 
//     @Override
//     public String toString() {
//         return "Key[" + name + ":" + type.getSimpleName() + "]";
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (o == null || getClass() != o.getClass()) return false;
// 
//         Key key = (Key) o;
// 
//         if (!name.equals(key.name)) return false;
//         if (!type.equals(key.type)) return false;
// 
//         return true;
//     }
// 
//     @Override
//     public int hashCode() {
//         int result = name.hashCode();
//         result = 31 * result + type.hashCode();
//         return result;
//     }
// 
// }


// Path: src/main/java/com/optimaize/command4j/commands/BaseCommand.java
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.optimaize.command4j.Command;
import com.optimaize.command4j.lang.Key;
import org.jetbrains.annotations.NotNull;

package com.optimaize.command4j.commands;


/**
 * A base class for users wanting to implement a {@link Command}.
 *
 * @param <A> the optional Argument's data type
 * @param <R> the Result's data type
 * @author Eike Kettner
 */
public abstract class BaseCommand<A, R> implements CombinableCommand<A,R> {

    @NotNull @Override
    public final <C> BaseCommand<A, C> andThen(@NotNull Command<R, C> cmd) {