private static String jobTitle(AnalyzeProjectRequest request) {
   if (request.getOnlyOnFiles() == null) {
     return "SonarLint analysis of project " + request.getProject().getName();
   }
   if (request.getOnlyOnFiles().size() == 1) {
     return "SonarLint analysis of file "
         + request.getOnlyOnFiles().iterator().next().getProjectRelativePath().toString()
         + " (Project "
         + request.getProject().getName()
         + ")";
   }
   return "SonarLint analysis of project "
       + request.getProject().getName()
       + " ("
       + request.getOnlyOnFiles().size()
       + " files)";
 }
  @Override
  protected IStatus run(SonarRunnerFacade runner, final IProgressMonitor monitor) {

    // Configure
    Properties properties = configureAnalysis(monitor, extraProps);

    // Analyze
    Collection<File> tmpToDelete = new ArrayList<>();
    try {
      if (request.getOnlyOnFiles() != null) {
        IProject project = request.getProject();
        final File baseDir = project.getLocation().toFile();
        handleLinkedFiles(tmpToDelete, baseDir);
      }
      run(request.getProject(), properties, runner, monitor);
      analysisCompleted(properties, monitor);
    } catch (Exception e) {
      SonarLintCorePlugin.getDefault()
          .error("Error during execution of SonarLint analysis" + System.lineSeparator(), e);
      return new Status(
          Status.WARNING,
          SonarLintCorePlugin.PLUGIN_ID,
          "Error when executing SonarLint analysis",
          e);
    } finally {
      for (File f : tmpToDelete) {
        try {
          f.delete();
        } catch (Exception e) {
          SonarLintCorePlugin.getDefault()
              .error("Unable to delete temporary file" + System.lineSeparator(), e);
        }
      }
    }
    if (monitor.isCanceled()) {
      return Status.CANCEL_STATUS;
    }

    return Status.OK_STATUS;
  }
 private void handleLinkedFiles(Collection<File> tmpToDelete, final File baseDir) {
   // Handle linked files
   for (IFile file : request.getOnlyOnFiles()) {
     if (file.isLinked()) {
       File tmp = new File(baseDir, file.getProjectRelativePath().toString());
       SonarLintCorePlugin.getDefault()
           .debug(
               file.getName()
                   + " is a linked resource. Will create a temporary copy"
                   + System.lineSeparator());
       try {
         Files.copy(file.getContents(), tmp.toPath());
         tmpToDelete.add(tmp);
       } catch (IOException | CoreException e) {
         SonarLintCorePlugin.getDefault()
             .error(
                 "Unable to create temporary copy for linked resource" + System.lineSeparator(),
                 e);
       }
     }
   }
 }