// Path: app/src/main/java/com/lucilu/rxdynamicsearch/utils/Preconditions.java
// @NonNull
// public static <T> T get(@Nullable final T reference) {
//     if (reference == null) {
//         throw new NullPointerException("Assertion for a nonnull object failed.");
//     }
//     return reference;
// }


import android.support.annotation.NonNull;
import java.util.concurrent.TimeUnit;
import rx.Observable;
import rx.schedulers.Schedulers;
import rx.subjects.PublishSubject;
import static com.lucilu.rxdynamicsearch.Constants.DYNAMIC_SEARCH_DELAY_MILLIS;
import static com.lucilu.rxdynamicsearch.Constants.EMPTY_QUERY;
import static com.lucilu.rxdynamicsearch.utils.Preconditions.get;
package com.lucilu.rxdynamicsearch.service;





public class SearchService {

    private final PublishSubject<String> dynamicQueryStream = PublishSubject.create();
    private final PublishSubject<String> submittedQueryStream = PublishSubject.create();
    private final Observable<String> searchQueryStream;

    public SearchService() {
        searchQueryStream = defineSearchQueryStream();
    }

    private Observable<String> defineSearchQueryStream() {
        return Observable
                .merge(defineDynamicQueryStream(), defineSubmittedQueryStream())
                .map(String::trim)
                .startWith(EMPTY_QUERY)
                .distinctUntilChanged();
    }

    private Observable<String> defineDynamicQueryStream() {
        return dynamicQueryStream
                .debounce(DYNAMIC_SEARCH_DELAY_MILLIS,
                          TimeUnit.MILLISECONDS,
                          Schedulers.computation());
    }

    private Observable<String> defineSubmittedQueryStream() {
        return submittedQueryStream;
    }

    public void queryTextChanged(@NonNull final String query) {
// Path: app/src/main/java/com/lucilu/rxdynamicsearch/utils/Preconditions.java
// @NonNull
// public static <T> T get(@Nullable final T reference) {
//     if (reference == null) {
//         throw new NullPointerException("Assertion for a nonnull object failed.");
//     }
//     return reference;
// }


// Path: app/src/main/java/com/lucilu/rxdynamicsearch/service/SearchService.java
import android.support.annotation.NonNull;
import java.util.concurrent.TimeUnit;
import rx.Observable;
import rx.schedulers.Schedulers;
import rx.subjects.PublishSubject;
import static com.lucilu.rxdynamicsearch.Constants.DYNAMIC_SEARCH_DELAY_MILLIS;
import static com.lucilu.rxdynamicsearch.Constants.EMPTY_QUERY;
import static com.lucilu.rxdynamicsearch.utils.Preconditions.get;

package com.lucilu.rxdynamicsearch.service;





public class SearchService {

    private final PublishSubject<String> dynamicQueryStream = PublishSubject.create();
    private final PublishSubject<String> submittedQueryStream = PublishSubject.create();
    private final Observable<String> searchQueryStream;

    public SearchService() {
        searchQueryStream = defineSearchQueryStream();
    }

    private Observable<String> defineSearchQueryStream() {
        return Observable
                .merge(defineDynamicQueryStream(), defineSubmittedQueryStream())
                .map(String::trim)
                .startWith(EMPTY_QUERY)
                .distinctUntilChanged();
    }

    private Observable<String> defineDynamicQueryStream() {
        return dynamicQueryStream
                .debounce(DYNAMIC_SEARCH_DELAY_MILLIS,
                          TimeUnit.MILLISECONDS,
                          Schedulers.computation());
    }

    private Observable<String> defineSubmittedQueryStream() {
        return submittedQueryStream;
    }

    public void queryTextChanged(@NonNull final String query) {
        dynamicQueryStream.onNext(get(query));