/**
   * Creates a wrapper that executes this class' run method, sets {@link #current} and subsequently
   * removes it from the list of pending tasks and shows a {@link ProgressThreadDialog} if
   * necessary. As a side effect, calling this method also results in adding this ProgressThread to
   * the list of pending tasks.
   */
  private Runnable makeWrapper() {
    // show dialog if wanted
    if (runInForeground) {
      SwingUtilities.invokeLater(
          new Runnable() {

            @Override
            public void run() {
              if (!ProgressThreadDialog.getInstance().isVisible()) {
                ProgressThreadDialog.getInstance().setVisible(false, true);
              }
            };
          });
    }

    synchronized (LOCK) {
      currentThreads.add(ProgressThread.this);
    }
    taskStarted(this);
    return new Runnable() {

      @Override
      public void run() {
        synchronized (LOCK) {
          if (cancelled) {
            LogService.getRoot()
                .log(
                    Level.INFO,
                    "com.rapidminer.gui.tools.ProgressThread.task_cancelled",
                    getName());
            return;
          }
          started = true;
        }
        final Timer showProgressTimer = new Timer("show-pg-timer", true);
        final TimerTask showProgressTask =
            new TimerTask() {

              @Override
              public void run() {
                SwingUtilities.invokeLater(
                    new Runnable() {

                      @Override
                      public void run() {
                        runInForeground = true;
                        if (!ProgressThreadDialog.getInstance().isVisible()) {
                          ProgressThreadDialog.getInstance().setVisible(false, true);
                        }
                      };
                    });
              }
            };
        if (!isRunInForegroundFlagSet() && isStartDialogShowTimer()) {
          showProgressTimer.schedule(showProgressTask, getShowDialogTimerDelay());
        }
        try {
          ActionStatisticsCollector.getInstance()
              .startTimer(ActionStatisticsCollector.TYPE_PROGRESS_THREAD, key, "runtime");
          ActionStatisticsCollector.getInstance()
              .log(ActionStatisticsCollector.TYPE_PROGRESS_THREAD, key, "started");
          ProgressThread.this.run();
          showProgressTimer.cancel();
          ActionStatisticsCollector.getInstance()
              .log(ActionStatisticsCollector.TYPE_PROGRESS_THREAD, key, "completed");
        } catch (ProgressThreadStoppedException e) {
          showProgressTimer.cancel();
          ActionStatisticsCollector.getInstance()
              .log(ActionStatisticsCollector.TYPE_PROGRESS_THREAD, key, "stopped");
          LogService.getRoot()
              .log(
                  Level.FINE,
                  "com.rapidminer.gui.tools.ProgressThread.progress_thread_aborted",
                  getName());
        } catch (Exception e) {
          showProgressTimer.cancel();
          ActionStatisticsCollector.getInstance()
              .log(ActionStatisticsCollector.TYPE_PROGRESS_THREAD, key, "failed");
          LogService.getRoot()
              .log(
                  Level.WARNING,
                  I18N.getMessage(
                      LogService.getRoot().getResourceBundle(),
                      "com.rapidminer.gui.tools.ProgressThread.error_executing_background_job",
                      name,
                      e),
                  e);

          SwingTools.showSimpleErrorMessage("error_executing_background_job", e, name, e);
        } finally {
          ActionStatisticsCollector.getInstance()
              .stopTimer(ActionStatisticsCollector.TYPE_PROGRESS_THREAD, key, "runtime");
          if (!ProgressThread.this.isCancelled()) {
            ProgressThread.this.getProgressListener().complete();
          }
          synchronized (LOCK) {
            currentThreads.remove(ProgressThread.this);
          }
          for (ProgressThreadListener listener : listeners) {
            listener.threadFinished(ProgressThread.this);
          }
          checkQueueForDependenciesAndExecuteUnblockedTasks();
          taskFinished(ProgressThread.this);
        }
      }
    };
  }