class CollectionViewPresenter {

  void onLoadMore() {
    disposeDisposable();
    if (listData == null || isCurrentLastPage(listData.paging())) {
      return;
    }
    final int nextPage = listData.paging().currentPage() + 1;
    final List<?> currentItems = listData.items();
    disposable = map(dataProvider.fetch(nextPage))
        .map(new Function<List<?>, List<?>>() {
          @Override
          public List<?> apply(List<?> objects) throws Exception {
            return concat(currentItems, objects);
          }
        })
        .map(includeLoading())
        .subscribe(
            new Consumer<List<?>>() {
              @Override
              public void accept(List<?> items) throws Exception {
                collectionView.setItems(items);
              }
            },
            new Consumer<Throwable>() {
              @Override
              public void accept(Throwable throwable) throws Exception {
                throwable.printStackTrace();
                collectionView.hideLoadMore();
              }
            });
  }

    CollectionViewPresenter(@NonNull DataProvider<?> dataProvider);

}