private ProcessingResult processIncomingChange(@NotNull Change change,
                                                   @NotNull IncomingChangeListData changeListData,
                                                   @Nullable Collection<FilePath> incomingFiles) {
      final CommittedChangeList changeList = changeListData.changeList;
      final ContentRevision afterRevision = change.getAfterRevision();
      if (afterRevision != null) {
        if (afterRevision.getFile().isNonLocal()) {
          // don't bother to search for non-local paths on local disk
          return new ProcessingResult(true, AFTER_DOES_NOT_MATTER_NON_LOCAL);
        }
        if (change.getBeforeRevision() == null) {
          final FilePath path = afterRevision.getFile();
          debug("Marking created file " + path);
          myCreatedFiles.add(path);
        }
        else if (change.getBeforeRevision().getFile().getPath().equals(afterRevision.getFile().getPath()) && change.isIsReplaced()) {
          myReplacedFiles.add(afterRevision.getFile());
        }
        if (incomingFiles != null && !incomingFiles.contains(afterRevision.getFile())) {
          debug("Skipping new/changed file outside of incoming files: " + afterRevision.getFile());
          return new ProcessingResult(true, AFTER_DOES_NOT_MATTER_OUTSIDE_INCOMING);
        }
        debug("Checking file " + afterRevision.getFile().getPath());
        FilePath localPath = ChangesUtil.getLocalPath(myProject, afterRevision.getFile());

        if (! FileUtil.isAncestor(myChangesCacheFile.myRootPath.getIOFile(), localPath.getIOFile(), false)) {
          // alien change in list; skip
          debug("Alien path " +
                localPath.getPresentableUrl() +
                " under root " +
                myChangesCacheFile.myRootPath.getPresentableUrl() +
                "; skipping.");
          return new ProcessingResult(true, AFTER_DOES_NOT_MATTER_ALIEN_PATH);
        }

        final VirtualFile file = localPath.getVirtualFile();
        if (isDeletedFile(myDeletedFiles, afterRevision, myReplacedFiles)) {
          debug("Found deleted file");
          return new ProcessingResult(true, AFTER_DOES_NOT_MATTER_DELETED_FOUND_IN_INCOMING_LIST);
        }
        else if (file != null) {
          return new ProcessingResult(file, revision -> {
            if (revision != null) {
              debug("Current revision is " + revision + ", changelist revision is " + afterRevision.getRevisionNumber());
              //noinspection unchecked
              if (myChangesCacheFile.myChangesProvider
                .isChangeLocallyAvailable(afterRevision.getFile(), revision, afterRevision.getRevisionNumber(), changeList)) {
                return new ProcessingResult(true, AFTER_EXISTS_LOCALLY_AVAILABLE);
              }
              return new ProcessingResult(false, AFTER_EXISTS_NOT_LOCALLY_AVAILABLE);
            }
            debug("Failed to fetch revision");
            return new ProcessingResult(false, AFTER_EXISTS_REVISION_NOT_LOADED);
          });
        }
        else {
          //noinspection unchecked
          if (myChangesCacheFile.myChangesProvider.isChangeLocallyAvailable(afterRevision.getFile(), null, afterRevision.getRevisionNumber(), changeList)) {
            return new ProcessingResult(true, AFTER_NOT_EXISTS_LOCALLY_AVAILABLE);
          }
          if (fileMarkedForDeletion(localPath)) {
            debug("File marked for deletion and not committed jet.");
            return new ProcessingResult(true, AFTER_NOT_EXISTS_MARKED_FOR_DELETION);
          }
          if (wasSubsequentlyDeleted(afterRevision.getFile(), changeListData.indexOffset)) {
            return new ProcessingResult(true, AFTER_NOT_EXISTS_SUBSEQUENTLY_DELETED);
          }
          debug("Could not find local file for change " + afterRevision.getFile().getPath());
          return new ProcessingResult(false, AFTER_NOT_EXISTS_OTHER);
        }
      }
      else {
        final ContentRevision beforeRevision = change.getBeforeRevision();
        assert beforeRevision != null;
        debug("Checking deleted file " + beforeRevision.getFile());
        myDeletedFiles.add(beforeRevision.getFile());
        if (incomingFiles != null && !incomingFiles.contains(beforeRevision.getFile())) {
          debug("Skipping deleted file outside of incoming files: " + beforeRevision.getFile());
          return new ProcessingResult(true, BEFORE_DOES_NOT_MATTER_OUTSIDE);
        }
        if (beforeRevision.getFile().getVirtualFile() == null || myCreatedFiles.contains(beforeRevision.getFile())) {
          // if not deleted from vcs, mark as incoming, otherwise file already deleted
          final boolean locallyDeleted = ChangeListManagerImpl.getInstanceImpl(myProject)
            .isContainedInLocallyDeleted(beforeRevision.getFile());
          debug(locallyDeleted ? "File deleted locally, change marked as incoming" : "File already deleted");
          return new ProcessingResult(!locallyDeleted, locallyDeleted ? BEFORE_NOT_EXISTS_DELETED_LOCALLY : BEFORE_NOT_EXISTS_ALREADY_DELETED);
        }
        else if (!myChangesCacheFile.myVcs.fileExistsInVcs(beforeRevision.getFile())) {
          debug("File exists locally and is unversioned");
          return new ProcessingResult(true, BEFORE_UNVERSIONED_INSTEAD_OF_VERS_DELETED);
        }
        else {
          final VirtualFile file = beforeRevision.getFile().getVirtualFile();
          return new ProcessingResult(file, currentRevision -> {
            if ((currentRevision != null) && (currentRevision.compareTo(beforeRevision.getRevisionNumber()) > 0)) {
              // revived in newer revision - possibly was added file with same name
              debug("File with same name was added after file deletion");
              return new ProcessingResult(true, BEFORE_SAME_NAME_ADDED_AFTER_DELETION);
            }
            debug("File exists locally and no 'create' change found for it");
            return new ProcessingResult(false, BEFORE_EXISTS_BUT_SHOULD_NOT);
          });
        }
      }
    }
private ProcessingResult processIncomingChange(@NotNull Change change,
                                                   @NotNull IncomingChangeListData changeListData,
                                                   @Nullable Collection<FilePath> incomingFiles)