private boolean isDeletedRemotely(SyncInfo info) {
   int kind = info.getKind();
   if (kind == (SyncInfo.INCOMING | SyncInfo.DELETION)) return true;
   if (SyncInfo.getDirection(kind) == SyncInfo.CONFLICTING && info.getRemote() == null)
     return true;
   return false;
 }
  /** {@inheritDoc} */
  public boolean accept(Object element) {
    boolean passes = true;

    if (element instanceof IFile) {

      IFile file = (IFile) element;
      IProject project = file.getProject();

      if (RepositoryProvider.isShared(project)) {

        RepositoryProvider provider = RepositoryProvider.getProvider(project);

        if (provider != null) {

          Subscriber subscriber = provider.getSubscriber();

          if (subscriber != null) {

            try {
              SyncInfo synchInfo = subscriber.getSyncInfo(file);

              if (synchInfo != null) {
                int kind = synchInfo.getKind();
                passes = (SyncInfo.getDirection(kind) & SyncInfo.OUTGOING) == SyncInfo.OUTGOING;
              }
            } catch (TeamException e) {
              CheckstyleLog.log(e);
            }
          }
        }
      }
    }
    return passes;
  }
 /*
  * Add the remote change to an incoming commit set
  */
 private void addRemoteChange(
     SyncInfo info, ICVSRemoteResource remoteResource, ILogEntry logEntry) {
   if (disposed) return;
   LogEntryCacheUpdateHandler handler = getLogEntryHandler();
   if (handler != null
       && remoteResource != null
       && logEntry != null
       && handler.isRemoteChange(info)) {
     if (requiresCustomSyncInfo(info, remoteResource, logEntry)) {
       info =
           new CVSUpdatableSyncInfo(
               info.getKind(),
               info.getLocal(),
               info.getBase(),
               (RemoteResource) logEntry.getRemoteFile(),
               ((CVSSyncInfo) info).getSubscriber());
       try {
         info.init();
       } catch (TeamException e) {
         // this shouldn't happen, we've provided our own calculate kind
       }
     }
     // Only add the info if the base and remote differ
     IResourceVariant base = info.getBase();
     IResourceVariant remote = info.getRemote();
     if ((base == null && remote != null)
         || (remote == null && base != null)
         || (remote != null && base != null && !base.equals(remote))) {
       synchronized (this) {
         CheckedInChangeSet set = getChangeSetFor(logEntry);
         if (set == null) {
           set = createChangeSetFor(logEntry);
           add(set);
         }
         set.add(info);
       }
     }
   } else {
     // The info was not retrieved for the remote change for some reason.
     // Add the node to the root
     addToDefaultSet(DEFAULT_INCOMING_SET_NAME, info);
   }
 }
  @Override
  public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
    final SyncInfo[] infos = getSyncInfoSet().getSyncInfos();
    if (Utils.isEmpty(infos)) {
      return;
    }

    for (SyncInfo syncInfo : infos) {
      if (SyncInfo.getDirection(syncInfo.getKind()) == SyncInfo.INCOMING) {
        logger.warn("Request to apply incoming change to remote");
        StringBuffer strBuff = new StringBuffer("Change is ");
        strBuff
            .append(getDirectionString(syncInfo))
            .append(".\n\nAre you sure you want to override ")
            .append(getDirectionString(syncInfo))
            .append(" ")
            .append(getDeltaString(syncInfo))
            .append(" and apply local ")
            .append(getReverseDeltaString(syncInfo))
            .append(" to server?");
        ConfirmRunnable confirm = new ConfirmRunnable("Incoming Change Found", strBuff.toString());
        Display.getDefault().syncExec(confirm);
        if (!confirm.getResult()) {
          return;
        }
      }
    }

    try {
      applyToServer(getSubscriber(), infos, monitor);
    } catch (InterruptedException e) {
      logger.warn("Operation cancelled: " + e.getMessage());
    } catch (InvocationTargetException e) {
      Throwable cause = e.getTargetException();
      if (cause instanceof InsufficientPermissionsException) {
        DialogUtils.getInstance()
            .presentInsufficientPermissionsDialog((InsufficientPermissionsException) cause);
      } else {
        logger.error("Unable to apply change to server", e);
        showErrorAsync(e, true, "Unable to apply change to server");
      }
    }
  }
  private void prepareChangeLog(IProgressMonitor monitor) {

    Object element = selected.getFirstElement();

    IResource resource = null;
    Vector<PatchFile> newList = new Vector<PatchFile>();
    Vector<PatchFile> removeList = new Vector<PatchFile>();
    Vector<PatchFile> changeList = new Vector<PatchFile>();
    int totalChanges = 0;

    if (element instanceof IResource) {
      resource = (IResource) element;
    } else if (element instanceof ISynchronizeModelElement) {
      ISynchronizeModelElement sme = (ISynchronizeModelElement) element;
      resource = sme.getResource();
    } else if (element instanceof IAdaptable) {
      resource = (IResource) ((IAdaptable) element).getAdapter(IResource.class);
    }

    if (resource == null) return;

    IProject project = resource.getProject();
    // Get the repository provider so we can support multiple types of
    // code repositories without knowing exactly which (e.g. CVS, SVN, etc..).
    RepositoryProvider r = RepositoryProvider.getProvider(project);
    if (r == null) return;
    SyncInfoSet set = new SyncInfoSet();
    Subscriber s = r.getSubscriber();
    if (s == null) return;
    if (element instanceof ISynchronizeModelElement) {
      // We can extract the ChangeLog list from the synchronize view which
      // allows us to skip items removed from the view
      ISynchronizeModelElement d = (ISynchronizeModelElement) element;
      while (d.getParent() != null) d = (ISynchronizeModelElement) d.getParent();
      extractSynchronizeModelInfo(d, new Path(""), newList, removeList, changeList);
      totalChanges = newList.size() + removeList.size() + changeList.size();
    } else {
      // We can then get a list of all out-of-sync resources.
      s.collectOutOfSync(new IResource[] {project}, IResource.DEPTH_INFINITE, set, monitor);
      SyncInfo[] infos = set.getSyncInfos();
      totalChanges = infos.length;
      // Iterate through the list of changed resources and categorize them into
      // New, Removed, and Changed lists.
      for (SyncInfo info : infos) {
        int kind = SyncInfo.getChange(info.getKind());
        PatchFile p = new PatchFile(info.getLocal());

        // Check the type of entry and sort into lists.  Do not add an entry
        // for ChangeLog files.
        if (!(p.getPath().lastSegment().equals("ChangeLog"))) { // $NON-NLS-1$
          if (kind == SyncInfo.ADDITION) {
            p.setNewfile(true);
            newList.add(p);
          } else if (kind == SyncInfo.DELETION) {
            p.setRemovedFile(true);
            removeList.add(p);
          } else if (kind == SyncInfo.CHANGE) {
            if (info.getLocal().getType() == IResource.FILE) {
              changeList.add(p);
            }
          }
        } else {
          this.changeLogModified = true;
        }
      }
    }

    if (totalChanges == 0) return; // nothing to parse

    PatchFile[] patchFileInfoList = new PatchFile[totalChanges];

    // Group like changes together and sort them by path name.
    // We want removed files, then new files, then changed files.
    // To get this, we put them in the array in reverse order.
    int index = 0;
    if (changeList.size() > 0) {
      // Get the repository provider so we can support multiple types of
      // code repositories without knowing exactly which (e.g. CVS, SVN, etc..).
      Collections.sort(changeList, new PatchFileComparator());
      int size = changeList.size();
      for (int i = 0; i < size; ++i) {
        PatchFile p = changeList.get(i);
        getChangedLines(s, p, monitor);
        patchFileInfoList[index + (size - i - 1)] = p;
      }
      index += size;
    }

    if (newList.size() > 0) {
      Collections.sort(newList, new PatchFileComparator());
      int size = newList.size();
      for (int i = 0; i < size; ++i) patchFileInfoList[index + (size - i - 1)] = newList.get(i);
      index += size;
    }

    if (removeList.size() > 0) {
      Collections.sort(removeList, new PatchFileComparator());
      int size = removeList.size();
      for (int i = 0; i < size; ++i) patchFileInfoList[index + (size - i - 1)] = removeList.get(i);
    }

    // now, find out modified functions/classes.
    // try to use the the extension point. so it can be extended easily
    // for all files in patch file info list, get function guesses of each
    // file.
    monitor.subTask(Messages.getString("ChangeLog.WritingMessage")); // $NON-NLS-1$
    int unitwork = 250 / patchFileInfoList.length;
    for (PatchFile pf : patchFileInfoList) {
      // for each file
      if (pf != null) { // any ChangeLog changes will have null entries for them
        String[] funcGuessList = guessFunctionNames(pf);
        outputMultipleEntryChangeLog(pf, funcGuessList);
      }
      monitor.worked(unitwork);
    }
  }