/**
   * Executes the task with the specified parameters. The task returns itself (this) so that the
   * caller can keep a reference to it.
   *
   * <p>This method is typically used with {@link #THREAD_POOL_EXECUTOR} to allow multiple tasks to
   * run in parallel on a pool of threads managed by AsyncTask, however you can also use your own
   * {@link Executor} for custom behavior.
   *
   * <p><em>Warning:</em> Allowing multiple tasks to run in parallel from a thread pool is generally
   * <em>not</em> what one wants, because the order of their operation is not defined. For example,
   * if these tasks are used to modify any state in common (such as writing a file due to a button
   * click), there are no guarantees on the order of the modifications. Without careful work it is
   * possible in rare cases for the newer version of the data to be over-written by an older one,
   * leading to obscure data loss and stability issues.
   *
   * <p>This method must be invoked on the UI thread.
   *
   * @param exec The executor to use. {@link #THREAD_POOL_EXECUTOR} is available as a convenient
   *     process-wide thread pool for tasks that are loosely coupled.
   * @param params The parameters of the task.
   * @return This instance of AsyncTask.
   * @throws IllegalStateException If {@link #getStatus()} returns either {@link
   *     android.os.AsyncTask.Status#RUNNING} or {@link android.os.AsyncTask.Status#FINISHED}.
   */
  @DSGenerator(
      tool_name = "Doppelganger",
      tool_version = "2.0",
      generated_on = "2013-12-30 12:30:27.866 -0500",
      hash_original_method = "2D658F6D3BDE5104FE23D8DBAC134A95",
      hash_generated_method = "D7A7EF08D4CC189B5BB96678F7C7E5D6")
  @DSSafe(DSCat.SAFE_LIST)
  public final ModernAsyncTask<Params, Progress, Result> executeOnExecutor(
      Executor exec, Params... params) {
    if (mStatus != Status.PENDING) {
      switch (mStatus) {
        case RUNNING:
          throw new IllegalStateException("Cannot execute task:" + " the task is already running.");
        case FINISHED:
          throw new IllegalStateException(
              "Cannot execute task:"
                  + " the task has already been executed "
                  + "(a task can be executed only once)");
      }
    }

    mStatus = Status.RUNNING;

    onPreExecute();

    mWorker.mParams = params;
    exec.execute(mFuture);

    return this;
  }