content: package com.airbnb.epoxy;
  
  /** Helper to store relevant information about a model that we need to determine if it changed. */
  class ModelState {
    long id;
    int hashCode;
    int position;
    EpoxyModel<?> model;
  
    /**
     * A link to the item with the same id in the other list when diffing two lists. This will be null
     * if the item doesn't exist, in the case of insertions or removals. This is an optimization to
     * prevent having to look up the matching pair in a hash map every time.
     */
    ModelState pair;
  
    /**
     * How many movement operations have been applied to this item in order to update its position. As
     * we find more item movements we need to update the position of affected items in the list in
     * order to correctly calculate the next movement. Instead of iterating through all items in the
     * list every time a movement operation happens we keep track of how many of these operations have
     * been applied to an item, and apply all new operations in order when we need to get this item's
     * up to date position.
     */
    int lastMoveOp;
  
    static ModelState build(EpoxyModel<?> model, int position, boolean immutableModel) {
      ModelState state = new ModelState();
  
      state.lastMoveOp = 0;
      state.pair = null;
      state.id = model.id();
      state.position = position;
  
      if (immutableModel) {
        state.model = model;
      } else {
        state.hashCode = model.hashCode();
      }
  
      return state;
    }
  
    /**
     * Used for an item inserted into the new list when we need to track moves that effect the
     * inserted item in the old list.
     */
    void pairWithSelf() {
      if (pair != null) {
        throw new IllegalStateException("Already paired.");
      }
  
      pair = new ModelState();
      pair.lastMoveOp = 0;
      pair.id = id;
      pair.position = position;
      pair.hashCode = hashCode;
      pair.pair = this;
      pair.model = model;
    }
  
    @Override
    public String toString() {
      return "ModelState{"
          + "id=" + id
          + ", model=" + model
          + ", hashCode=" + hashCode
          + ", position=" + position
          + ", pair=" + pair
          + ", lastMoveOp=" + lastMoveOp
          + '}';
    }
  }
  