@Override
    public void run() {
      final List<Runnable> copy = new ArrayList<>();
      try {
        synchronized (myLock) {
          if (!myRequestSubmitted) return;
          myRequestSubmitted = false;

          LOG.assertTrue(!myRequestRunning);
          myRequestRunning = true;

          if (myStopped) {
            debug("Stopped", this);
            return;
          }

          if (checkLifeCycle() || checkHeavyOperations()) {
            debug("Reschedule", this);
            schedule(); // try again later
            return;
          }

          copy.addAll(myWaitingUpdateCompletionQueue);
          myWaitingUpdateCompletionQueue.clear();
        }

        debug("Before callback", this);
        boolean success = myRefreshDelegate.getAsBoolean(); // CLM.updateImmediately
        debug("After callback, was success: " + success, this);

        if (!success) {
          // Refresh was cancelled, will fire events after the next successful one
          debug("Restoring runnables", this);
          synchronized (myLock) {
            myWaitingUpdateCompletionQueue.addAll(0, copy);
            copy.clear();
          }
        }
      }
      finally {
        synchronized (myLock) {
          debug("Finally", this);
          myRequestRunning = false;

          if (!myWaitingUpdateCompletionQueue.isEmpty() && !myRequestSubmitted && !myStopped) {
            LOG.error("No update task to handle request(s)");
          }
        }
        runWaiters(copy);
        freeSemaphores();
        debug("Runnables executed", this);
      }
    }
@Override
    public void run()