package com.filestack.model;

import com.filestack.model.transform.base.ImageTransform;
import com.filestack.util.Upload;
import com.filestack.util.UploadOptions;

import java.io.IOException;

/**
 * Wrapper for communicating with the Filestack REST API.
 * Instantiate with an API Key from the Developer Portal.
 */
public class FilestackClient {
  private String apiKey;
  private Security security;

  /**
   * Constructs an instance without security.
   *
   * @param apiKey account key from the dev portal
   */
  public FilestackClient(String apiKey) {
    this.apiKey = apiKey;
  }

  /**
   * Constructs an instance with security.
   *
   * @param apiKey   account key from the dev portal
   * @param security needs required permissions for your intended actions
   */
  public FilestackClient(String apiKey, Security security) {
    this.apiKey = apiKey;
    this.security = security;
  }

  /**
   * Upload local file to Filestack using default storage options.
   *
   * @param filepath path to the file, can be local or absolute
   * @return new {@link FileLink} referencing file
   * @throws IOException for network failures or invalid security
   */
  public FileLink upload(String filepath) throws IOException {
    UploadOptions defaultOptions = new UploadOptions.Builder().build();
    return upload(filepath, defaultOptions);
  }

  /**
   * Upload local file to Filestack using custom storage options.
   *
   * @param filepath path to the file, can be local or absolute
   * @param options storage options, https://www.filestack.com/docs/rest-api/store
   * @return new {@link FileLink} referencing file
   * @throws IOException or network failures or invalid security
   */
  public FileLink upload(String filepath, UploadOptions options) throws IOException {
    Upload upload = new Upload(filepath, this, options);
    return upload.run();
  }

  /**
   * Creates an image transformation object for this file.
   * A transformation call isn't made directly by this method.
   *
   * @return {@link ImageTransform ImageTransform} instance configured for this file
   */
  public ImageTransform imageTransform(String url) {
    return new ImageTransform(this, url);
  }

  public String getApiKey() {
    return apiKey;
  }

  public Security getSecurity() {
    return security;
  }
}

@@ -168,27 +168,137 @@
 ort 
-java.io.IOException
+io.reactivex.Single;%0Aimport io.reactivex.schedulers.Schedulers;%0A%0Aimport java.io.IOException;%0Aimport java.util.concurrent.Callable
 ;%0A%0A/
@@ -1963,32 +1963,816 @@
 oad.run();%0A  %7D%0A%0A
+  // Async method wrappers%0A%0A  /**%0A   * Async, observable version of %7B@link #upload(String)%7D.%0A   * Throws same exceptions.%0A   */%0A  public Single%3CFileLink%3E uploadAsync(String filepath) %7B%0A    UploadOptions defaultOptions = new UploadOptions.Builder().build();%0A    return uploadAsync(filepath, defaultOptions);%0A  %7D%0A%0A  /**%0A   * Async, observable version of %7B@link #upload(String, UploadOptions)%7D.%0A   * Throws same exceptions.%0A   */%0A  public Single%3CFileLink%3E uploadAsync(final String filepath, final UploadOptions options) %7B%0A    return Single.fromCallable(new Callable%3CFileLink%3E() %7B%0A      @Override%0A      public FileLink call() throws IOException %7B%0A        return upload(filepath, options);%0A      %7D%0A    %7D)%0A        .subscribeOn(Schedulers.io())%0A        .observeOn(Schedulers.single());%0A  %7D%0A%0A
   /**%0A   * Creat

Add async methods to FilestackClient