@Override
  public JsonObject visit(UpdateOperation operation) throws Throwable {
    MobileServiceJsonTable table = this.getRemoteTable(operation.getTableName());
    table.setSystemProperties(getSystemProperties(this.mItem));

    ListenableFuture<JsonObject> future = table.update(this.mItem);

    try {
      return future.get();
    } catch (ExecutionException ex) {
      throw ex.getCause();
    }
  }
  @Override
  public JsonObject visit(InsertOperation operation) throws Throwable {
    MobileServiceJsonTable table = this.getRemoteTable(operation.getTableName());
    table.setSystemProperties(EnumSet.allOf(MobileServiceSystemProperty.class));

    JsonObject item = removeSystemProperties(this.mItem);

    ListenableFuture<JsonObject> future = table.insert(item);

    try {
      return future.get();
    } catch (ExecutionException ex) {
      throw ex.getCause();
    }
  }
  @Override
  public JsonObject visit(DeleteOperation operation) throws Throwable {
    MobileServiceJsonTable table = this.getRemoteTable(operation.getTableName());
    ListenableFuture<Void> future = table.delete(this.mItem);

    try {
      future.get();

      return null;
    } catch (ExecutionException ex) {

      if (!ExceptionIs404NotFound(ex)) {
        throw ex.getCause();
      }

      return null;
    }
  }
 /**
  * Returns an instance of a remote table to be used by this processor
  *
  * @param tableName the name of the remote table
  * @return an instance of a remote table with the given name
  */
 private MobileServiceJsonTable getRemoteTable(String tableName) {
   MobileServiceJsonTable table = this.mClient.getTable(tableName);
   table.addFeature(MobileServiceFeatures.Offline);
   return table;
 }