// 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.Optional;
import com.google.common.collect.Maps;
import com.optimaize.command4j.lang.Immutable;
import com.optimaize.command4j.lang.Key;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
package com.optimaize.command4j;



/**
 * The mode contains definitions that apply to a whole execution of
 * a command. They may control the behaviour of the executor by defining
 * values that can be accessed by all commands and
 * {@link ModeExtension extensions} in a chain of execution.
 *
 * <p>A Mode may be reused for multiple command executions, or it may be created
 * completely new for each call, or an existing one may serve as a base where
 * only little change is applied for a new command execution.</p>
 *
 * <p>The object is immutable; all "modification" methods return a new instance
 * and leave the old one untouched.</p>
 *
 * @author Eike Kettner
 * @author Fabian Kessler
 */
@Immutable
public final class Mode {

    /**
     * Because it's immutable anyway it does not need to be created over and over again.
     */
    private static final Mode INITIAL_MODE = new Mode();

    /**
     * Does not contain null values.
     */
    @NotNull
// 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/Mode.java
import com.google.common.base.Optional;
import com.google.common.collect.Maps;
import com.optimaize.command4j.lang.Immutable;
import com.optimaize.command4j.lang.Key;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;

package com.optimaize.command4j;



/**
 * The mode contains definitions that apply to a whole execution of
 * a command. They may control the behaviour of the executor by defining
 * values that can be accessed by all commands and
 * {@link ModeExtension extensions} in a chain of execution.
 *
 * <p>A Mode may be reused for multiple command executions, or it may be created
 * completely new for each call, or an existing one may serve as a base where
 * only little change is applied for a new command execution.</p>
 *
 * <p>The object is immutable; all "modification" methods return a new instance
 * and leave the old one untouched.</p>
 *
 * @author Eike Kettner
 * @author Fabian Kessler
 */
@Immutable
public final class Mode {

    /**
     * Because it's immutable anyway it does not need to be created over and over again.
     */
    private static final Mode INITIAL_MODE = new Mode();

    /**
     * Does not contain null values.
     */
    @NotNull
    private final Map<Key<?>, Object> defs = Maps.newHashMap();