/**
   * Populate properties with everything required for the SonarLint analysis in issues mode.
   *
   * @param monitor
   * @param properties
   * @return
   */
  public Properties configureAnalysis(
      final IProgressMonitor monitor, List<SonarLintProperty> extraProps) {
    Properties properties = new Properties();
    IProject project = request.getProject();
    final File baseDir = project.getLocation().toFile();
    IPath projectSpecificWorkDir = project.getWorkingLocation(SonarLintCorePlugin.PLUGIN_ID);

    // Preview mode by default
    properties.setProperty(
        SonarLintProperties.ANALYSIS_MODE, SonarLintProperties.ANALYSIS_MODE_ISSUES);

    // Configuration by configurators (common and language specific)
    configure(project, this.request.getOnlyOnFiles(), properties, monitor);

    // Append workspace and project properties
    for (SonarLintProperty sonarProperty : extraProps) {
      properties.put(sonarProperty.getName(), sonarProperty.getValue());
    }
    if (this.request.getOnlyOnFiles() != null) {
      Collection<String> paths = new ArrayList<>(this.request.getOnlyOnFiles().size());
      for (IFile file : this.request.getOnlyOnFiles()) {
        MarkerUtils.deleteIssuesMarkers(file);
        paths.add(file.getProjectRelativePath().toString());
      }
      ProjectConfigurator.setPropertyList(properties, "sonar.tests", paths);
      ProjectConfigurator.setPropertyList(properties, "sonar.sources", paths);
    } else {
      MarkerUtils.deleteIssuesMarkers(project);
    }

    properties.setProperty(SonarLintProperties.PROJECT_BASEDIR, baseDir.toString());
    properties.setProperty(SonarLintProperties.WORK_DIR, projectSpecificWorkDir.toString());

    return properties;
  }
  private void configure(
      final IProject project,
      Collection<IFile> filesToAnalyze,
      final Properties properties,
      final IProgressMonitor monitor) {
    String projectName = project.getName();
    String encoding;
    try {
      encoding = project.getDefaultCharset();
    } catch (CoreException e) {
      throw new SonarEclipseException("Unable to get charset from project", e);
    }

    properties.setProperty(SonarLintProperties.PROJECT_NAME_PROPERTY, projectName);
    properties.setProperty(SonarLintProperties.PROJECT_VERSION_PROPERTY, "0.1-SNAPSHOT");
    properties.setProperty(SonarLintProperties.ENCODING_PROPERTY, encoding);

    ProjectConfigurationRequest configuratorRequest =
        new ProjectConfigurationRequest(project, filesToAnalyze, properties);
    Collection<ProjectConfigurator> configurators = ConfiguratorUtils.getConfigurators();
    for (ProjectConfigurator configurator : configurators) {
      if (configurator.canConfigure(project)) {
        configurator.configure(configuratorRequest, monitor);
        usedConfigurators.add(configurator);
      }
    }

    ProjectConfigurator.appendProperty(
        properties,
        SonarConfiguratorProperties.TEST_INCLUSIONS_PROPERTY,
        PreferencesUtils.getTestFileRegexps());
    if (!properties.containsKey(SonarConfiguratorProperties.SOURCE_DIRS_PROPERTY)
        && !properties.containsKey(SonarConfiguratorProperties.TEST_DIRS_PROPERTY)) {
      // Try to analyze all files
      properties.setProperty(SonarConfiguratorProperties.SOURCE_DIRS_PROPERTY, ".");
      properties.setProperty(SonarConfiguratorProperties.TEST_DIRS_PROPERTY, ".");
      // Try to exclude derived folders
      try {
        for (IResource member : project.members()) {
          if (member.isDerived()) {
            ProjectConfigurator.appendProperty(
                properties,
                SonarConfiguratorProperties.SOURCE_EXCLUSIONS_PROPERTY,
                member.getName() + "/**/*");
            ProjectConfigurator.appendProperty(
                properties,
                SonarConfiguratorProperties.TEST_EXCLUSIONS_PROPERTY,
                member.getName() + "/**/*");
          }
        }
      } catch (CoreException e) {
        throw new IllegalStateException("Unable to list members of " + project, e);
      }
    }
  }
 private void analysisCompleted(Properties properties, final IProgressMonitor monitor) {
   for (ProjectConfigurator p : usedConfigurators) {
     p.analysisComplete(Collections.unmodifiableMap(toMap(properties)), monitor);
   }
 }