// Path: library/src/main/java/drebin/core/Binder.java
// public interface Binder<V extends View, VH extends ViewHost<V>, M, BE extends BinderEnvironment> {
//   /**
//    * @return an enclosing {@link ViewFactory} for a {@link View}. The {@link ViewFactory}
//    * knows how to create a view.
//    */
//   ViewFactory<V> getViewFactory();
// 
//   /**
//    * @param view a root view created in the {@link ViewFactory}
//    * @return an enclosing {@link ViewHost} class.
//    * <p>
//    * The ViewHost would be the place to use injectors like ButterKnife or perform any decoration
//    * on the view.
//    */
//   VH createViewHost(V view);
// 
//   /**
//    * Displays the data from the model into the view.
//    *
//    * @param model
//    * @param viewHost
//    * @param environment
//    */
//   void bind(M model, VH viewHost, BE environment);
// 
//   /**
//    * Cleans up anything done in the {@link #bind(Object, ViewHost, BinderEnvironment)} method.
//    *
//    * @param viewHost
//    * @param environment
//    */
//   void unbind(VH viewHost, BE environment);
// }
// 
// Path: library/src/main/java/drebin/core/BinderEnvironment.java
// public interface BinderEnvironment {
//   /**
//    * Empty implementation of a {@link BinderEnvironment}. Useful when you don't have
//    * external input.
//    */
//   enum EmptyEnvironment implements BinderEnvironment {
//     INSTANCE;
//   }
// }
// 
// Path: library/src/main/java/drebin/core/BinderSelector.java
// public interface BinderSelector<M, BE extends BinderEnvironment> {
// 
//   /**
//    * @param model
//    * @param environment
//    * @return the appropriate {@link Binder} for the given model
//    */
//   Binder select(M model, BE environment);
// 
//   /**
//    * Creates a {@link BinderSelector} based on an only possible {@link Binder}.
//    */
//   class BINDER {
//     public static <M, BE extends BinderEnvironment> BinderSelector<M, BE> build(final Binder binder) {
//       return new BinderSelector<M, BE>() {
//         @Override public Binder select(final M item, final BE environment) {
//           return binder;
//         }
//       };
//     }
//   }
// }


import android.support.annotation.NonNull;
import android.support.v4.util.ArrayMap;
import drebin.core.Binder;
import drebin.core.BinderEnvironment;
import drebin.core.BinderSelector;
package drebin.util;



/**
 * Convenience mapper from model classes to binder selectors.
 */
public class BinderSelectorMapper {

  private final ArrayMap<Class, Entry> mEntries;

  public BinderSelectorMapper() {
    mEntries = new ArrayMap<>();
  }

  public void add(Class modelClass, Binder binder) {
    add(modelClass, BinderSelector.BINDER.build(binder));
  }

  public void add(Class modelClass, BinderSelector binderSelector) {
    mEntries.put(modelClass, new Entry(modelClass, binderSelector));
  }

// Path: library/src/main/java/drebin/core/Binder.java
// public interface Binder<V extends View, VH extends ViewHost<V>, M, BE extends BinderEnvironment> {
//   /**
//    * @return an enclosing {@link ViewFactory} for a {@link View}. The {@link ViewFactory}
//    * knows how to create a view.
//    */
//   ViewFactory<V> getViewFactory();
// 
//   /**
//    * @param view a root view created in the {@link ViewFactory}
//    * @return an enclosing {@link ViewHost} class.
//    * <p>
//    * The ViewHost would be the place to use injectors like ButterKnife or perform any decoration
//    * on the view.
//    */
//   VH createViewHost(V view);
// 
//   /**
//    * Displays the data from the model into the view.
//    *
//    * @param model
//    * @param viewHost
//    * @param environment
//    */
//   void bind(M model, VH viewHost, BE environment);
// 
//   /**
//    * Cleans up anything done in the {@link #bind(Object, ViewHost, BinderEnvironment)} method.
//    *
//    * @param viewHost
//    * @param environment
//    */
//   void unbind(VH viewHost, BE environment);
// }
// 
// Path: library/src/main/java/drebin/core/BinderEnvironment.java
// public interface BinderEnvironment {
//   /**
//    * Empty implementation of a {@link BinderEnvironment}. Useful when you don't have
//    * external input.
//    */
//   enum EmptyEnvironment implements BinderEnvironment {
//     INSTANCE;
//   }
// }
// 
// Path: library/src/main/java/drebin/core/BinderSelector.java
// public interface BinderSelector<M, BE extends BinderEnvironment> {
// 
//   /**
//    * @param model
//    * @param environment
//    * @return the appropriate {@link Binder} for the given model
//    */
//   Binder select(M model, BE environment);
// 
//   /**
//    * Creates a {@link BinderSelector} based on an only possible {@link Binder}.
//    */
//   class BINDER {
//     public static <M, BE extends BinderEnvironment> BinderSelector<M, BE> build(final Binder binder) {
//       return new BinderSelector<M, BE>() {
//         @Override public Binder select(final M item, final BE environment) {
//           return binder;
//         }
//       };
//     }
//   }
// }


// Path: library/src/main/java/drebin/util/BinderSelectorMapper.java
import android.support.annotation.NonNull;
import android.support.v4.util.ArrayMap;
import drebin.core.Binder;
import drebin.core.BinderEnvironment;
import drebin.core.BinderSelector;

package drebin.util;



/**
 * Convenience mapper from model classes to binder selectors.
 */
public class BinderSelectorMapper {

  private final ArrayMap<Class, Entry> mEntries;

  public BinderSelectorMapper() {
    mEntries = new ArrayMap<>();
  }

  public void add(Class modelClass, Binder binder) {
    add(modelClass, BinderSelector.BINDER.build(binder));
  }

  public void add(Class modelClass, BinderSelector binderSelector) {
    mEntries.put(modelClass, new Entry(modelClass, binderSelector));
  }

  @NonNull Binder binderForModel(Object model, BinderEnvironment environment) {