class CurrencyListEditorPresenter extends BasePresenter<CurrencyListEditorView> {

    @Override
    @CallSuper
    public void subscribe() {
        // A ConnectableObservable resembles an ordinary Observable, but it does not begin emitting until #connect is called
        final ConnectableObservable<List<CharSequence>> currenciesConnectableObservable = Observable.fromCallable(this.databaseHelper::getCurrenciesList)
                .subscribeOn(subscribeOnScheduler)
                .observeOn(observeOnScheduler)
                .publish();

        // Display the full list of currencies
        this.compositeDisposable.add(currenciesConnectableObservable
                .subscribe(view.displayCurrencies()));

        // Ensure we always restore the "last" currency
        //noinspection Convert2MethodRef
        this.compositeDisposable.add(currenciesConnectableObservable
                .map(currenciesList -> {
                    final String currencyCode;
                    if (savedInstanceState != null && savedInstanceState.containsKey(OUT_STATE_SELECTED_CURRENCY_POSITION)) {
                        currencyCode = currenciesList.get(savedInstanceState.getInt(OUT_STATE_SELECTED_CURRENCY_POSITION)).toString();
                    } else if (lastSelectedCurrencyCodeIndex >= 0) {
                        currencyCode = currenciesList.get(lastSelectedCurrencyCodeIndex).toString();
                    } else {
                        currencyCode = defaultCurrencyCodeSupplier.get();
                    }

                    final int currencyPosition = currenciesList.indexOf(currencyCode);
                    if (currencyPosition >= 0) {
                        return currencyPosition;
                    } else {
                        return 0;
                    }
                })
                .subscribe(view.displayCurrencySelection()));

        // Handle selections
        this.compositeDisposable.add(currenciesConnectableObservable
                    .flatMap(currenciesList -> {
                        //noinspection ConstantConditions
                        return view.currencyClicks()
                                .filter(currencyIndex -> currencyIndex >= 0);
                    })
                    .doOnNext(currencyIndex -> lastSelectedCurrencyCodeIndex = currencyIndex)
                    .subscribe(view.displayCurrencySelection()));

        // Call #connect to start out emissions
        this.compositeDisposable.add(currenciesConnectableObservable.connect());
    }

    public  CurrencyListEditorPresenter(@NonNull CurrencyListEditorView view,
                                       @NonNull DatabaseHelper databaseHelper,
                                       @NonNull CurrencyCodeSupplier defaultCurrencyCodeSupplier,
                                       @Nullable Bundle savedInstanceState);
    @VisibleForTesting  CurrencyListEditorPresenter(@NonNull CurrencyListEditorView view,
                                @NonNull DatabaseHelper databaseHelper,
                                @NonNull CurrencyCodeSupplier defaultCurrencyCodeSupplier,
                                @Nullable Bundle savedInstanceState,
                                @NonNull Scheduler subscribeOnScheduler,
                                @NonNull Scheduler observeOnScheduler);

}