content: package com.airbnb.epoxy;
  
  import java.util.Collections;
  import java.util.List;
  
  import androidx.annotation.NonNull;
  import androidx.annotation.Nullable;
  import androidx.recyclerview.widget.AdapterListUpdateCallback;
  import androidx.recyclerview.widget.DiffUtil;
  import androidx.recyclerview.widget.ListUpdateCallback;
  import androidx.recyclerview.widget.RecyclerView.Adapter;
  
  /**
   * Wraps the result of {@link AsyncEpoxyDiffer#submitList(List)}.
   */
  public class DiffResult {
    @NonNull final List<? extends EpoxyModel<?>> previousModels;
    @NonNull final List<? extends EpoxyModel<?>> newModels;
  
    /**
     * If this is non null it means the full differ ran and the result is contained
     * in this object. If it is null, it means that either the old list or the new list was empty, so
     * we can simply add all or clear all items and skipped running the full diffing.
     */
    @Nullable final DiffUtil.DiffResult differResult;
  
    /** No changes were made to the models. */
    static DiffResult noOp(@Nullable List<? extends EpoxyModel<?>> models) {
      if (models == null) {
        models = Collections.emptyList();
      }
      return new DiffResult(models, models, null);
    }
  
    /** The previous list was empty and the given non empty list was inserted. */
    static DiffResult inserted(@NonNull List<? extends EpoxyModel<?>> newModels) {
      //noinspection unchecked
      return new DiffResult(Collections.EMPTY_LIST, newModels, null);
    }
  
    /** The previous list was non empty and the new list is empty. */
    static DiffResult clear(@NonNull List<? extends EpoxyModel<?>> previousModels) {
      //noinspection unchecked
      return new DiffResult(previousModels, Collections.EMPTY_LIST, null);
    }
  
    /**
     * The previous and new models are both non empty and a full differ pass was run on them.
     * There may be no changes, however.
     */
    static DiffResult diff(
        @NonNull List<? extends EpoxyModel<?>> previousModels,
        @NonNull List<? extends EpoxyModel<?>> newModels,
        @NonNull DiffUtil.DiffResult differResult
    ) {
      return new DiffResult(previousModels, newModels, differResult);
    }
  
    private DiffResult(
        @NonNull List<? extends EpoxyModel<?>> previousModels,
        @NonNull List<? extends EpoxyModel<?>> newModels,
        @Nullable DiffUtil.DiffResult differResult
    ) {
      this.previousModels = previousModels;
      this.newModels = newModels;
      this.differResult = differResult;
    }
  
    public void dispatchTo(Adapter adapter) {
      dispatchTo(new AdapterListUpdateCallback(adapter));
    }
  
    public void dispatchTo(ListUpdateCallback callback) {
      if (differResult != null) {
        differResult.dispatchUpdatesTo(callback);
      } else if (newModels.isEmpty() && !previousModels.isEmpty()) {
        callback.onRemoved(0, previousModels.size());
      } else if (!newModels.isEmpty() && previousModels.isEmpty()) {
        callback.onInserted(0, newModels.size());
      }
  
      // Else nothing changed!
    }
  }
  