@Override
  public Observable<List<TMWRule>> loadRemoteRules() {
    return ruleApi
        .getAllRules(new DbSearch(Storage.loadUserId()))
        .subscribeOn(Schedulers.io())
        .map(
            new Func1<DbDocuments<DbRule>, List<TMWRule>>() {
              @Override
              public List<TMWRule> call(DbDocuments<DbRule> docs) {
                new Delete().from(TMWRule.class).execute();

                ActiveAndroid.beginTransaction();
                try {
                  for (DbRule dbRule : docs.getDocuments()) {
                    checkGcmNotification(dbRule);

                    TMWRule rule = DataMapper.toRule(dbRule);
                    rule.save();
                  }
                  ActiveAndroid.setTransactionSuccessful();
                } finally {
                  ActiveAndroid.endTransaction();
                }

                return new Select().from(TMWRule.class).execute();
              }
            });
  }
 @Override
 public Observable<Boolean> createRule(final TMWRule rule) {
   return ruleApi
       .createRule(DataMapper.toDbRule(rule))
       .subscribeOn(Schedulers.io())
       .map(
           new Func1<DbStatus, Boolean>() {
             @Override
             public Boolean call(DbStatus status) {
               return status.getOk().toLowerCase().equals("true");
             }
           });
 }
  @Override
  public Observable<Boolean> deleteRule(final String id, String revId) {
    return ruleApi
        .deleteRule(id, revId)
        .subscribeOn(Schedulers.io())
        .map(
            new Func1<DbStatus, Boolean>() {
              @Override
              public Boolean call(DbStatus dbStatus) {
                boolean status = dbStatus.getOk().toLowerCase().equals("true");
                if (status)
                  new Delete().from(TMWNotification.class).where("ruleId = ?", id).execute();

                return status;
              }
            });
  }
  @Override
  public Observable<Boolean> updateRule(final TMWRule rule) {
    return ruleApi
        .updateRule(rule.dbId, rule.drRev, DataMapper.toDbRule(rule))
        .subscribeOn(Schedulers.io())
        .map(
            new Func1<DbStatus, Boolean>() {
              @Override
              public Boolean call(DbStatus dbStatus) {
                boolean status = dbStatus.getOk().toLowerCase().equals("true");

                if (status) {
                  rule.drRev = dbStatus.getRev();
                  rule.save();
                }

                return status;
              }
            });
  }
  private void updateRuleNotifications(final DbRule rule) {
    ruleApi
        .updateRule(rule.getId(), rule.getRev(), rule)
        .subscribeOn(Schedulers.io())
        .subscribe(
            new Subscriber<DbStatus>() {
              @Override
              public void onCompleted() {}

              @Override
              public void onError(Throwable e) {
                Log.d("RuleService", "Problem updating the rule");
              }

              @Override
              public void onNext(DbStatus dbStatus) {
                Log.d("RuleService", "Updated rule: " + rule.getDetails().getName());
              }
            });
  }
  @Override
  public Observable<Boolean> refreshRule(final String ruleId) {
    return ruleApi
        .getAllRules(new DbSearch(Storage.loadUserId()))
        .subscribeOn(Schedulers.io())
        .map(
            new Func1<DbDocuments<DbRule>, Boolean>() {
              @Override
              public Boolean call(DbDocuments<DbRule> docs) {
                for (DbRule dbRule : docs.getDocuments()) {
                  if (dbRule.getId().equals(ruleId)) {
                    new Delete().from(TMWRule.class).where("dbId = ?", ruleId).execute();

                    TMWRule rule = DataMapper.toRule(dbRule);
                    rule.save();
                    Storage.prepareRuleForEdit(rule);
                    return true;
                  }
                }

                return false;
              }
            });
  }