// Path: databoundary/src/main/java/eu/rampsoftware/er/data/CurrencyData.java
// public class CurrencyData {
//     private final String mBaseCurrency;
//     private Date mDate;
//     private Map<String, Double> mCurrencies;
// 
//     public CurrencyData(final Date date, final Map<String, Double> currencies, final String baseCurrency) {
//         mDate = date;
//         mCurrencies = currencies;
//         mBaseCurrency = baseCurrency;
//     }
// 
//     public String getBaseCurrency() {
//         return mBaseCurrency;
//     }
// 
//     public Date getDate() {
//         return mDate;
//     }
// 
//     public Map<String, Double> getCurrencies() {
//         return mCurrencies;
//     }
// }
// 
// Path: domain/src/main/java/eu/rampsoftware/er/domain/usecases/GetCurrenciesRatesDate.java
// public class GetCurrenciesRatesDate extends NoArgQueryUseCase<Optional<Date>> {
//     private final PreferencesData mPreferencesData;
// 
//     public GetCurrenciesRatesDate(final Scheduler workScheduler,
//                                   final Scheduler observeScheduler,
//                                   final PreferencesData preferencesData) {
//         super(workScheduler, observeScheduler);
//         mPreferencesData = preferencesData;
//     }
// 
//     @Override
//     protected Observable<Optional<Date>> buildUseCaseObservable() {
//         return Observable.just(mPreferencesData.getCurrenciesExchangeDate());
// 
//     }
// }
// 
// Path: domain/src/main/java/eu/rampsoftware/er/domain/usecases/GetCurrenciesUseCase.java
// public class GetCurrenciesUseCase extends QueryUseCase<CurrencyData, GetCurrenciesUseCase.CurrenciesParam> {
// 
//     private final CurrencyRepository mRepository;
//     private final PreferencesData mPreferences;
// 
//     public GetCurrenciesUseCase(final Scheduler workScheduler,
//                                 final Scheduler observeScheduler,
//                                 CurrencyRepository repository,
//                                 PreferencesData preferencesData) {
//         super(workScheduler, observeScheduler);
//         mRepository = repository;
//         mPreferences = preferencesData;
//     }
// 
//     @Override
//     protected Observable<CurrencyData> buildUseCaseObservable(final CurrenciesParam params) {
//         mPreferences.setCurrenciesExchangeDate(params.date);
//         return mRepository.getCurrencies(params.date);
//     }
// 
//     public static class CurrenciesParam {
//         Date date;
// 
//         public CurrenciesParam(final Date date) {
//             this.date = checkNotNull(date);
//         }
//     }
// }
// 
// Path: presentation/src/main/java/eu/rampsoftware/er/navigation/Navigator.java
// public class Navigator {
// 
//     private Activity mContext;
// 
//     public Navigator(final Activity context) {
//         mContext = context;
//     }
// 
//     public void navigateToCurrencyDetails(final String currencyCode) {
//         Intent intentToLaunch = CurrencyDetailsActivity.getCallingIntent(mContext, currencyCode);
//         mContext.startActivity(intentToLaunch);
//     }
// }
// 
// Path: presentation/src/main/java/eu/rampsoftware/er/viewmodel/BaseDisposableViewModel.java
// public abstract class BaseDisposableViewModel extends BaseObservable implements BaseViewModel {
// 
//     private final CompositeDisposable mDisposables;
// 
//     protected BaseDisposableViewModel() {
//         mDisposables = new CompositeDisposable();
//     }
// 
//     public void dispose() {
//         if (!mDisposables.isDisposed()) {
//             mDisposables.dispose();
//         }
//     }
// 
//     protected void addDisposable(Disposable disposable) {
//         mDisposables.add(disposable);
//     }
// 
// }
// 
// Path: presentation/src/main/java/eu/rampsoftware/er/viewmodel/BaseViewModel.java
// public interface BaseViewModel {
//     /**
//      * Invoked when view is initialized and is ready to display the data exposed by view model.
//      * @param bundle additional to be passed to the viewmodel.
//      */
//     void onLoad(final Bundle bundle);
// 
//     void dispose();
// }


import android.databinding.Bindable;
import android.databinding.ObservableArrayList;
import android.databinding.ObservableList;
import android.os.Bundle;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import eu.rampsoftware.er.BR;
import eu.rampsoftware.er.data.CurrencyData;
import eu.rampsoftware.er.domain.usecases.GetCurrenciesRatesDate;
import eu.rampsoftware.er.domain.usecases.GetCurrenciesUseCase;
import eu.rampsoftware.er.navigation.Navigator;
import eu.rampsoftware.er.viewmodel.BaseDisposableViewModel;
import eu.rampsoftware.er.viewmodel.BaseViewModel;
import static com.fernandocejas.arrow.checks.Preconditions.checkNotNull;
        notifyPropertyChanged(BR.progressVisible);
    }

    @Bindable
    public ObservableList<CurrencyItemViewModel> getCurrencies() {
        return mCurrencies;
    }

    @Override
    public void onLoad(final Bundle bundle) {
        setProgressVisible(true);
        addDisposable(
                mGetCurrenciesRatesDate.run()
                        .doOnError(throwable -> setProgressVisible(false))
                        .subscribe(dateOptional -> {
                            mReadDate = dateOptional.or(mReadDate);
                            onDate(mReadDate);
                        })
        );
    }

    private void onDate(final Date date) {
        addDisposable(
                mCurrenciesUseCase.run(new GetCurrenciesUseCase.CurrenciesParam(date))
                        .doFinally(() -> setProgressVisible(false))
                        .subscribe(this::onCurrencyDataLoaded)
        );

    }

// Path: databoundary/src/main/java/eu/rampsoftware/er/data/CurrencyData.java
// public class CurrencyData {
//     private final String mBaseCurrency;
//     private Date mDate;
//     private Map<String, Double> mCurrencies;
// 
//     public CurrencyData(final Date date, final Map<String, Double> currencies, final String baseCurrency) {
//         mDate = date;
//         mCurrencies = currencies;
//         mBaseCurrency = baseCurrency;
//     }
// 
//     public String getBaseCurrency() {
//         return mBaseCurrency;
//     }
// 
//     public Date getDate() {
//         return mDate;
//     }
// 
//     public Map<String, Double> getCurrencies() {
//         return mCurrencies;
//     }
// }
// 
// Path: domain/src/main/java/eu/rampsoftware/er/domain/usecases/GetCurrenciesRatesDate.java
// public class GetCurrenciesRatesDate extends NoArgQueryUseCase<Optional<Date>> {
//     private final PreferencesData mPreferencesData;
// 
//     public GetCurrenciesRatesDate(final Scheduler workScheduler,
//                                   final Scheduler observeScheduler,
//                                   final PreferencesData preferencesData) {
//         super(workScheduler, observeScheduler);
//         mPreferencesData = preferencesData;
//     }
// 
//     @Override
//     protected Observable<Optional<Date>> buildUseCaseObservable() {
//         return Observable.just(mPreferencesData.getCurrenciesExchangeDate());
// 
//     }
// }
// 
// Path: domain/src/main/java/eu/rampsoftware/er/domain/usecases/GetCurrenciesUseCase.java
// public class GetCurrenciesUseCase extends QueryUseCase<CurrencyData, GetCurrenciesUseCase.CurrenciesParam> {
// 
//     private final CurrencyRepository mRepository;
//     private final PreferencesData mPreferences;
// 
//     public GetCurrenciesUseCase(final Scheduler workScheduler,
//                                 final Scheduler observeScheduler,
//                                 CurrencyRepository repository,
//                                 PreferencesData preferencesData) {
//         super(workScheduler, observeScheduler);
//         mRepository = repository;
//         mPreferences = preferencesData;
//     }
// 
//     @Override
//     protected Observable<CurrencyData> buildUseCaseObservable(final CurrenciesParam params) {
//         mPreferences.setCurrenciesExchangeDate(params.date);
//         return mRepository.getCurrencies(params.date);
//     }
// 
//     public static class CurrenciesParam {
//         Date date;
// 
//         public CurrenciesParam(final Date date) {
//             this.date = checkNotNull(date);
//         }
//     }
// }
// 
// Path: presentation/src/main/java/eu/rampsoftware/er/navigation/Navigator.java
// public class Navigator {
// 
//     private Activity mContext;
// 
//     public Navigator(final Activity context) {
//         mContext = context;
//     }
// 
//     public void navigateToCurrencyDetails(final String currencyCode) {
//         Intent intentToLaunch = CurrencyDetailsActivity.getCallingIntent(mContext, currencyCode);
//         mContext.startActivity(intentToLaunch);
//     }
// }
// 
// Path: presentation/src/main/java/eu/rampsoftware/er/viewmodel/BaseDisposableViewModel.java
// public abstract class BaseDisposableViewModel extends BaseObservable implements BaseViewModel {
// 
//     private final CompositeDisposable mDisposables;
// 
//     protected BaseDisposableViewModel() {
//         mDisposables = new CompositeDisposable();
//     }
// 
//     public void dispose() {
//         if (!mDisposables.isDisposed()) {
//             mDisposables.dispose();
//         }
//     }
// 
//     protected void addDisposable(Disposable disposable) {
//         mDisposables.add(disposable);
//     }
// 
// }
// 
// Path: presentation/src/main/java/eu/rampsoftware/er/viewmodel/BaseViewModel.java
// public interface BaseViewModel {
//     /**
//      * Invoked when view is initialized and is ready to display the data exposed by view model.
//      * @param bundle additional to be passed to the viewmodel.
//      */
//     void onLoad(final Bundle bundle);
// 
//     void dispose();
// }


// Path: presentation/src/main/java/eu/rampsoftware/er/viewmodel/currencies/CurrencyListViewModel.java
import android.databinding.Bindable;
import android.databinding.ObservableArrayList;
import android.databinding.ObservableList;
import android.os.Bundle;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import eu.rampsoftware.er.BR;
import eu.rampsoftware.er.data.CurrencyData;
import eu.rampsoftware.er.domain.usecases.GetCurrenciesRatesDate;
import eu.rampsoftware.er.domain.usecases.GetCurrenciesUseCase;
import eu.rampsoftware.er.navigation.Navigator;
import eu.rampsoftware.er.viewmodel.BaseDisposableViewModel;
import eu.rampsoftware.er.viewmodel.BaseViewModel;
import static com.fernandocejas.arrow.checks.Preconditions.checkNotNull;

        notifyPropertyChanged(BR.progressVisible);
    }

    @Bindable
    public ObservableList<CurrencyItemViewModel> getCurrencies() {
        return mCurrencies;
    }

    @Override
    public void onLoad(final Bundle bundle) {
        setProgressVisible(true);
        addDisposable(
                mGetCurrenciesRatesDate.run()
                        .doOnError(throwable -> setProgressVisible(false))
                        .subscribe(dateOptional -> {
                            mReadDate = dateOptional.or(mReadDate);
                            onDate(mReadDate);
                        })
        );
    }

    private void onDate(final Date date) {
        addDisposable(
                mCurrenciesUseCase.run(new GetCurrenciesUseCase.CurrenciesParam(date))
                        .doFinally(() -> setProgressVisible(false))
                        .subscribe(this::onCurrencyDataLoaded)
        );

    }

    private void onCurrencyDataLoaded(final CurrencyData currencyData) {