package aashrai.android.gettowork.model;

import aashrai.android.gettowork.di.SettingsScope;
import aashrai.android.gettowork.utils.Utils;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import java.util.List;
import javax.inject.Inject;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

@SettingsScope public class ApplicationInfoFetcher {

  private final Context context;

  @Inject public ApplicationInfoFetcher(Context context) {
    this.context = context;
  }

  public Observable<List<ApplicationInfo>> getAllApplications() {
    return Utils.getAllApplications(context);
  }

  public Observable<List<ApplicationInfo>> getFilteredApplications(
      List<ApplicationInfo> applicationInfoList, String query) {
    return Observable.from(applicationInfoList)
        .observeOn(Schedulers.computation())
        .filter(new PackageQueryFilter(context, query))
        .toList()
        .observeOn(AndroidSchedulers.mainThread());
  }

  private static class PackageQueryFilter implements Func1<ApplicationInfo, Boolean> {
    private final Context context;
    private final String query;

    private PackageQueryFilter(Context context, String query) {
      this.query = query.toLowerCase().trim();
      this.context = context;
    }

    @Override public Boolean call(ApplicationInfo applicationInfo) {
      return query.isEmpty() || Utils.getApplicationName(applicationInfo, context).contains(query);
    }
  }
}

@@ -207,16 +207,117 @@
 onInfo;%0A
+import android.content.pm.PackageManager;%0Aimport com.fernandocejas.frodo.annotation.RxLogObservable;%0A
 import j
@@ -664,32 +664,49 @@
 context;%0A  %7D%0A%0A  
+@RxLogObservable 
 public Observabl
@@ -768,181 +768,762 @@
 urn 
-Utils.getAllApplications(context);%0A  %7D%0A%0A  public Observable%3CList%3CApplicationInfo%3E%3E getFilteredApplications(%0A      List%3CApplicationInfo%3E applicationInfoList, String query) %7B%0A
+Observable.from(%0A        context.getPackageManager().getInstalledApplications(PackageManager.GET_META_DATA))%0A        .observeOn(Schedulers.computation())%0A        .filter(Utils.removeSelfPackage(context))%0A        .filter(Utils.removeLaunchers(context))%0A        .filter(Utils.removeSystemApps())%0A        .toSortedList(Utils.getApplicationSortFunction(context))%0A        .observeOn(AndroidSchedulers.mainThread())%0A        .cache();%0A  %7D%0A%0A  public Observable%3CList%3CApplicationInfo%3E%3E getFilteredApplications(String query) %7B%0A    return getAllApplications().flatMap(%0A        new Func1%3CList%3CApplicationInfo%3E, Observable%3CApplicationInfo%3E%3E() %7B%0A          @Override%0A          public Observable%3CApplicationInfo%3E call(List%3CApplicationInfo%3E applicationInfoList) %7B%0A        
     
@@ -1565,16 +1565,40 @@
 nfoList)
+;%0A          %7D%0A        %7D)
 %0A       

Load filtered applications from cached observable