@Override
 public boolean isCanceled() {
   if (super.isCanceled()) {
     return true;
   }
   if (job.shouldReschedule() && job.isBlocking()) {
     if (blockTime == 0) {
       blockTime = System.currentTimeMillis();
     } else if (System.currentTimeMillis() - blockTime > THRESHOLD) {
       // We've been blocking for too long
       wasBlocking = true;
       return true;
     }
   } else {
     blockTime = 0;
   }
   wasBlocking = false;
   return false;
 }
  /**
   * This is run by the job scheduler. A list of subscribers will be refreshed, errors will not stop
   * the job and it will continue to refresh the other subscribers.
   */
  @Override
  public IStatus run(IProgressMonitor monitor) {
    // Perform a pre-check for auto-build or manual build jobs
    // when auto-refreshing
    if (shouldReschedule()
        && (isJobInFamilyRunning(ResourcesPlugin.FAMILY_AUTO_BUILD)
            || isJobInFamilyRunning(ResourcesPlugin.FAMILY_MANUAL_BUILD))) {
      return POSTPONED;
    }
    // Only allow one refresh job at a time
    // NOTE: It would be cleaner if this was done by a scheduling
    // rule but at the time of writing, it is not possible due to
    // the scheduling rule containment rules.
    // Acquiring lock to ensure only one refresh job is running at a particular time
    boolean acquired = false;
    try {
      while (!acquired) {
        try {
          acquired = lock.acquire(1000);
        } catch (InterruptedException e1) {
          acquired = false;
        }
        Policy.checkCanceled(monitor);
      }

      IChangeDescription changeDescription = createChangeDescription();
      RefreshEvent event =
          new RefreshEvent(
              reschedule ? IRefreshEvent.SCHEDULED_REFRESH : IRefreshEvent.USER_REFRESH,
              participant,
              changeDescription);
      IStatus status = null;
      NonblockingProgressMonitor wrappedMonitor = null;
      try {
        event.setStartTime(System.currentTimeMillis());
        if (monitor.isCanceled()) {
          return Status.CANCEL_STATUS;
        }
        // Pre-Notify
        notifyListeners(STARTED, event);
        // Perform the refresh
        monitor.setTaskName(getName());
        wrappedMonitor = new NonblockingProgressMonitor(monitor, this);
        doRefresh(changeDescription, wrappedMonitor);
        // Prepare the results
        setProperty(IProgressConstants.KEEPONE_PROPERTY, Boolean.valueOf(!isJobModal()));
      } catch (OperationCanceledException e2) {
        if (monitor.isCanceled()) {
          // The refresh was canceled by the user
          status = Status.CANCEL_STATUS;
        } else {
          // The refresh was canceled due to a blockage or a canceled authentication
          if (wrappedMonitor != null && wrappedMonitor.wasBlocking()) {
            status = POSTPONED;
          } else {
            status = Status.CANCEL_STATUS;
          }
        }
      } catch (CoreException e) {
        // Determine the status to be returned and the GOTO action
        status = e.getStatus();
        if (!isUser()) {
          // Use the GOTO action to show the error and return OK
          Object prop = getProperty(IProgressConstants.ACTION_PROPERTY);
          if (prop instanceof GotoActionWrapper) {
            GotoActionWrapper wrapper = (GotoActionWrapper) prop;
            wrapper.setStatus(e.getStatus());
            status =
                new Status(IStatus.OK, TeamUIPlugin.ID, IStatus.OK, e.getStatus().getMessage(), e);
          }
        }
        if (!isUser() && status.getSeverity() == IStatus.ERROR) {
          // Never prompt for errors on non-user jobs
          setProperty(IProgressConstants.NO_IMMEDIATE_ERROR_PROMPT_PROPERTY, Boolean.TRUE);
        }
      } finally {
        event.setStopTime(System.currentTimeMillis());
      }

      // Post-Notify
      if (status == null) {
        status = calculateStatus(event);
      }
      event.setStatus(status);
      notifyListeners(DONE, event);
      if (event.getChangeDescription().getChangeCount() > 0) {
        if (participant instanceof AbstractSynchronizeParticipant) {
          AbstractSynchronizeParticipant asp = (AbstractSynchronizeParticipant) participant;
          asp.firePropertyChange(
              participant, ISynchronizeParticipant.P_CONTENT, null, event.getChangeDescription());
        }
      }
      return event.getStatus();
    } finally {
      if (acquired) lock.release();
      monitor.done();
    }
  }