// 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: databoundary/src/main/java/eu/rampsoftware/er/data/CurrencyRepository.java
// public interface CurrencyRepository {
// 
//     Observable<CurrencyData> getCurrencies(final Date date);
// 
//     Observable<SingleValue> getSeries(Date from, Date to, String currencyCode);
// }
// 
// Path: databoundary/src/main/java/eu/rampsoftware/er/data/SingleValue.java
// public class SingleValue {
//     private Date mDate;
//     private double mValue;
// 
//     public SingleValue(final Date date, final double value) {
//         mDate = date;
//         mValue = value;
//     }
// 
//     public Date getDate() {
//         return mDate;
//     }
// 
//     public double getValue() {
//         return mValue;
//     }
// 
//     @Override
//     public String toString() {
//         return "SingleValue{" +
//                 "mDate=" + mDate +
//                 ", mValue=" + mValue +
//                 '}';
//     }
// }
// 
// Path: data/src/main/java/eu/rampsoftware/er/data/datasource/CurrencyDataSource.java
// public interface CurrencyDataSource {
// 
//     Observable<CurrencyData> getCurrencies(Date date);
// 
//     boolean containsCurrencyValue(Date date, String currencyCode);
// 
//     boolean containsCurrencyValues(Date date);
// 
//     Observable<SingleValue> getCurrencyValues(Date startDate, Date endDate, String currencyCode);
// 
//     void storeCurrencies(CurrencyData currencyData);
// }


import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import eu.rampsoftware.er.data.CurrencyData;
import eu.rampsoftware.er.data.CurrencyRepository;
import eu.rampsoftware.er.data.SingleValue;
import eu.rampsoftware.er.data.datasource.CurrencyDataSource;
import io.reactivex.Observable;
import io.reactivex.schedulers.Schedulers;
package eu.rampsoftware.er.data.repository;



public class CachingCurrencyRepository implements CurrencyRepository {
    private CurrencyDataSource mLocalSource;
    private CurrencyDataSource mRemoteSource;

    public CachingCurrencyRepository(final CurrencyDataSource localSource,
                                     final CurrencyDataSource remoteSource) {
        mLocalSource = localSource;
        mRemoteSource = remoteSource;
    }

    @Override
    public Observable<CurrencyData> getCurrencies(final Date date) {
        if (mLocalSource.containsCurrencyValues(date)) {
            return mLocalSource.getCurrencies(date);
        }
        final Observable<CurrencyData> remoteCurrencies = mRemoteSource.getCurrencies(date);
        remoteCurrencies.doOnNext(currencyData -> mLocalSource.storeCurrencies(currencyData));
        return remoteCurrencies;
    }

    @Override
// 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: databoundary/src/main/java/eu/rampsoftware/er/data/CurrencyRepository.java
// public interface CurrencyRepository {
// 
//     Observable<CurrencyData> getCurrencies(final Date date);
// 
//     Observable<SingleValue> getSeries(Date from, Date to, String currencyCode);
// }
// 
// Path: databoundary/src/main/java/eu/rampsoftware/er/data/SingleValue.java
// public class SingleValue {
//     private Date mDate;
//     private double mValue;
// 
//     public SingleValue(final Date date, final double value) {
//         mDate = date;
//         mValue = value;
//     }
// 
//     public Date getDate() {
//         return mDate;
//     }
// 
//     public double getValue() {
//         return mValue;
//     }
// 
//     @Override
//     public String toString() {
//         return "SingleValue{" +
//                 "mDate=" + mDate +
//                 ", mValue=" + mValue +
//                 '}';
//     }
// }
// 
// Path: data/src/main/java/eu/rampsoftware/er/data/datasource/CurrencyDataSource.java
// public interface CurrencyDataSource {
// 
//     Observable<CurrencyData> getCurrencies(Date date);
// 
//     boolean containsCurrencyValue(Date date, String currencyCode);
// 
//     boolean containsCurrencyValues(Date date);
// 
//     Observable<SingleValue> getCurrencyValues(Date startDate, Date endDate, String currencyCode);
// 
//     void storeCurrencies(CurrencyData currencyData);
// }


// Path: data/src/main/java/eu/rampsoftware/er/data/repository/CachingCurrencyRepository.java
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import eu.rampsoftware.er.data.CurrencyData;
import eu.rampsoftware.er.data.CurrencyRepository;
import eu.rampsoftware.er.data.SingleValue;
import eu.rampsoftware.er.data.datasource.CurrencyDataSource;
import io.reactivex.Observable;
import io.reactivex.schedulers.Schedulers;

package eu.rampsoftware.er.data.repository;



public class CachingCurrencyRepository implements CurrencyRepository {
    private CurrencyDataSource mLocalSource;
    private CurrencyDataSource mRemoteSource;

    public CachingCurrencyRepository(final CurrencyDataSource localSource,
                                     final CurrencyDataSource remoteSource) {
        mLocalSource = localSource;
        mRemoteSource = remoteSource;
    }

    @Override
    public Observable<CurrencyData> getCurrencies(final Date date) {
        if (mLocalSource.containsCurrencyValues(date)) {
            return mLocalSource.getCurrencies(date);
        }
        final Observable<CurrencyData> remoteCurrencies = mRemoteSource.getCurrencies(date);
        remoteCurrencies.doOnNext(currencyData -> mLocalSource.storeCurrencies(currencyData));
        return remoteCurrencies;
    }

    @Override
    public Observable<SingleValue> getSeries(final Date from, final Date to, final String currencyCode) {