// 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/StableIdsResolver.java
// public interface StableIdsResolver<M, BE extends BinderEnvironment> {
//   int getId(M model, BE environment);
// }
// 
// Path: library/src/main/java/drebin/core/ViewHost.java
// public class ViewHost<V extends View> {
//   public final V rootView;
// 
//   public ViewHost(V view) {
//     this.rootView = view;
//   }
// }


import android.content.Context;
import android.support.v4.util.SparseArrayCompat;
import android.support.v7.widget.RecyclerView;
import android.view.ViewGroup;
import java.util.List;
import drebin.core.Binder;
import drebin.core.BinderEnvironment;
import drebin.core.StableIdsResolver;
import drebin.core.ViewHost;
    mContext = context;
    mEnvironment = environment;
    mBinderCache = new SparseArrayCompat<>();
    mItems = items;
    mMapper = mapper;
    mIdResolver = stableIdsResolver;
    setHasStableIds(mIdResolver != null);
  }

  public void add(Object item) {
    mItems.add(item);
  }

  public void addAll(List items) {
    mItems.addAll(items);
  }

  public void clear() {
    mItems.clear();
  }

  @Override public int getItemViewType(final int position) {
    Object rawItem = mItems.get(position);
    Binder binder = mMapper.binderForModel(rawItem, mEnvironment);
    mBinderCache.put(binder.hashCode(), binder);
    return binder.hashCode();
  }

  @Override public BinderRecyclerViewAdapter.BinderViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
    Binder binder = mBinderCache.get(viewType);
// 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/StableIdsResolver.java
// public interface StableIdsResolver<M, BE extends BinderEnvironment> {
//   int getId(M model, BE environment);
// }
// 
// Path: library/src/main/java/drebin/core/ViewHost.java
// public class ViewHost<V extends View> {
//   public final V rootView;
// 
//   public ViewHost(V view) {
//     this.rootView = view;
//   }
// }


// Path: library/src/main/java/drebin/util/BinderRecyclerViewAdapter.java
import android.content.Context;
import android.support.v4.util.SparseArrayCompat;
import android.support.v7.widget.RecyclerView;
import android.view.ViewGroup;
import java.util.List;
import drebin.core.Binder;
import drebin.core.BinderEnvironment;
import drebin.core.StableIdsResolver;
import drebin.core.ViewHost;

    mContext = context;
    mEnvironment = environment;
    mBinderCache = new SparseArrayCompat<>();
    mItems = items;
    mMapper = mapper;
    mIdResolver = stableIdsResolver;
    setHasStableIds(mIdResolver != null);
  }

  public void add(Object item) {
    mItems.add(item);
  }

  public void addAll(List items) {
    mItems.addAll(items);
  }

  public void clear() {
    mItems.clear();
  }

  @Override public int getItemViewType(final int position) {
    Object rawItem = mItems.get(position);
    Binder binder = mMapper.binderForModel(rawItem, mEnvironment);
    mBinderCache.put(binder.hashCode(), binder);
    return binder.hashCode();
  }

  @Override public BinderRecyclerViewAdapter.BinderViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
    Binder binder = mBinderCache.get(viewType);
    ViewHost viewHost = binder.createViewHost(binder.getViewFactory().create(mContext, parent));