@Override
  public void apply(@NotNull Project project,
                    @NotNull IdeModifiableModelsProvider modelsProvider,
                    @NotNull ConfigurationData configuration) {
    Object obj = configuration.find("compiler");
    if (!(obj instanceof Map)) return;

    @SuppressWarnings("unchecked")
    Map<String, ?> configurationMap = (Map<String, ?>)obj;

    ApplicationManager.getApplication().invokeLater(() -> {
      final CompilerConfigurationImpl compilerConfiguration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(project);
      final CompilerWorkspaceConfiguration workspaceConfiguration = CompilerWorkspaceConfiguration.getInstance(project);
      final JpsJavaCompilerOptions javacConfiguration = JavacConfiguration.getOptions(project, JavacConfiguration.class);

      boolean changed = false;
      String resourcePatterns = getString(configurationMap, "resourcePatterns");
      if (resourcePatterns != null) {
        try {
          String[] resourceFilePatterns = compilerConfiguration.getResourceFilePatterns();
          compilerConfiguration.removeResourceFilePatterns();
          CompilerUIConfigurable.applyResourcePatterns(resourcePatterns, compilerConfiguration);
          if (!Arrays.equals(resourceFilePatterns, compilerConfiguration.getResourceFilePatterns())) {
            changed = true;
          }
        }
        catch (ConfigurationException e) {
          LOG.warn("Unable to apply compiler resource patterns", e);
        }
      }

      Number processHeapSize = getNumber(configurationMap, "processHeapSize");
      if (processHeapSize != null && processHeapSize.intValue() != compilerConfiguration.getBuildProcessHeapSize(0)) {
        compilerConfiguration.setBuildProcessHeapSize(processHeapSize.intValue());
        changed = true;
      }

      Boolean useReleaseOption = getBoolean(configurationMap, "useReleaseOption");
      if (useReleaseOption != null && compilerConfiguration.useReleaseOption() != useReleaseOption) {
        compilerConfiguration.setUseReleaseOption(useReleaseOption);
        changed = true;
      }

      Boolean autoShowFirstErrorInEditor = getBoolean(configurationMap, "autoShowFirstErrorInEditor");
      if (autoShowFirstErrorInEditor != null && workspaceConfiguration.AUTO_SHOW_ERRORS_IN_EDITOR != autoShowFirstErrorInEditor) {
        workspaceConfiguration.AUTO_SHOW_ERRORS_IN_EDITOR = autoShowFirstErrorInEditor;
        changed = true;
      }
      Boolean displayNotificationPopup = getBoolean(configurationMap, "displayNotificationPopup");
      if (displayNotificationPopup != null && workspaceConfiguration.DISPLAY_NOTIFICATION_POPUP != displayNotificationPopup) {
        workspaceConfiguration.DISPLAY_NOTIFICATION_POPUP = displayNotificationPopup;
        changed = true;
      }
      Boolean clearOutputDirectory = getBoolean(configurationMap, "clearOutputDirectory");
      if (clearOutputDirectory != null && workspaceConfiguration.CLEAR_OUTPUT_DIRECTORY != clearOutputDirectory) {
        workspaceConfiguration.CLEAR_OUTPUT_DIRECTORY = clearOutputDirectory;
        changed = true;
      }
      Boolean addNotNullAssertions = getBoolean(configurationMap, "addNotNullAssertions");
      if (addNotNullAssertions != null && compilerConfiguration.isAddNotNullAssertions() != addNotNullAssertions) {
        compilerConfiguration.setAddNotNullAssertions(addNotNullAssertions);
        changed = true;
      }
      Boolean enableAutomake = getBoolean(configurationMap, "enableAutomake");
      if (enableAutomake != null && workspaceConfiguration.MAKE_PROJECT_ON_SAVE != enableAutomake) {
        workspaceConfiguration.MAKE_PROJECT_ON_SAVE = enableAutomake;
        changed = true;
      }
      Boolean parallelCompilation = getBoolean(configurationMap, "parallelCompilation");
      if (parallelCompilation != null && compilerConfiguration.isParallelCompilationEnabled() != parallelCompilation) {
        compilerConfiguration.setParallelCompilationEnabled(parallelCompilation);
        changed = true;
      }
      Boolean rebuildOnDependencyChange = getBoolean(configurationMap, "rebuildModuleOnDependencyChange");
      if (rebuildOnDependencyChange != null && workspaceConfiguration.REBUILD_ON_DEPENDENCY_CHANGE != rebuildOnDependencyChange) {
        workspaceConfiguration.REBUILD_ON_DEPENDENCY_CHANGE = rebuildOnDependencyChange;
        changed = true;
      }
      String additionalVmOptions = getString(configurationMap, "additionalVmOptions");
      if (additionalVmOptions != null && !additionalVmOptions.equals(workspaceConfiguration.COMPILER_PROCESS_ADDITIONAL_VM_OPTIONS)) {
        workspaceConfiguration.COMPILER_PROCESS_ADDITIONAL_VM_OPTIONS = additionalVmOptions;
        changed = true;
      }

      Map<String, ?> javacOptions = getMap(configurationMap, "javacOptions");
      if (javacOptions != null) {
        Boolean preferTargetJDKCompiler = getBoolean(javacOptions, "preferTargetJDKCompiler");
        if (preferTargetJDKCompiler != null && javacConfiguration.PREFER_TARGET_JDK_COMPILER != preferTargetJDKCompiler) {
          javacConfiguration.PREFER_TARGET_JDK_COMPILER = preferTargetJDKCompiler;
          changed = true;
        }

        String javacAdditionalOptions = getString(javacOptions, "javacAdditionalOptions");
        if (javacAdditionalOptions != null && !javacConfiguration.ADDITIONAL_OPTIONS_STRING.equals(javacAdditionalOptions)) {
          javacConfiguration.ADDITIONAL_OPTIONS_STRING = javacAdditionalOptions;
          changed = true;
        }

        Map<String, String> moduleJavacAdditionalOptions = getMap(javacOptions, "moduleJavacAdditionalOptions");
        if (moduleJavacAdditionalOptions != null && !javacConfiguration.ADDITIONAL_OPTIONS_OVERRIDE.equals(moduleJavacAdditionalOptions)) {
          javacConfiguration.ADDITIONAL_OPTIONS_OVERRIDE = moduleJavacAdditionalOptions;
          changed = true;
        }

        Boolean generateDebugInfo = getBoolean(javacOptions, "generateDebugInfo");
        if (generateDebugInfo != null && javacConfiguration.DEBUGGING_INFO != generateDebugInfo) {
          javacConfiguration.DEBUGGING_INFO = generateDebugInfo;
          changed = true;
        }

        Boolean generateDeprecationWarnings = getBoolean(javacOptions, "generateDeprecationWarnings");
        if (generateDeprecationWarnings != null && javacConfiguration.DEPRECATION != generateDeprecationWarnings) {
          javacConfiguration.DEPRECATION = generateDeprecationWarnings;
          changed = true;
        }

        Boolean generateNoWarnings = getBoolean(javacOptions, "generateNoWarnings");
        if (generateNoWarnings != null && javacConfiguration.GENERATE_NO_WARNINGS != generateNoWarnings) {
          javacConfiguration.GENERATE_NO_WARNINGS = generateNoWarnings;
          changed = true;
        }
      }

      if (changed && !project.isDefault()) {
        BuildManager.getInstance().clearState(project);
      }
    });
  }
@Override
  public void apply(@NotNull Project project,
                    @NotNull IdeModifiableModelsProvider modelsProvider,
                    @NotNull ConfigurationData configuration)