 .../Plugin/Discovery/DefaultsDecorator.php         | 71 ++++++++++++++++++++++
 .../Drupal/Component/Plugin/PluginManagerBase.php  | 33 +---------
 .../Plugin/Type/Widget/WidgetPluginManager.php     | 19 +++---
 3 files changed, 81 insertions(+), 42 deletions(-)

diff --git a/core/lib/Drupal/Component/Plugin/Discovery/DefaultsDecorator.php b/core/lib/Drupal/Component/Plugin/Discovery/DefaultsDecorator.php
new file mode 100644
index 0000000..401031a
--- /dev/null
+++ b/core/lib/Drupal/Component/Plugin/Discovery/DefaultsDecorator.php
@@ -0,0 +1,71 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\Component\Plugin\Discovery\DefaultsDecorator.
+ */
+
+namespace Drupal\Component\Plugin\Discovery;
+
+use Drupal\Component\Utility\NestedArray;
+
+/**
+ * Discovery decorator that applies defaults to each plugin definition.
+ */
+class DefaultsDecorator implements DiscoveryInterface {
+
+  /**
+   * The parent object implementing DiscoveryInterface that is being decorated.
+   *
+   * @var \Drupal\Component\Plugin\Discovery\DiscoveryInterface
+   */
+  protected $decorated;
+
+  /**
+   * An array of defaults that will be added to each plugin definition.
+   *
+   * @var array
+   */
+  protected $defaults;
+
+  /**
+   * Constructs a DefaultsDecorator object.
+   *
+   * @param \Drupal\Component\Plugin\Discovery\DiscoveryInterface $discovery
+   *   The parent object implementing DiscoveryInterface that is being
+   *   decorated.
+   * @param array $defaults
+   *   An array of defaults that will be merged onto each plugin definition
+   *   using \Drupal\Component\Utility\NestedArray::mergeDeep().
+   */
+  public function __construct(DiscoveryInterface $decorated, $defaults) {
+    $this->decorated = $decorated;
+    $this->defaults = $defaults;
+  }
+
+  /**
+   * Implements Drupal\Component\Plugin\Discovery\DiscoveryInterface::getDefinition().
+   */
+  public function getDefinition($plugin_id) {
+    $definitions = $this->getDefinitions();
+    return isset($definitions[$plugin_id]) ? $definitions[$plugin_id] : NULL;
+  }
+
+  /**
+   * Implements Drupal\Component\Plugin\Discovery\DiscoveryInterface::getDefinitions().
+   */
+  public function getDefinitions() {
+    $definitions = $this->decorated->getDefinitions();
+    foreach ($definitions as $plugin_id => &$definition) {
+      $definition = NestedArray::mergeDeep($this->defaults, $definition);
+    }
+    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 73f1b55..b80a9e9 100644
--- a/core/lib/Drupal/Component/Plugin/PluginManagerBase.php
+++ b/core/lib/Drupal/Component/Plugin/PluginManagerBase.php
@@ -34,35 +34,17 @@
   protected $mapper;
 
   /**
-   * A set of defaults to be referenced by $this->processDefinition() if
-   * additional processing of plugins is necessary or helpful for development
-   * purposes.
-   *
-   * @var array
-   */
-  protected $defaults = array();
-
-  /**
    * 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();
   }
 
   /**
@@ -78,15 +60,4 @@ public function createInstance($plugin_id, array $configuration = array()) {
   public function getInstance(array $options) {
     return $this->mapper->getInstance($options);
   }
-
-  /**
-   * Performs extra processing on plugin definitions.
-   *
-   * By default we add defaults for the type to the definition. If a type has
-   * additional processing logic they can do that by replacing or extending the
-   * method.
-   */
-  protected function processDefinition(&$definition, $plugin_id) {
-    $definition += $this->defaults;
-  }
 }
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 d0410e0..b3b0008 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
@@ -7,6 +7,7 @@
 
 namespace Drupal\field\Plugin\Type\Widget;
 
+use Drupal\Component\Plugin\Discovery\DefaultsDecorator;
 use Drupal\Component\Plugin\PluginManagerBase;
 use Drupal\Core\Plugin\Discovery\CacheDecorator;
 use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
@@ -18,15 +19,6 @@
 class WidgetPluginManager extends PluginManagerBase {
 
   /**
-   * Overrides Drupal\Component\Plugin\PluginManagerBase:$defaults.
-   */
-  protected $defaults = array(
-    'settings' => array(),
-    'multiple_values' => FALSE,
-    'default_value' => TRUE,
-  );
-
-  /**
    * The cache bin used for plugin definitions.
    *
    * @var string
@@ -44,8 +36,13 @@ class WidgetPluginManager extends PluginManagerBase {
    * Constructs a WidgetPluginManager object.
    */
   public function __construct() {
-    $this->baseDiscovery = new WidgetLegacyDiscoveryDecorator(new AnnotatedClassDiscovery('field', 'widget'));
-    $this->discovery = new CacheDecorator($this->baseDiscovery, $this->cache_id, $this->cache_bin);
+    $defaults = array(
+      'settings' => array(),
+      'multiple_values' => FALSE,
+      'default_value' => TRUE,
+    );
+    $base_discovery = new DefaultsDecorator(new WidgetLegacyDiscoveryDecorator(new AnnotatedClassDiscovery('field', 'widget')), $defaults);
+    $this->discovery = new CacheDecorator($base_discovery, $this->cache_id, $this->cache_bin);
 
     $this->factory = new WidgetFactory($this);
   }
