private @Nullable JComponent createCompositePerRunnerSettings(@NotNull Executor executor, @NotNull ProgramRunner<RunnerSettings> runner) {
    final SettingsEditor<ConfigurationPerRunnerSettings> configEditor = myConfiguration.getRunnerSettingsEditor(runner);
    SettingsEditor<RunnerSettings> runnerEditor;
    try {
      runnerEditor = runner.getSettingsEditor(executor, myConfiguration);
    }
    catch (AbstractMethodError error) {
      // this is stub code for plugin compatibility
      runnerEditor = null;
    }

    if (configEditor == null && runnerEditor == null) {
      return null;
    }

    SettingsEditor<RunnerAndConfigurationSettings> wrappedConfigEditor = null;
    SettingsEditor<RunnerAndConfigurationSettings> wrappedRunEditor = null;
    if (configEditor != null) {
      wrappedConfigEditor = wrapEditor(configEditor,
                                       runner, configurationSettings -> configurationSettings.getConfigurationSettings(runner)
      );
    }

    if (runnerEditor != null) {
      wrappedRunEditor = wrapEditor(runnerEditor,
                                    runner, configurationSettings -> configurationSettings.getRunnerSettings(runner)
      );
    }

    if (wrappedRunEditor != null && wrappedConfigEditor != null) {
      JPanel panel = new JPanel(new BorderLayout());
      panel.add(wrappedConfigEditor.getComponent(), BorderLayout.CENTER);
      JComponent wrappedRunEditorComponent = wrappedRunEditor.getComponent();
      wrappedRunEditorComponent.setBorder(JBUI.Borders.emptyTop(3));
      panel.add(wrappedRunEditorComponent, BorderLayout.SOUTH);
      return panel;
    }

    return wrappedRunEditor == null ? Objects.requireNonNull(wrappedConfigEditor).getComponent() : wrappedRunEditor.getComponent();
  }
private @Nullable JComponent createCompositePerRunnerSettings(@NotNull Executor executor, @NotNull ProgramRunner<RunnerSettings> runner)