diff --git a/core/lib/Drupal/Component/Plugin/Discovery/ProcessDecorator.php b/core/lib/Drupal/Component/Plugin/Discovery/ProcessDecorator.php
new file mode 100644
index 0000000..2e31dbc
--- /dev/null
+++ b/core/lib/Drupal/Component/Plugin/Discovery/ProcessDecorator.php
@@ -0,0 +1,71 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Component\Plugin\Discovery\ProcessDecorator.
+ */
+
+namespace Drupal\Component\Plugin\Discovery;
+
+/**
+ * Allows custom processing of the discovered definition..
+ */
+class ProcessDecorator implements DiscoveryInterface {
+
+  /**
+   * The Discovery object being decorated.
+   *
+   * @var \Drupal\Component\Plugin\Discovery\DiscoveryInterface
+   */
+  protected $decorated;
+
+  /**
+   * The processor function to run on each discovered definition.
+   *
+   * @var callable
+   */
+   protected $processFunction;
+
+  /**
+   * Constructs a \Drupal\Component\Plugin\Discovery\ProcessDecorator object.
+   *
+   * @param \Drupal\Component\Plugin\Discovery\DiscoveryInterface $decorated
+   *   The discovery object that is being decorated.
+   * @param callable $process_function
+   *   The processor function to run on each discovered definition. The
+   *   function will be called with the following arguments:
+   *   - array $definition: the discovered definition, that the function
+   *     should accept by reference and modify in place.
+   *   - string $plugin_id: the corresponding plugin_id.
+   */
+  public function __construct(DiscoveryInterface $decorated, $process_function) {
+    $this->decorated = $decorated;
+    $this->processFunction = $process_function;
+  }
+
+  /**
+   * Implements \Drupal\Component\Plugin\Discovery\DicoveryInterface::getDefinition().
+   */
+  public function getDefinition($plugin_id) {
+    $definitions = $this->getDefinitions();
+    return isset($definitions[$plugin_id]) ? $definitions[$plugin_id] : NULL;
+  }
+
+  /**
+   * Implements \Drupal\Component\Plugin\Discovery\DicoveryInterface::getDefinitions().
+   */
+  public function getDefinitions() {
+    $definitions = $this->decorated->getDefinitions();
+    foreach ($definitions as $plugin_id => &$definition) {
+      call_user_func_array($this->processFunction, array(&$definition, $plugin_id));
+    }
+    return $definitions;
+  }
+
+  /**
+   * Passes through all unknown calls onto the decorated object.
+   */
+  public function __call($method, $args) {
+    return call_user_func_array(array($this->decorated, $method), $args);
+  }
+}
diff --git a/core/lib/Drupal/Component/Plugin/PluginManagerBase.php b/core/lib/Drupal/Component/Plugin/PluginManagerBase.php
index e4131fc..f19b34d 100644
--- a/core/lib/Drupal/Component/Plugin/PluginManagerBase.php
+++ b/core/lib/Drupal/Component/Plugin/PluginManagerBase.php
@@ -48,23 +48,14 @@
    * Implements Drupal\Component\Plugin\PluginManagerInterface::getDefinition().
    */
   public function getDefinition($plugin_id) {
-    $definition = $this->discovery->getDefinition($plugin_id);
-    if (isset($definition)) {
-      $this->processDefinition($definition, $plugin_id);
-    }
-    return $definition;
+    return $this->discovery->getDefinition($plugin_id);;
   }
 
   /**
    * Implements Drupal\Component\Plugin\PluginManagerInterface::getDefinitions().
    */
   public function getDefinitions() {
-    $definitions = $this->discovery->getDefinitions();
-    foreach ($definitions as $plugin_id => &$definition) {
-      $this->processDefinition($definition, $plugin_id);
-    }
-
-    return $definitions;
+    return $this->discovery->getDefinitions();
   }
 
   /**
@@ -88,7 +79,7 @@ public function getInstance(array $options) {
    * additional processing logic they can do that by replacing or extending the
    * method.
    */
-  protected function processDefinition(&$definition, $plugin_id) {
+  public function processDefinition(&$definition, $plugin_id) {
     $definition = NestedArray::mergeDeep($this->defaults, $definition);
   }
 
diff --git a/core/lib/Drupal/Core/Entity/EntityManager.php b/core/lib/Drupal/Core/Entity/EntityManager.php
index e34adb6..76398a4 100644
--- a/core/lib/Drupal/Core/Entity/EntityManager.php
+++ b/core/lib/Drupal/Core/Entity/EntityManager.php
@@ -9,6 +9,7 @@
 
 use Drupal\Component\Plugin\PluginManagerBase;
 use Drupal\Component\Plugin\Factory\DefaultFactory;
+use Drupal\Component\Plugin\Discovery\ProcessDecorator;
 use Drupal\Core\Plugin\Discovery\AlterDecorator;
 use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
 use Drupal\Core\Plugin\Discovery\InfoHookDecorator;
@@ -223,7 +224,10 @@ class EntityManager extends PluginManagerBase {
    */
   public function __construct() {
     // Allow the plugin definition to be altered by hook_entity_info_alter().
-    $this->discovery = new AlterDecorator(new InfoHookDecorator(new AnnotatedClassDiscovery('Core', 'Entity'), 'entity_info'), 'entity_info');
+    $this->discovery = new AnnotatedClassDiscovery('Core', 'Entity');
+    $this->discovery = new InfoHookDecorator($this->discovery, 'entity_info');
+    $this->discovery = new AlterDecorator($this->discovery, 'entity_info');
+    $this->discovery = new ProcessDecorator($this->discovery, array($this, 'processDefinition'));
     $this->factory = new DefaultFactory($this);
 
     // Entity type plugins includes translated strings, so each language is
@@ -261,7 +265,7 @@ public function getDefinitions() {
   /**
    * Overrides Drupal\Component\Plugin\PluginManagerBase::processDefinition().
    */
-  protected function processDefinition(&$definition, $plugin_id) {
+  public function processDefinition(&$definition, $plugin_id) {
     parent::processDefinition($definition, $plugin_id);
 
     // @todo Remove this check once http://drupal.org/node/1780396 is resolved.
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php
index 6dc4163..8ec226d 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php
@@ -8,10 +8,11 @@
 namespace Drupal\field\Plugin\Type\Formatter;
 
 use Drupal\Component\Plugin\PluginManagerBase;
+use Drupal\Component\Plugin\Discovery\ProcessDecorator;
 use Drupal\Core\Plugin\Discovery\CacheDecorator;
+use Drupal\Core\Plugin\Discovery\AlterDecorator;
 use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
 use Drupal\field\Plugin\Type\Formatter\FormatterLegacyDiscoveryDecorator;
-use Drupal\Core\Plugin\Discovery\AlterDecorator;
 
 /**
  * Plugin type manager for field formatters.
@@ -44,7 +45,10 @@ class FormatterPluginManager extends PluginManagerBase {
    * Constructs a FormatterPluginManager object.
    */
   public function __construct() {
-    $this->baseDiscovery = new AlterDecorator(new FormatterLegacyDiscoveryDecorator(new AnnotatedClassDiscovery('field', 'formatter')), 'field_formatter_info');
+    $this->baseDiscovery = new AnnotatedClassDiscovery('field', 'formatter');
+    $this->baseDiscovery = new FormatterLegacyDiscoveryDecorator($this->baseDiscovery);
+    $this->baseDiscovery = new AlterDecorator($this->baseDiscovery, 'field_formatter_info');
+    $this->baseDiscovery = new ProcessDecorator($this->baseDiscovery, array($this, 'processDefinition'));
     $this->discovery = new CacheDecorator($this->baseDiscovery, $this->cache_id, $this->cache_bin);
 
     $this->factory = new FormatterFactory($this);
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetPluginManager.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetPluginManager.php
index a605129..0879282 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetPluginManager.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetPluginManager.php
@@ -8,6 +8,7 @@
 namespace Drupal\field\Plugin\Type\Widget;
 
 use Drupal\Component\Plugin\PluginManagerBase;
+use Drupal\Component\Plugin\Discovery\ProcessDecorator;
 use Drupal\Core\Plugin\Discovery\CacheDecorator;
 use Drupal\Core\Plugin\Discovery\AlterDecorator;
 use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
@@ -45,7 +46,10 @@ class WidgetPluginManager extends PluginManagerBase {
    * Constructs a WidgetPluginManager object.
    */
   public function __construct() {
-    $this->baseDiscovery = new AlterDecorator(new WidgetLegacyDiscoveryDecorator(new AnnotatedClassDiscovery('field', 'widget')), 'field_widget_info');
+    $this->baseDiscovery = new AnnotatedClassDiscovery('field', 'widget');
+    $this->baseDiscovery = new WidgetLegacyDiscoveryDecorator($this->baseDiscovery);
+    $this->baseDiscovery = new AlterDecorator($this->baseDiscovery, 'field_widget_info');
+    $this->baseDiscovery = new ProcessDecorator($this->baseDiscovery, array($this, 'processDefinition'));
     $this->discovery = new CacheDecorator($this->baseDiscovery, $this->cache_id, $this->cache_bin);
 
     $this->factory = new WidgetFactory($this);
diff --git a/core/modules/layout/lib/Drupal/layout/Plugin/Type/LayoutManager.php b/core/modules/layout/lib/Drupal/layout/Plugin/Type/LayoutManager.php
index e58ad4b..8446fa8 100644
--- a/core/modules/layout/lib/Drupal/layout/Plugin/Type/LayoutManager.php
+++ b/core/modules/layout/lib/Drupal/layout/Plugin/Type/LayoutManager.php
@@ -9,6 +9,7 @@
 
 use Drupal\Component\Plugin\PluginManagerBase;
 use Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator;
+use Drupal\Component\Plugin\Discovery\ProcessDecorator;
 use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
 use Drupal\Component\Plugin\Factory\ReflectionFactory;
 
@@ -26,7 +27,10 @@ class LayoutManager extends PluginManagerBase {
    */
   public function __construct() {
     // Create layout plugin derivatives from declaratively defined layouts.
-    $this->discovery = new DerivativeDiscoveryDecorator(new AnnotatedClassDiscovery('layout', 'layout'));
+    $this->discovery = new AnnotatedClassDiscovery('layout', 'layout');
+    $this->discovery = new DerivativeDiscoveryDecorator($this->discovery);
+    $this->discovery = new ProcessDecorator($this->discovery, array($this, 'processDefinition'));
+
     $this->factory = new ReflectionFactory($this);
   }
 }
diff --git a/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/DefaultsTestPluginManager.php b/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/DefaultsTestPluginManager.php
index 607b100..a449c81 100644
--- a/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/DefaultsTestPluginManager.php
+++ b/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/DefaultsTestPluginManager.php
@@ -9,6 +9,7 @@
 
 use Drupal\Component\Plugin\PluginManagerBase;
 use Drupal\Component\Plugin\Discovery\StaticDiscovery;
+use Drupal\Component\Plugin\Discovery\ProcessDecorator;
 use Drupal\Component\Plugin\Factory\DefaultFactory;
 
 /**
@@ -22,6 +23,7 @@ public function __construct() {
     // discovery implementation, but StaticDiscovery lets us add some simple
     // mock plugins for unit testing.
     $this->discovery = new StaticDiscovery();
+    $this->discovery = new ProcessDecorator($this->discovery, array($this, 'ProcessDefinition'));
     $this->factory = new DefaultFactory($this);
 
     // Specify default values.
diff --git a/core/modules/views/lib/Drupal/views/Plugin/Type/JoinManager.php b/core/modules/views/lib/Drupal/views/Plugin/Type/JoinManager.php
index eac395b..2ed3f99 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/Type/JoinManager.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/Type/JoinManager.php
@@ -9,6 +9,7 @@
 
 use Drupal\Component\Plugin\PluginManagerBase;
 use Drupal\Component\Plugin\Factory\DefaultFactory;
+use Drupal\Component\Plugin\Discovery\ProcessDecorator;
 use Drupal\Core\Plugin\Discovery\AlterDecorator;
 use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
 use Drupal\Core\Plugin\Discovery\CacheDecorator;
@@ -19,7 +20,11 @@ class JoinManager extends PluginManagerBase {
    * Constructs a JoinManager object.
    */
   public function __construct() {
-    $this->discovery = new CacheDecorator(new AlterDecorator(new AnnotatedClassDiscovery('views', 'join'), 'views_plugins_join'), 'views:join', 'views_info');
+    $this->discovery = new AnnotatedClassDiscovery('views', 'join');
+    $this->discovery = new AlterDecorator($this->discovery, 'views_plugins_join');
+    $this->discovery = new ProcessDecorator($this->discovery, array($this, 'processDefinition'));
+    $this->discovery = new CacheDecorator($this->discovery, 'views:join', 'views_info');
+
     $this->factory = new DefaultFactory($this);
     $this->defaults = array(
       'module' => 'views',
diff --git a/core/modules/views/lib/Drupal/views/Plugin/Type/PluginManager.php b/core/modules/views/lib/Drupal/views/Plugin/Type/PluginManager.php
index f5f6f6e..354c106 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/Type/PluginManager.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/Type/PluginManager.php
@@ -9,6 +9,7 @@
 
 use Drupal\Component\Plugin\PluginManagerBase;
 use Drupal\Component\Plugin\Factory\DefaultFactory;
+use Drupal\Component\Plugin\Discovery\ProcessDecorator;
 use Drupal\Core\Plugin\Discovery\AlterDecorator;
 use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
 use Drupal\Core\Plugin\Discovery\CacheDecorator;
@@ -19,7 +20,11 @@ class PluginManager extends PluginManagerBase {
    * Constructs a PluginManager object.
    */
   public function __construct($type) {
-    $this->discovery = new CacheDecorator(new AlterDecorator(new AnnotatedClassDiscovery('views', $type), 'views_plugins_' . $type), 'views:' . $type, 'views_info');
+    $this->discovery = new AnnotatedClassDiscovery('views', $type);
+    $this->discovery = new AlterDecorator($this->discovery, 'views_plugins_' . $type);
+    $this->discovery = new ProcessDecorator($this->discovery, array($this, 'processDefinition'));
+    $this->discovery = new CacheDecorator($this->discovery, 'views:' . $type, 'views_info');
+
     $this->factory = new DefaultFactory($this);
     $this->defaults += array(
       'parent' => 'parent',
diff --git a/core/modules/views/lib/Drupal/views/Plugin/Type/WizardManager.php b/core/modules/views/lib/Drupal/views/Plugin/Type/WizardManager.php
index 96b544f..8a0aed5 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/Type/WizardManager.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/Type/WizardManager.php
@@ -9,6 +9,7 @@
 
 use Drupal\Component\Plugin\PluginManagerBase;
 use Drupal\Component\Plugin\Factory\DefaultFactory;
+use Drupal\Component\Plugin\Discovery\ProcessDecorator;
 use Drupal\Core\Plugin\Discovery\AlterDecorator;
 use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
 use Drupal\Core\Plugin\Discovery\CacheDecorator;
@@ -19,7 +20,10 @@ class WizardManager extends PluginManagerBase {
    * Constructs a WizardManager object.
    */
   public function __construct() {
-    $this->discovery = new CacheDecorator(new AlterDecorator(new AnnotatedClassDiscovery('views', 'wizard'), 'views_plugins_wizard'), 'views:wizard', 'views_info');
+    $this->discovery = new AnnotatedClassDiscovery('views', 'wizard');
+    $this->discovery = new AlterDecorator($this->discovery, 'views_plugins_wizard');
+    $this->discovery = new ProcessDecorator($this->discovery, array($this, 'processDefinition'));
+    $this->discovery = new CacheDecorator($this->discovery, 'views:wizard', 'views_info');
     $this->factory = new DefaultFactory($this);
     $this->defaults = array(
       'module' => 'views',
