diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Form/SettingsForm.php b/core/modules/aggregator/lib/Drupal/aggregator/Form/SettingsForm.php
index 9a5cbde..3d753c2 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Form/SettingsForm.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Form/SettingsForm.php
@@ -7,9 +7,11 @@
 
 namespace Drupal\aggregator\Form;
 
-use Drupal\system\SystemConfigFormBase;
+use Drupal\Core\Form\FormInterface;
 use Drupal\Core\Config\ConfigFactory;
+use Drupal\system\SystemConfigFormBase;
 use Drupal\aggregator\Plugin\AggregatorPluginManager;
+use Drupal\Component\Utility\String;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -36,6 +38,13 @@ class SettingsForm extends SystemConfigFormBase {
   );
 
   /**
+   * The instanciated plugin instances.
+   *
+   * @var array
+   */
+  protected $instances = array();
+
+  /**
    * Constructs a \Drupal\aggregator\SettingsForm object.
    *
    * @param \Drupal\Core\Config\ConfigFactory $config_factory
@@ -57,13 +66,13 @@ public function __construct(ConfigFactory $config_factory, AggregatorPluginManag
     // Get all available fetcher, parser and processor definitions.
     foreach (array('fetcher', 'parser', 'processor') as $type) {
       foreach ($this->managers[$type]->getDefinitions() as $id => $definition) {
-        $this->definitions[$type][$id] = format_string('@title <span class="description">@description</span>', array('@title' => $definition['title'], '@description' => $definition['description']));
+        $this->definitions[$type][$id] = String::format('@title <span class="description">@description</span>', array('@title' => $definition['title'], '@description' => $definition['description']));
       }
     }
   }
 
   /**
-   * Implements \Drupal\Core\ControllerInterface::create().
+   * {@inheritdoc}
    */
   public static function create(ContainerInterface $container) {
     return new static(
@@ -75,14 +84,14 @@ public static function create(ContainerInterface $container) {
   }
 
   /**
-   * Implements \Drupal\Core\Form\FormInterface::getFormID().
+   * {@inheritdoc}
    */
   public function getFormID() {
     return 'aggregator_admin_form';
   }
 
   /**
-   * Implements \Drupal\Core\Form\FormInterface::buildForm().
+   * {@inheritdoc}
    */
   public function buildForm(array $form, array &$form_state) {
     $config = $this->configFactory->get('aggregator.settings');
@@ -136,28 +145,56 @@ public function buildForm(array $form, array &$form_state) {
       $form['basic_conf'] += $basic_conf;
     }
 
+    // Call buildForm() 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 FormInterface) {
+          $form = $instance->buildForm($form, $form_state);
+          // Store the instance for validate and submit handlers.
+          $this->instances[] = $instance;
+        }
+      }
+    }
+
     // Implementing processor plugins will expect an array at $form['processors'].
     $form['processors'] = array();
-    // Call settingsForm() for each active processor.
+    // Call buildForm() for each active processor.
     foreach ($this->definitions['processor'] as $id => $definition) {
       if (in_array($id, $config->get('processors'))) {
-        $form = $this->managers['processor']->createInstance($id)->settingsForm($form, $form_state);
+        $instance = $this->managers['processor']->createInstance($id);
+        if ($instance instanceof FormInterface) {
+          $form = $instance->buildForm($form, $form_state);
+          // Store the instance for validate and submit handlers.
+          $this->instances[] = $instance;
+        }
       }
     }
     return parent::buildForm($form, $form_state);
   }
 
   /**
-   * Implements \Drupal\Core\Form\FormInterface::submitForm().
+   * {@inheritdoc}
+   */
+  public function validateForm(array &$form, array &$form_state) {
+    parent::validateForm($form, $form_state);
+    // Let active plugins validate their settings.
+    foreach ($this->instances as $instance) {
+      $instance->validateForm($form, $form_state);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
    */
   public function submitForm(array &$form, array &$form_state) {
     parent::submitForm($form, $form_state);
     $config = $this->configFactory->get('aggregator.settings');
-    // Let active processors save their settings.
-    foreach ($this->definitions['processor'] as $id => $definition) {
-      if (in_array($id, $config->get('processors'))) {
-        $this->managers['processor']->createInstance($id)->settingsSubmit($form, $form_state);
-      }
+
+    // Let active plugins save their settings.
+    foreach ($this->instances as $instance) {
+      $instance->submitForm($form, $form_state);
     }
 
     $config->set('items.allowed_html', $form_state['values']['aggregator_allowed_html_tags']);
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/AggregatorPluginSettingsBase.php b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/AggregatorPluginSettingsBase.php
new file mode 100644
index 0000000..9a1c4b2
--- /dev/null
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/AggregatorPluginSettingsBase.php
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\aggregator\Plugin\AggregatorPluginSettingsBase.
+ */
+
+namespace Drupal\aggregator\Plugin;
+
+use Drupal\Component\Plugin\PluginBase;
+use Drupal\Core\Form\FormInterface;
+
+/**
+ * Base class for aggregator's plugin implementations.
+ */
+abstract class AggregatorPluginSettingsBase extends PluginBase implements FormInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormID() {
+    return 'aggregator_admin_form';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, array &$form_state) {
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateForm(array &$form, array &$form_state) {}
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, array &$form_state) {}
+
+}
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/ProcessorInterface.php b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/ProcessorInterface.php
index b670383..844abb0 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/ProcessorInterface.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/ProcessorInterface.php
@@ -21,31 +21,6 @@
 interface ProcessorInterface {
 
   /**
-   * Returns a form to configure settings for the processor.
-   *
-   * @param array $form
-   *   The form definition array where the settings form is being included in.
-   * @param array $form_state
-   *   An associative array containing the current state of the form.
-   *
-   * @return array
-   *   The form elements for the processor settings.
-   */
-  public function settingsForm(array $form, array &$form_state);
-
-  /**
-   * Adds processor specific submission handling for the configuration form.
-   *
-   * @param array $form
-   *   The form definition array where the settings form is being included in.
-   * @param array $form_state
-   *   An associative array containing the current state of the form.
-   *
-   * @see \Drupal\aggregator\Plugin\ProcessorInterface::settingsForm()
-   */
-  public function settingsSubmit(array $form, array &$form_state);
-
-  /**
    * Processes feed data.
    *
    * @param \Drupal\aggregator\Plugin\Core\Entity\Feed $feed
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/fetcher/DefaultFetcher.php b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/fetcher/DefaultFetcher.php
index e71412b..79035ff 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/fetcher/DefaultFetcher.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/fetcher/DefaultFetcher.php
@@ -28,7 +28,7 @@
 class DefaultFetcher implements FetcherInterface {
 
   /**
-   * Implements \Drupal\aggregator\Plugin\FetcherInterface::fetch().
+   * {@inheritdoc}
    */
   public function fetch(Feed $feed) {
     // @todo: Inject the http client.
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/parser/DefaultParser.php b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/parser/DefaultParser.php
index 0086bac..82cf12d 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/parser/DefaultParser.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/parser/DefaultParser.php
@@ -68,7 +68,7 @@ class DefaultParser implements ParserInterface {
   protected $item;
 
   /**
-   * Implements \Drupal\aggregator\Plugin\ParserInterface::parse().
+   * {@inheritdoc}
    */
   public function parse(Feed $feed) {
     // Filter the input data.
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 08777d1..9cb03d0 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
@@ -7,8 +7,8 @@
 
 namespace Drupal\aggregator\Plugin\aggregator\processor;
 
-use Drupal\Component\Plugin\PluginBase;
 use Drupal\aggregator\Plugin\ProcessorInterface;
+use Drupal\aggregator\Plugin\AggregatorPluginSettingsBase;
 use Drupal\aggregator\Plugin\Core\Entity\Feed;
 use Drupal\Component\Annotation\Plugin;
 use Drupal\Core\Annotation\Translation;
@@ -25,12 +25,12 @@
  *   description = @Translation("Creates lightweight records from feed items.")
  * )
  */
-class DefaultProcessor extends PluginBase implements ProcessorInterface {
+class DefaultProcessor extends AggregatorPluginSettingsBase implements ProcessorInterface {
 
   /**
-   * Implements \Drupal\aggregator\Plugin\ProcessorInterface::settingsForm().
+   * {@inheritdoc}
    */
-  public function settingsForm(array $form, array &$form_state) {
+  public function buildForm(array $form, array &$form_state) {
     $config = config('aggregator.settings');
     $processors = $config->get('processors');
     $info = $this->getDefinition();
@@ -84,9 +84,9 @@ public function settingsForm(array $form, array &$form_state) {
   }
 
   /**
-   * Implements \Drupal\aggregator\Plugin\ProcessorInterface::settingsSubmit().
+   * {@inheritdoc}
    */
-  public function settingsSubmit(array $form, array &$form_state) {
+  public function submitForm(array &$form, array &$form_state) {
     $config = config('aggregator.settings');
     $config->set('items.expire', $form_state['values']['aggregator_clear'])
       ->set('items.teaser_length', $form_state['values']['aggregator_teaser_length'])
@@ -96,7 +96,7 @@ public function settingsSubmit(array $form, array &$form_state) {
   }
 
   /**
-   * Implements \Drupal\aggregator\Plugin\ProcessorInterface::process().
+   * {@inheritdoc}
    */
   public function process(Feed $feed) {
     if (!is_array($feed->items)) {
@@ -147,7 +147,7 @@ public function process(Feed $feed) {
   }
 
   /**
-   * Implements \Drupal\aggregator\Plugin\ProcessorInterface::remove().
+   * {@inheritdoc}
    */
   public function remove(Feed $feed) {
     $iids = Database::getConnection()->query('SELECT iid FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->id()))->fetchCol();
@@ -159,9 +159,7 @@ public function remove(Feed $feed) {
   }
 
   /**
-   * Implements \Drupal\aggregator\Plugin\ProcessorInterface::postProcess().
-   *
-   * Expires items from a feed depending on expiration settings.
+   * {@inheritdoc}
    */
   public function postProcess(Feed $feed) {
     $aggregator_clear = config('aggregator.settings')->get('items.expire');
diff --git a/core/modules/aggregator/tests/lib/Drupal/aggregator_test/Plugin/aggregator/processor/TestProcessor.php b/core/modules/aggregator/tests/lib/Drupal/aggregator_test/Plugin/aggregator/processor/TestProcessor.php
index 3ffe213..cb4af64 100644
--- a/core/modules/aggregator/tests/lib/Drupal/aggregator_test/Plugin/aggregator/processor/TestProcessor.php
+++ b/core/modules/aggregator/tests/lib/Drupal/aggregator_test/Plugin/aggregator/processor/TestProcessor.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\aggregator_test\Plugin\aggregator\processor;
 
-use Drupal\Component\Plugin\PluginBase;
+use Drupal\aggregator\Plugin\AggregatorPluginSettingsBase;
 use Drupal\aggregator\Plugin\ProcessorInterface;
 use Drupal\aggregator\Plugin\Core\Entity\Feed;
 use Drupal\Component\Annotation\Plugin;
@@ -24,12 +24,12 @@
  *   description = @Translation("Test generic processor functionality.")
  * )
  */
-class TestProcessor extends PluginBase implements ProcessorInterface {
+class TestProcessor extends AggregatorPluginSettingsBase implements ProcessorInterface {
 
   /**
-   * Implements \Drupal\aggregator\Plugin\ProcessorInterface::settingsForm().
+   * {@inheritdoc}
    */
-  public function settingsForm(array $form, array &$form_state) {
+  public function buildForm(array $form, array &$form_state) {
     $config = config('aggregator.settings');
     $processors = $config->get('processors');
     $info = $this->getDefinition();
@@ -40,7 +40,7 @@ public function settingsForm(array $form, array &$form_state) {
       '#description' => $info['description'],
       '#collapsed' => !in_array($info['id'], $processors),
     );
-    // Add some dummy settings to verify settingsForm is called.
+    // Add some dummy settings to verify buildForm is called.
     $form['processors'][$info['id']]['dummy_length'] = array(
       '#title' => t('Dummy length setting'),
       '#type' => 'number',
@@ -52,16 +52,16 @@ public function settingsForm(array $form, array &$form_state) {
   }
 
   /**
-   * Implements \Drupal\aggregator\Plugin\ProcessorInterface::settingsSubmit().
+   * {@inheritdoc}
    */
-  public function settingsSubmit(array $form, array &$form_state) {
+  public function submitForm(array &$form, array &$form_state) {
     config('aggregator_test.settings')
       ->set('items.dummy_length', $form_state['values']['dummy_length'])
       ->save();
   }
 
   /**
-   * Implements \Drupal\aggregator\Plugin\ProcessorInterface::process().
+   * {@inheritdoc}
    */
   public function process(Feed $feed) {
     foreach ($feed->items as &$item) {
@@ -71,7 +71,7 @@ public function process(Feed $feed) {
   }
 
   /**
-   * Implements \Drupal\aggregator\Plugin\ProcessorInterface::remove().
+   * {@inheritdoc}
    */
   public function remove(Feed $feed) {
     // Append a random number, just to change the feed description.
@@ -79,7 +79,7 @@ public function remove(Feed $feed) {
   }
 
   /**
-   * Implements \Drupal\aggregator\Plugin\ProcessorInterface::postProcess().
+   * {@inheritdoc}
    */
   public function postProcess(Feed $feed) {
     // Double the refresh rate.
