private void Pause(String description) throws Exception {
   Utilities.Log.Debug(
       "Pausing for "
           + Settings.PAUSE_SECONDS
           + " seconds: "
           + description
           + ". Other threads may be processing these tasks.");
   Thread.currentThread().sleep(Settings.PAUSE_SECONDS * 1000);
   Utilities.Log.Debug("Retrying after pause: " + description + ".");
 }
  // Execute all callable objects and pause if any of them has not completed
  public void ExecuteWithRetries(String description) throws Exception {
    ArrayList results = Lists.CreateBooleanList(false);

    do {
      try {
        // Try to execute the tasks
        results = Execute();

        // If any of the tasks have not yet been executed, pause
        if (Lists.AnyFalse(results)) Pause(description);
      } catch (Exception ex) {
        // Pause after an exception has occurred
        Utilities.Log.Exception(ex);
        Pause(description);
      }
    } while (Lists.AnyFalse(results));
  }
  /**
   * Executes multiple callable objects in a multithreaded fashion
   *
   * @return Objects that are returned from each _callable object
   * @throws Exception
   */
  public ArrayList Execute() throws Exception {
    if (_callables == null || _callables.size() == 0) return new ArrayList();

    Utilities.Log.Debug("Attempting to share execution across " + _numThreads + " threads.");

    ArrayList results = new ArrayList();

    // If only one thread is desired, then there is no need to involve the more complicated thread
    // pool logic
    if (_numThreads == 1) {
      for (Callable callable : _callables) {
        Object result = callable.call();

        if (result != null) results.add(result);
      }

      return results;
    }

    // The logic below enables multi-threaded execution
    ExecutorService service = Executors.newFixedThreadPool(_numThreads);

    ArrayList<Future<Object>> futures = new ArrayList<Future<Object>>();

    for (Callable<Object> callable : _callables) futures.add(service.submit(callable));

    for (Future<Object> future : futures) {
      Object result = future.get(Settings.THREAD_TIMEOUT_MINUTES, TimeUnit.MINUTES);

      if (result != null) results.add(result);
    }

    // Very important to shut down the service
    service.shutdown();

    return results;
  }