 core/lib/Drupal/Core/Form/ConfigFormBase.php       |   2 +-
 core/lib/Drupal/Core/Form/ConfigFormInterface.php  |  23 ++++
 .../Core/Plugin/PluginConfigFormInterface.php      |  30 +++++
 .../lib/Drupal/aggregator/Form/SettingsForm.php    |  93 +++++++++-----
 .../Plugin/AggregatorPluginSettingsBase.php        |   6 +
 .../aggregator/processor/DefaultProcessor.php      |   7 ++
 .../aggregator/Tests/Form/SettingsFormTest.php     | 139 +++++++++++++++++++++
 .../Plugin/aggregator/processor/TestProcessor.php  |   7 ++
 .../book/lib/Drupal/book/Form/BookSettingsForm.php |   7 ++
 .../forum/lib/Drupal/forum/ForumSettingsForm.php   |   7 ++
 .../language/Form/ContentLanguageSettingsForm.php  |   7 ++
 .../language/Form/NegotiationBrowserForm.php       |   7 ++
 .../language/Form/NegotiationSelectedForm.php      |   7 ++
 .../language/Form/NegotiationSessionForm.php       |   7 ++
 .../Drupal/language/Form/NegotiationUrlForm.php    |   7 ++
 .../lib/Drupal/locale/Form/LocaleSettingsForm.php  |   7 ++
 .../menu/lib/Drupal/menu/MenuSettingsForm.php      |   7 ++
 .../lib/Drupal/node/Plugin/Search/NodeSearch.php   |   2 -
 .../lib/Drupal/search/Form/SearchSettingsForm.php  |  17 +++
 .../Plugin/Search/SearchExtraTypeSearch.php        |  13 +-
 .../simpletest/Form/SimpletestSettingsForm.php     |   7 ++
 .../Drupal/statistics/StatisticsSettingsForm.php   |   7 ++
 .../system/lib/Drupal/system/Form/CronForm.php     |   7 ++
 .../lib/Drupal/system/Form/FileSystemForm.php      |   7 ++
 .../lib/Drupal/system/Form/ImageToolkitForm.php    |   7 ++
 .../system/lib/Drupal/system/Form/LoggingForm.php  |   7 ++
 .../lib/Drupal/system/Form/PerformanceForm.php     |   7 ++
 .../system/lib/Drupal/system/Form/RegionalForm.php |   7 ++
 .../system/lib/Drupal/system/Form/RssFeedsForm.php |   7 ++
 .../lib/Drupal/system/Form/SiteInformationForm.php |   7 ++
 .../Drupal/system/Form/SiteMaintenanceModeForm.php |   7 ++
 .../lib/Drupal/system/Form/ThemeSettingsForm.php   |  14 +++
 .../Drupal/form_test/SystemConfigFormTestForm.php  |   7 ++
 .../lib/Drupal/update/UpdateSettingsForm.php       |   7 ++
 .../user/lib/Drupal/user/AccountSettingsForm.php   |   7 ++
 .../Drupal/views_ui/Form/AdvancedSettingsForm.php  |   7 ++
 .../lib/Drupal/views_ui/Form/BasicSettingsForm.php |   7 ++
 37 files changed, 490 insertions(+), 38 deletions(-)

diff --git a/core/lib/Drupal/Core/Form/ConfigFormBase.php b/core/lib/Drupal/Core/Form/ConfigFormBase.php
index 5c69835..8f4b912 100644
--- a/core/lib/Drupal/Core/Form/ConfigFormBase.php
+++ b/core/lib/Drupal/Core/Form/ConfigFormBase.php
@@ -15,7 +15,7 @@
 /**
  * Base class for implementing system configuration forms.
  */
-abstract class ConfigFormBase extends FormBase {
+abstract class ConfigFormBase extends FormBase implements ConfigFormInterface {
 
   /**
    * Stores the configuration factory.
diff --git a/core/lib/Drupal/Core/Form/ConfigFormInterface.php b/core/lib/Drupal/Core/Form/ConfigFormInterface.php
new file mode 100644
index 0000000..3e75f6f
--- /dev/null
+++ b/core/lib/Drupal/Core/Form/ConfigFormInterface.php
@@ -0,0 +1,23 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Form\ConfigFormInterface.
+ */
+
+namespace Drupal\Core\Form;
+
+/**
+ * Provides an interface specific for forms based on configuration.
+ */
+interface ConfigFormInterface extends FormInterface {
+
+  /**
+   * Returns an array of configuration names associated with the form.
+   *
+   * @return array
+   *   An array of configuration names
+   */
+  public function getConfigNames();
+
+}
diff --git a/core/lib/Drupal/Core/Plugin/PluginConfigFormInterface.php b/core/lib/Drupal/Core/Plugin/PluginConfigFormInterface.php
new file mode 100644
index 0000000..53c91d5
--- /dev/null
+++ b/core/lib/Drupal/Core/Plugin/PluginConfigFormInterface.php
@@ -0,0 +1,30 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Plugin\PluginConfigFormInterface.
+ */
+
+namespace Drupal\Core\Plugin;
+
+/**
+ * Provides an interface for a plugin that saves configuration.
+ *
+ * This interface is only needed for plugins that save their configuration in
+ * separate configuration files. If the configuration is saved as part of a
+ * configuration entity by utilizing the plugin bag pattern, for example, use
+ * PluginFormInterface instead.
+ *
+ * @see \Drupal\Core\Plugin\PluginFormInterface
+ */
+interface PluginConfigFormInterface extends PluginFormInterface {
+
+  /**
+   * Returns an array of configuration names associated with the form.
+   *
+   * @return array
+   *   An array of configuration names.
+   */
+  public function getConfigNames();
+
+}
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Form/SettingsForm.php b/core/modules/aggregator/lib/Drupal/aggregator/Form/SettingsForm.php
index 85e96e0..8c0669a 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Form/SettingsForm.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Form/SettingsForm.php
@@ -11,6 +11,7 @@
 use Drupal\Component\Utility\String;
 use Drupal\Core\Config\Context\ContextInterface;
 use Drupal\Core\Config\ConfigFactory;
+use Drupal\Core\Plugin\PluginConfigFormInterface;
 use Drupal\Core\Plugin\PluginFormInterface;
 use Drupal\Core\StringTranslation\TranslationInterface;
 use Drupal\Core\Form\ConfigFormBase;
@@ -33,7 +34,7 @@ class SettingsForm extends ConfigFormBase {
    *
    * @var \Drupal\Core\Plugin\PluginFormInterface[]
    */
-  protected $configurableInstances = array();
+  protected $configurableInstances;
 
   /**
    * The aggregator plugin definitions.
@@ -100,6 +101,47 @@ public function getFormID() {
   }
 
   /**
+   * Collect configurable instances of this form's plugins.
+   */
+  protected function getConfigurableInstances() {
+    if (!isset($this->configurableInstances)) {
+      $this->configurableInstances = array();
+
+      $config = $this->configFactory->get('aggregator.settings');
+
+      // Parse fetchers and parsers and collect their PluginFormInterface
+      // instances.
+      foreach (array('fetcher', 'parser') as $type) {
+        $active = $config->get($type);
+        if (array_key_exists($active, $this->definitions[$type])) {
+          $instance = $this->managers[$type]->createInstance($active);
+          if ($instance instanceof PluginFormInterface) {
+            // Store the instance for validate and submit handlers.
+            // Keying by ID would bring conflicts, because two instances of a
+            // different type could have the same ID.
+            $this->configurableInstances[] = $instance;
+          }
+        }
+      }
+
+      // Parse processors and collect their PluginFormInterface instances.
+      foreach ($this->definitions['processor'] as $id => $definition) {
+        if (in_array($id, $config->get('processors'))) {
+          $instance = $this->managers['processor']->createInstance($id);
+          if ($instance instanceof PluginFormInterface) {
+            // Store the instance for validate and submit handlers.
+            // Keying by ID would bring conflicts, because two instances of a
+            // different type could have the same ID.
+            $this->configurableInstances[] = $instance;
+          }
+        }
+      }
+    }
+
+    return $this->configurableInstances;
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function buildForm(array $form, array &$form_state) {
@@ -154,35 +196,9 @@ public function buildForm(array $form, array &$form_state) {
       $form['basic_conf'] += $basic_conf;
     }
 
-    // Call buildConfigurationForm() on the active fetcher and parser.
-    foreach (array('fetcher', 'parser') as $type) {
-      $active = $config->get($type);
-      if (array_key_exists($active, $this->definitions[$type])) {
-        $instance = $this->managers[$type]->createInstance($active);
-        if ($instance instanceof PluginFormInterface) {
-          $form = $instance->buildConfigurationForm($form, $form_state);
-          // Store the instance for validate and submit handlers.
-          // Keying by ID would bring conflicts, because two instances of a
-          // different type could have the same ID.
-          $this->configurableInstances[] = $instance;
-        }
-      }
-    }
-
-    // Implementing processor plugins will expect an array at $form['processors'].
     $form['processors'] = array();
-    // Call buildConfigurationForm() for each active processor.
-    foreach ($this->definitions['processor'] as $id => $definition) {
-      if (in_array($id, $config->get('processors'))) {
-        $instance = $this->managers['processor']->createInstance($id);
-        if ($instance instanceof PluginFormInterface) {
-          $form = $instance->buildConfigurationForm($form, $form_state);
-          // Store the instance for validate and submit handlers.
-          // Keying by ID would bring conflicts, because two instances of a
-          // different type could have the same ID.
-          $this->configurableInstances[] = $instance;
-        }
-      }
+    foreach ($this->getConfigurableInstances() as $instance) {
+      $form = $instance->buildConfigurationForm($form, $form_state);
     }
 
     return parent::buildForm($form, $form_state);
@@ -194,7 +210,7 @@ public function buildForm(array $form, array &$form_state) {
   public function validateForm(array &$form, array &$form_state) {
     parent::validateForm($form, $form_state);
     // Let active plugins validate their settings.
-    foreach ($this->configurableInstances as $instance) {
+    foreach ($this->getConfigurableInstances() as $instance) {
       $instance->validateConfigurationForm($form, $form_state);
     }
   }
@@ -206,7 +222,7 @@ public function submitForm(array &$form, array &$form_state) {
     parent::submitForm($form, $form_state);
     $config = $this->configFactory->get('aggregator.settings');
     // Let active plugins save their settings.
-    foreach ($this->configurableInstances as $instance) {
+    foreach ($this->getConfigurableInstances() as $instance) {
       $instance->submitConfigurationForm($form, $form_state);
     }
 
@@ -223,4 +239,19 @@ public function submitForm(array &$form, array &$form_state) {
     $config->save();
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    $config_names = array('aggregator.settings');
+
+    foreach ($this->getConfigurableInstances() as $instance) {
+      if ($instance instanceof PluginConfigFormInterface) {
+        $config_names = array_merge($config_names, $instance->getConfigNames());
+      }
+    }
+
+    return array_unique($config_names);
+  }
+
 }
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/AggregatorPluginSettingsBase.php b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/AggregatorPluginSettingsBase.php
index 9ca7c79..288e3c6 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/AggregatorPluginSettingsBase.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/AggregatorPluginSettingsBase.php
@@ -29,4 +29,10 @@ public function defaultConfiguration() {
   public function validateConfigurationForm(array &$form, array &$form_state) {
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    return array();
+  }
 }
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/processor/DefaultProcessor.php b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/processor/DefaultProcessor.php
index ec7d193..23f333b 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/processor/DefaultProcessor.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/processor/DefaultProcessor.php
@@ -239,6 +239,13 @@ public function setConfiguration(array $configuration) {
   }
 
   /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    return array('aggregator.settings');
+  }
+
+  /**
    * Helper function for drupal_map_assoc.
    *
    * @param int $count
diff --git a/core/modules/aggregator/tests/Drupal/aggregator/Tests/Form/SettingsFormTest.php b/core/modules/aggregator/tests/Drupal/aggregator/Tests/Form/SettingsFormTest.php
new file mode 100644
index 0000000..14f7988
--- /dev/null
+++ b/core/modules/aggregator/tests/Drupal/aggregator/Tests/Form/SettingsFormTest.php
@@ -0,0 +1,139 @@
+<?php
+
+/**
+ * @file
+ * Contains\Drupal\aggregator\Tests\Form\SettingsFormTest.
+ */
+
+namespace Drupal\aggregator\Tests\Form;
+
+use Drupal\aggregator\Form\SettingsForm;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * Tests \Drupal\aggregator\Form\SettingsForm.
+ */
+class SettingsFormTest extends UnitTestCase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getInfo() {
+    return array(
+      'name' => 'Aggregator settings form tests',
+      'description' => 'Unit tests for the aggregator settings form',
+      'group' => 'Aggregator',
+    );
+  }
+
+  public function setUp() {
+
+  }
+
+  /**
+   * Tests getConfigNames().
+   */
+  public function testGetConfigNames() {
+    // Test with no aggregator plugins.
+    $configs = array('aggregator.settings' => array());
+    $definitions = array();
+
+    $settings_form = $this->getSettingsForm($configs, $definitions);
+
+    $expected = array('aggregator.settings');
+    $this->assertSame($expected, array_values($settings_form->getConfigNames()));
+
+    // Test that aggregator plugins can add additional configuration names.
+    // that duplicated names are removed.
+    $configs = array('aggregator.settings' => array(
+      'fetcher' => 'aggregator_test_fetcher',
+      'parser' => 'aggregator_test_parser',
+      'processors' => array('aggregator_test_processor')
+    ));
+    $definitions = array(
+      'aggregator_test_fetcher' => array(
+        'title' => 'Test fetcher',
+        'description' => 'Test generic fetcher functionality.',
+      ),
+      'aggregator_test_parser' => array(
+        'title' => 'Test parser',
+        'description' => 'Test generic parser functionality.',
+      ),
+      'aggregator_test_processor' => array(
+        'title' => 'Test processor',
+        'description' => 'Test generic processor functionality.',
+      ),
+    );
+    $config_names = array('aggregator_test.settings');
+
+    $settings_form = $this->getSettingsForm($configs, $definitions, $config_names);
+
+    $expected = array('aggregator.settings', 'aggregator_test.settings');
+
+    $this->assertEquals($expected, array_values($settings_form->getConfigNames()));
+
+    // Test that config names are not duplicated.
+    $config_names = array('aggregator.settings');
+
+    // Re-use $configs and $definitions.
+    $settings_form = $this->getSettingsForm($configs, $definitions, $config_names);
+
+    $expected = array('aggregator.settings');
+
+    $this->assertEquals($expected, array_values($settings_form->getConfigNames()));
+
+  }
+
+  /**
+   * Returns an aggregator settings form.
+   *
+   * @param array $configs
+   *   An array of configuration values as expected by
+   *   UnitTestCase::getConfigFactoryStub().
+   * @param array $definitions
+   *   An array of aggregator plugin definitions.
+   * @param array $config_names
+   *   An array of config names that the plugins should return.
+   *
+   * @return \Drupal\aggregator\Form\SettingsForm
+   *   The aggregator settings form.
+   */
+  protected function getSettingsForm(array $configs, array $definitions, array $config_names = NULL) {
+    $plugin_manager = $this->getMockBuilder('Drupal\aggregator\Plugin\AggregatorPluginManager')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $plugin_manager
+      ->expects($this->exactly(3))
+      ->method('getDefinitions')
+      ->will($this->returnValue($definitions));
+
+    $settings_form = new SettingsForm(
+      $this->getConfigFactoryStub($configs),
+      $this->getMock('Drupal\Core\Config\Context\ContextInterface'),
+      $plugin_manager,
+      $plugin_manager,
+      $plugin_manager,
+      $this->getMock('Drupal\Core\StringTranslation\TranslationInterface')
+    );
+
+    if (!empty($config_names)) {
+      $plugin = $this->getMock('Drupal\Core\Plugin\PluginFormInterface');
+      $plugin
+        ->expects($this->exactly(3))
+        ->method('getConfigNames')
+        ->will($this->returnValue($config_names));
+      $plugin_manager
+        ->expects($this->exactly(3))
+        ->method('createInstance')
+        ->will($this->returnValueMap(array(
+          array('aggregator_test_fetcher', array(), $plugin),
+          array('aggregator_test_parser', array(), $plugin),
+          array('aggregator_test_processor', array(), $plugin)
+        )));
+
+    }
+
+    return $settings_form;
+  }
+
+}
diff --git a/core/modules/aggregator/tests/modules/aggregator_test/lib/Drupal/aggregator_test/Plugin/aggregator/processor/TestProcessor.php b/core/modules/aggregator/tests/modules/aggregator_test/lib/Drupal/aggregator_test/Plugin/aggregator/processor/TestProcessor.php
index 04a5c5a..7c8e54e 100644
--- a/core/modules/aggregator/tests/modules/aggregator_test/lib/Drupal/aggregator_test/Plugin/aggregator/processor/TestProcessor.php
+++ b/core/modules/aggregator/tests/modules/aggregator_test/lib/Drupal/aggregator_test/Plugin/aggregator/processor/TestProcessor.php
@@ -142,4 +142,11 @@ public function setConfiguration(array $configuration) {
     $config->save();
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    return array('aggregator_test.settings');
+  }
+
 }
diff --git a/core/modules/book/lib/Drupal/book/Form/BookSettingsForm.php b/core/modules/book/lib/Drupal/book/Form/BookSettingsForm.php
index e5c48b1..7643c57 100644
--- a/core/modules/book/lib/Drupal/book/Form/BookSettingsForm.php
+++ b/core/modules/book/lib/Drupal/book/Form/BookSettingsForm.php
@@ -77,5 +77,12 @@ public function submitForm(array &$form, array &$form_state) {
     parent::submitForm($form, $form_state);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    return array('book.settings');
+  }
+
 }
 
diff --git a/core/modules/forum/lib/Drupal/forum/ForumSettingsForm.php b/core/modules/forum/lib/Drupal/forum/ForumSettingsForm.php
index 9fe4931..d7ace97 100644
--- a/core/modules/forum/lib/Drupal/forum/ForumSettingsForm.php
+++ b/core/modules/forum/lib/Drupal/forum/ForumSettingsForm.php
@@ -73,4 +73,11 @@ public function submitForm(array &$form, array &$form_state) {
     parent::submitForm($form, $form_state);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    return array('forum.settings');
+  }
+
 }
diff --git a/core/modules/language/lib/Drupal/language/Form/ContentLanguageSettingsForm.php b/core/modules/language/lib/Drupal/language/Form/ContentLanguageSettingsForm.php
index f4d7c54..e194c32 100644
--- a/core/modules/language/lib/Drupal/language/Form/ContentLanguageSettingsForm.php
+++ b/core/modules/language/lib/Drupal/language/Form/ContentLanguageSettingsForm.php
@@ -179,4 +179,11 @@ public function submitForm(array &$form, array &$form_state) {
     parent::submitForm($form, $form_state);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    return array('language.settings');
+  }
+
 }
diff --git a/core/modules/language/lib/Drupal/language/Form/NegotiationBrowserForm.php b/core/modules/language/lib/Drupal/language/Form/NegotiationBrowserForm.php
index b801b2b..09cec08 100644
--- a/core/modules/language/lib/Drupal/language/Form/NegotiationBrowserForm.php
+++ b/core/modules/language/lib/Drupal/language/Form/NegotiationBrowserForm.php
@@ -197,4 +197,11 @@ protected function language_get_browser_drupal_langcode_mappings() {
     return $config->get();
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    return array('language.mappings');
+  }
+
 }
diff --git a/core/modules/language/lib/Drupal/language/Form/NegotiationSelectedForm.php b/core/modules/language/lib/Drupal/language/Form/NegotiationSelectedForm.php
index 4271861..57e287c 100644
--- a/core/modules/language/lib/Drupal/language/Form/NegotiationSelectedForm.php
+++ b/core/modules/language/lib/Drupal/language/Form/NegotiationSelectedForm.php
@@ -48,4 +48,11 @@ public function submitForm(array &$form, array &$form_state) {
     parent::submitForm($form, $form_state);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    return array('language.negotiation');
+  }
+
 }
diff --git a/core/modules/language/lib/Drupal/language/Form/NegotiationSessionForm.php b/core/modules/language/lib/Drupal/language/Form/NegotiationSessionForm.php
index 1c73492..e2372ca 100644
--- a/core/modules/language/lib/Drupal/language/Form/NegotiationSessionForm.php
+++ b/core/modules/language/lib/Drupal/language/Form/NegotiationSessionForm.php
@@ -49,4 +49,11 @@ public function submitForm(array &$form, array &$form_state) {
     parent::submitForm($form, $form_state);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    return array('language.negotiation');
+  }
+
 }
diff --git a/core/modules/language/lib/Drupal/language/Form/NegotiationUrlForm.php b/core/modules/language/lib/Drupal/language/Form/NegotiationUrlForm.php
index 6855a24..8898076 100644
--- a/core/modules/language/lib/Drupal/language/Form/NegotiationUrlForm.php
+++ b/core/modules/language/lib/Drupal/language/Form/NegotiationUrlForm.php
@@ -171,4 +171,11 @@ public function submitForm(array &$form, array &$form_state) {
     parent::submitForm($form, $form_state);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    return array('language.negotiation');
+  }
+
 }
diff --git a/core/modules/locale/lib/Drupal/locale/Form/LocaleSettingsForm.php b/core/modules/locale/lib/Drupal/locale/Form/LocaleSettingsForm.php
index 2791646..1f80726 100644
--- a/core/modules/locale/lib/Drupal/locale/Form/LocaleSettingsForm.php
+++ b/core/modules/locale/lib/Drupal/locale/Form/LocaleSettingsForm.php
@@ -139,4 +139,11 @@ public function submitForm(array &$form, array &$form_state) {
     parent::submitForm($form, $form_state);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    return array('locale.settings');
+  }
+
 }
diff --git a/core/modules/menu/lib/Drupal/menu/MenuSettingsForm.php b/core/modules/menu/lib/Drupal/menu/MenuSettingsForm.php
index a354184..16998b3 100644
--- a/core/modules/menu/lib/Drupal/menu/MenuSettingsForm.php
+++ b/core/modules/menu/lib/Drupal/menu/MenuSettingsForm.php
@@ -69,4 +69,11 @@ public function submitForm(array &$form, array &$form_state) {
     parent::submitForm($form, $form_state);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    return array('menu.settings');
+  }
+
 }
diff --git a/core/modules/node/lib/Drupal/node/Plugin/Search/NodeSearch.php b/core/modules/node/lib/Drupal/node/Plugin/Search/NodeSearch.php
index cdc399f..2a2cda6 100644
--- a/core/modules/node/lib/Drupal/node/Plugin/Search/NodeSearch.php
+++ b/core/modules/node/lib/Drupal/node/Plugin/Search/NodeSearch.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\node\Plugin\Search;
 
-use Drupal\Core\Annotation\Translation;
 use Drupal\Core\Config\Config;
 use Drupal\Core\Database\Connection;
 use Drupal\Core\Database\Query\SelectExtender;
@@ -20,7 +19,6 @@
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\TypedData\AccessibleInterface;
 use Drupal\Core\Database\Query\Condition;
-use Drupal\search\Annotation\SearchPlugin;
 use Drupal\search\Plugin\SearchPluginBase;
 use Drupal\search\Plugin\SearchIndexingInterface;
 
diff --git a/core/modules/search/lib/Drupal/search/Form/SearchSettingsForm.php b/core/modules/search/lib/Drupal/search/Form/SearchSettingsForm.php
index 3f21186..d6a9d67 100644
--- a/core/modules/search/lib/Drupal/search/Form/SearchSettingsForm.php
+++ b/core/modules/search/lib/Drupal/search/Form/SearchSettingsForm.php
@@ -10,6 +10,7 @@
 use Drupal\Core\Config\Context\ContextInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\KeyValueStore\KeyValueStoreInterface;
+use Drupal\Core\Plugin\PluginConfigFormInterface;
 use Drupal\Core\Plugin\PluginFormInterface;
 use Drupal\search\SearchPluginManager;
 use Drupal\Core\Form\ConfigFormBase;
@@ -276,4 +277,20 @@ public function searchAdminReindexSubmit(array $form, array &$form_state) {
     $form_state['redirect'] = 'admin/config/search/settings/reindex';
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    $config_names = array('search.settings');
+
+    // Handle per-plugin submission logic.
+    foreach ($this->searchPluginManager->getActivePlugins() as $plugin) {
+      if ($plugin instanceof PluginConfigFormInterface) {
+        $config_names = array_merge($config_names, $plugin->getConfigNames());
+      }
+    }
+
+    return array_unique($config_names);
+  }
+
 }
diff --git a/core/modules/search/tests/modules/search_extra_type/lib/Drupal/search_extra_type/Plugin/Search/SearchExtraTypeSearch.php b/core/modules/search/tests/modules/search_extra_type/lib/Drupal/search_extra_type/Plugin/Search/SearchExtraTypeSearch.php
index 2ea35eb..7222ccd 100644
--- a/core/modules/search/tests/modules/search_extra_type/lib/Drupal/search_extra_type/Plugin/Search/SearchExtraTypeSearch.php
+++ b/core/modules/search/tests/modules/search_extra_type/lib/Drupal/search_extra_type/Plugin/Search/SearchExtraTypeSearch.php
@@ -7,11 +7,9 @@
 
 namespace Drupal\search_extra_type\Plugin\Search;
 
-use Drupal\Core\Annotation\Translation;
 use Drupal\Core\Config\Config;
-use Drupal\Core\Plugin\PluginFormInterface;
+use Drupal\Core\Plugin\PluginConfigFormInterface;
 use Drupal\search\Plugin\SearchPluginBase;
-use Drupal\search\Annotation\SearchPlugin;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -23,7 +21,7 @@
  *   path = "dummy_path"
  * )
  */
-class SearchExtraTypeSearch extends SearchPluginBase implements PluginFormInterface {
+class SearchExtraTypeSearch extends SearchPluginBase implements PluginConfigFormInterface {
 
   /**
    * @var \Drupal\Core\Config\Config
@@ -160,4 +158,11 @@ public function submitConfigurationForm(array &$form, array &$form_state) {
       ->save();
   }
 
+  /**
+   * @inheritdoc
+   */
+  public function getConfigNames() {
+    return array('search_extra_type.settings');
+  }
+
 }
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/Form/SimpletestSettingsForm.php b/core/modules/simpletest/lib/Drupal/simpletest/Form/SimpletestSettingsForm.php
index ed65884..f2fa16b 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/Form/SimpletestSettingsForm.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/Form/SimpletestSettingsForm.php
@@ -118,4 +118,11 @@ public function submitForm(array &$form, array &$form_state) {
     parent::submitForm($form, $form_state);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    return array('simpletest.settings');
+  }
+
 }
diff --git a/core/modules/statistics/lib/Drupal/statistics/StatisticsSettingsForm.php b/core/modules/statistics/lib/Drupal/statistics/StatisticsSettingsForm.php
index 437946f..7722996 100644
--- a/core/modules/statistics/lib/Drupal/statistics/StatisticsSettingsForm.php
+++ b/core/modules/statistics/lib/Drupal/statistics/StatisticsSettingsForm.php
@@ -96,4 +96,11 @@ public function submitForm(array &$form, array &$form_state) {
     parent::submitForm($form, $form_state);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    return array('statistics.settings');
+  }
+
 }
diff --git a/core/modules/system/lib/Drupal/system/Form/CronForm.php b/core/modules/system/lib/Drupal/system/Form/CronForm.php
index 12802e4..a79f74b 100644
--- a/core/modules/system/lib/Drupal/system/Form/CronForm.php
+++ b/core/modules/system/lib/Drupal/system/Form/CronForm.php
@@ -124,4 +124,11 @@ public function submitCron(array &$form, array &$form_state) {
     return new RedirectResponse(url('admin/config/system/cron', array('absolute' => TRUE)));
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    return array('system.cron');
+  }
+
 }
diff --git a/core/modules/system/lib/Drupal/system/Form/FileSystemForm.php b/core/modules/system/lib/Drupal/system/Form/FileSystemForm.php
index 100c921..e891306 100644
--- a/core/modules/system/lib/Drupal/system/Form/FileSystemForm.php
+++ b/core/modules/system/lib/Drupal/system/Form/FileSystemForm.php
@@ -87,4 +87,11 @@ public function submitForm(array &$form, array &$form_state) {
     parent::submitForm($form, $form_state);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    return array('system.file');
+  }
+
 }
diff --git a/core/modules/system/lib/Drupal/system/Form/ImageToolkitForm.php b/core/modules/system/lib/Drupal/system/Form/ImageToolkitForm.php
index dcdb2cc..63931eb 100644
--- a/core/modules/system/lib/Drupal/system/Form/ImageToolkitForm.php
+++ b/core/modules/system/lib/Drupal/system/Form/ImageToolkitForm.php
@@ -109,4 +109,11 @@ public function submitForm(array &$form, array &$form_state) {
     parent::submitForm($form, $form_state);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    return array('system.image');
+  }
+
 }
diff --git a/core/modules/system/lib/Drupal/system/Form/LoggingForm.php b/core/modules/system/lib/Drupal/system/Form/LoggingForm.php
index f4860cf..8140dc5 100644
--- a/core/modules/system/lib/Drupal/system/Form/LoggingForm.php
+++ b/core/modules/system/lib/Drupal/system/Form/LoggingForm.php
@@ -53,4 +53,11 @@ public function submitForm(array &$form, array &$form_state) {
     parent::submitForm($form, $form_state);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    return array('system.logging');
+  }
+
 }
diff --git a/core/modules/system/lib/Drupal/system/Form/PerformanceForm.php b/core/modules/system/lib/Drupal/system/Form/PerformanceForm.php
index ff4e8fd..340d88d 100644
--- a/core/modules/system/lib/Drupal/system/Form/PerformanceForm.php
+++ b/core/modules/system/lib/Drupal/system/Form/PerformanceForm.php
@@ -168,4 +168,11 @@ public function submitCacheClear(array &$form, array &$form_state) {
     drupal_set_message(t('Caches cleared.'));
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    return array('system.performance');
+  }
+
 }
diff --git a/core/modules/system/lib/Drupal/system/Form/RegionalForm.php b/core/modules/system/lib/Drupal/system/Form/RegionalForm.php
index 569a5c6..d013bfe 100644
--- a/core/modules/system/lib/Drupal/system/Form/RegionalForm.php
+++ b/core/modules/system/lib/Drupal/system/Form/RegionalForm.php
@@ -156,4 +156,11 @@ public function submitForm(array &$form, array &$form_state) {
     parent::submitForm($form, $form_state);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    return array('system.date');
+  }
+
 }
diff --git a/core/modules/system/lib/Drupal/system/Form/RssFeedsForm.php b/core/modules/system/lib/Drupal/system/Form/RssFeedsForm.php
index b3ef82b..445cf15 100644
--- a/core/modules/system/lib/Drupal/system/Form/RssFeedsForm.php
+++ b/core/modules/system/lib/Drupal/system/Form/RssFeedsForm.php
@@ -67,4 +67,11 @@ public function submitForm(array &$form, array &$form_state) {
     parent::submitForm($form, $form_state);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    return array('system.rss');
+  }
+
 }
diff --git a/core/modules/system/lib/Drupal/system/Form/SiteInformationForm.php b/core/modules/system/lib/Drupal/system/Form/SiteInformationForm.php
index 1b5029b..38ebeb9 100644
--- a/core/modules/system/lib/Drupal/system/Form/SiteInformationForm.php
+++ b/core/modules/system/lib/Drupal/system/Form/SiteInformationForm.php
@@ -181,4 +181,11 @@ public function submitForm(array &$form, array &$form_state) {
     parent::submitForm($form, $form_state);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    return array('system.site');
+  }
+
 }
diff --git a/core/modules/system/lib/Drupal/system/Form/SiteMaintenanceModeForm.php b/core/modules/system/lib/Drupal/system/Form/SiteMaintenanceModeForm.php
index 131af5b..c28a023 100644
--- a/core/modules/system/lib/Drupal/system/Form/SiteMaintenanceModeForm.php
+++ b/core/modules/system/lib/Drupal/system/Form/SiteMaintenanceModeForm.php
@@ -89,4 +89,11 @@ public function submitForm(array &$form, array &$form_state) {
     parent::submitForm($form, $form_state);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    return array('system.maintenance');
+  }
+
 }
diff --git a/core/modules/system/lib/Drupal/system/Form/ThemeSettingsForm.php b/core/modules/system/lib/Drupal/system/Form/ThemeSettingsForm.php
index 44b34fe..23a419b 100644
--- a/core/modules/system/lib/Drupal/system/Form/ThemeSettingsForm.php
+++ b/core/modules/system/lib/Drupal/system/Form/ThemeSettingsForm.php
@@ -454,4 +454,18 @@ protected function validatePath($path) {
     return FALSE;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    $configNames = array('system.theme.global');
+
+    $themes = list_themes();
+    foreach ($themes as $theme_name => $theme) {
+      $configNames[] = $theme_name . '.settings';
+    }
+
+    return $configNames;
+  }
+
 }
diff --git a/core/modules/system/tests/modules/form_test/lib/Drupal/form_test/SystemConfigFormTestForm.php b/core/modules/system/tests/modules/form_test/lib/Drupal/form_test/SystemConfigFormTestForm.php
index 9330682..30a891d 100644
--- a/core/modules/system/tests/modules/form_test/lib/Drupal/form_test/SystemConfigFormTestForm.php
+++ b/core/modules/system/tests/modules/form_test/lib/Drupal/form_test/SystemConfigFormTestForm.php
@@ -21,4 +21,11 @@ public function getFormID() {
     return 'form_test_system_config_test_form';
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    return array();
+  }
+
 }
diff --git a/core/modules/update/lib/Drupal/update/UpdateSettingsForm.php b/core/modules/update/lib/Drupal/update/UpdateSettingsForm.php
index d2f80d1..7a92eae 100644
--- a/core/modules/update/lib/Drupal/update/UpdateSettingsForm.php
+++ b/core/modules/update/lib/Drupal/update/UpdateSettingsForm.php
@@ -121,4 +121,11 @@ public function submitForm(array &$form, array &$form_state) {
     parent::submitForm($form, $form_state);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    return array('update.settings');
+  }
+
 }
diff --git a/core/modules/user/lib/Drupal/user/AccountSettingsForm.php b/core/modules/user/lib/Drupal/user/AccountSettingsForm.php
index e8077d3..fbf2e65 100644
--- a/core/modules/user/lib/Drupal/user/AccountSettingsForm.php
+++ b/core/modules/user/lib/Drupal/user/AccountSettingsForm.php
@@ -445,4 +445,11 @@ public function submitForm(array &$form, array &$form_state) {
       ->save();
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    return array('user.settings', 'user.mail', 'system.site');
+  }
+
 }
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Form/AdvancedSettingsForm.php b/core/modules/views_ui/lib/Drupal/views_ui/Form/AdvancedSettingsForm.php
index fd77d5e..5fd7506 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/Form/AdvancedSettingsForm.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/Form/AdvancedSettingsForm.php
@@ -103,4 +103,11 @@ public function cacheSubmit() {
     drupal_set_message($this->t('The cache has been cleared.'));
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    return array('views.settings');
+  }
+
 }
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Form/BasicSettingsForm.php b/core/modules/views_ui/lib/Drupal/views_ui/Form/BasicSettingsForm.php
index d1206d5..dfc83ca 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/Form/BasicSettingsForm.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/Form/BasicSettingsForm.php
@@ -142,4 +142,11 @@ public function submitForm(array &$form, array &$form_state) {
       ->save();
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigNames() {
+    return array('views.settings');
+  }
+
 }
