// Path: cacheio-core/src/main/java/com/mobilejazz/cacheio/FutureCache.java
// public interface FutureCache<K, V> {
// 
//   Future<V> get(K key);
// 
//   Future<V> put(K key, V value, long expiry, TimeUnit unit);
// 
//   Future<K> remove(K key);
// 
//   Future<Map<K, V>> getAll(Collection<K> keys);
// 
//   Future<Map<K, V>> putAll(Map<K, V> map, long expiry, TimeUnit unit);
// 
//   Future<Collection<K>> removeAll(Collection<K> keys);
// 
// }
// 
// Path: cacheio-core/src/main/java/com/mobilejazz/cacheio/SyncCache.java
// public interface SyncCache<K, V> {
// 
//   V get(K key);
// 
//   V put(K key, V value, long expiry, TimeUnit unit);
// 
//   K remove(K key);
// 
//   Map<K, V> getAll(Collection<K> keys);
// 
//   Map<K, V> putAll(Map<K, V> map, long expiry, TimeUnit unit);
// 
//   Collection<K> removeAll(Collection<K> keys);
// 
// }
// 
// Path: cacheio-core/src/main/java/com/mobilejazz/cacheio/helper/Preconditions.java
// public static <T> T checkArgument(T object, String message) {
//   if (object == null) {
//     throw new IllegalArgumentException(message);
//   }
// 
//   return object;
// }


import com.mobilejazz.cacheio.FutureCache;
import com.mobilejazz.cacheio.SyncCache;
import java.util.*;
import java.util.concurrent.*;
import static com.mobilejazz.cacheio.helper.Preconditions.checkArgument;

    private Class<K> keyType;
    private Class<V> valueType;

    private Builder() {
    }

    private Builder(Builder<K, V> proto) {
      this.delegate = proto.delegate;
      this.keyType = proto.keyType;
      this.valueType = proto.valueType;
    }

    public Builder<K, V> setDelegate(FutureCache<K, V> delegate) {
      this.delegate = delegate;
      return this;
    }

    protected Builder<K, V> setKeyType(Class<K> keyType) {
      this.keyType = keyType;
      return this;
    }

    protected Builder<K, V> setValueType(Class<V> valueType) {
      this.valueType = valueType;
      return this;
    }

    public SyncCacheWrapper<K, V> build() {

// Path: cacheio-core/src/main/java/com/mobilejazz/cacheio/FutureCache.java
// public interface FutureCache<K, V> {
// 
//   Future<V> get(K key);
// 
//   Future<V> put(K key, V value, long expiry, TimeUnit unit);
// 
//   Future<K> remove(K key);
// 
//   Future<Map<K, V>> getAll(Collection<K> keys);
// 
//   Future<Map<K, V>> putAll(Map<K, V> map, long expiry, TimeUnit unit);
// 
//   Future<Collection<K>> removeAll(Collection<K> keys);
// 
// }
// 
// Path: cacheio-core/src/main/java/com/mobilejazz/cacheio/SyncCache.java
// public interface SyncCache<K, V> {
// 
//   V get(K key);
// 
//   V put(K key, V value, long expiry, TimeUnit unit);
// 
//   K remove(K key);
// 
//   Map<K, V> getAll(Collection<K> keys);
// 
//   Map<K, V> putAll(Map<K, V> map, long expiry, TimeUnit unit);
// 
//   Collection<K> removeAll(Collection<K> keys);
// 
// }
// 
// Path: cacheio-core/src/main/java/com/mobilejazz/cacheio/helper/Preconditions.java
// public static <T> T checkArgument(T object, String message) {
//   if (object == null) {
//     throw new IllegalArgumentException(message);
//   }
// 
//   return object;
// }


// Path: cacheio-core/src/main/java/com/mobilejazz/cacheio/wrappers/SyncCacheWrapper.java
import com.mobilejazz.cacheio.FutureCache;
import com.mobilejazz.cacheio.SyncCache;
import java.util.*;
import java.util.concurrent.*;
import static com.mobilejazz.cacheio.helper.Preconditions.checkArgument;


    private Class<K> keyType;
    private Class<V> valueType;

    private Builder() {
    }

    private Builder(Builder<K, V> proto) {
      this.delegate = proto.delegate;
      this.keyType = proto.keyType;
      this.valueType = proto.valueType;
    }

    public Builder<K, V> setDelegate(FutureCache<K, V> delegate) {
      this.delegate = delegate;
      return this;
    }

    protected Builder<K, V> setKeyType(Class<K> keyType) {
      this.keyType = keyType;
      return this;
    }

    protected Builder<K, V> setValueType(Class<V> valueType) {
      this.valueType = valueType;
      return this;
    }

    public SyncCacheWrapper<K, V> build() {

      checkArgument(keyType, "Key type cannot be null");