diff --git a/core/lib/Drupal/Component/Annotation/Plugin/Discovery/AnnotatedClassDiscovery.php b/core/lib/Drupal/Component/Annotation/Plugin/Discovery/AnnotatedClassDiscovery.php
index b1c0dbf..18d9ae8 100644
--- a/core/lib/Drupal/Component/Annotation/Plugin/Discovery/AnnotatedClassDiscovery.php
+++ b/core/lib/Drupal/Component/Annotation/Plugin/Discovery/AnnotatedClassDiscovery.php
@@ -13,12 +13,15 @@
 use Doctrine\Common\Annotations\SimpleAnnotationReader;
 use Doctrine\Common\Annotations\AnnotationRegistry;
 use Doctrine\Common\Reflection\StaticReflectionParser;
+use Drupal\Component\Plugin\Discovery\DiscoveryTrait;
 
 /**
  * Defines a discovery mechanism to find annotated plugins in PSR-0 namespaces.
  */
 class AnnotatedClassDiscovery implements DiscoveryInterface {
 
+  use DiscoveryTrait;
+
   /**
    * The namespaces within which to find plugin classes.
    *
@@ -76,14 +79,6 @@ protected function getAnnotationReader() {
   }
 
   /**
-   * Implements Drupal\Component\Plugin\Discovery\DiscoveryInterface::getDefinition().
-   */
-  public function getDefinition($plugin_id) {
-    $plugins = $this->getDefinitions();
-    return isset($plugins[$plugin_id]) ? $plugins[$plugin_id] : NULL;
-  }
-
-  /**
    * Implements Drupal\Component\Plugin\Discovery\DiscoveryInterface::getDefinitions().
    */
   public function getDefinitions() {
diff --git a/core/lib/Drupal/Component/Plugin/Discovery/DerivativeDiscoveryDecorator.php b/core/lib/Drupal/Component/Plugin/Discovery/DerivativeDiscoveryDecorator.php
index 208bf0e..4850076 100644
--- a/core/lib/Drupal/Component/Plugin/Discovery/DerivativeDiscoveryDecorator.php
+++ b/core/lib/Drupal/Component/Plugin/Discovery/DerivativeDiscoveryDecorator.php
@@ -17,6 +17,8 @@
  */
 class DerivativeDiscoveryDecorator implements DiscoveryInterface {
 
+  use DiscoveryTrait;
+
   protected $derivativeFetchers = array();
   protected $decorated;
 
@@ -39,10 +41,15 @@ public function __construct(DiscoveryInterface $decorated) {
    *   Thrown if the 'derivative' class specified in the plugin definition does
    *   not implement \Drupal\Component\Plugin\Derivative\DerivativeInterface.
    */
-  public function getDefinition($plugin_id) {
-    $plugin_definition = $this->decorated->getDefinition($plugin_id);
+  public function getDefinition($plugin_id, $exception_on_invalid = TRUE) {
+    // This check is only for derivative plugins that have explicitly provided
+    // an ID. This is not common, and can be expected to fail. Therefore, opt
+    // out of the thrown exception, which will be handled when checking the
+    // $base_plugin_id.
+    $plugin_definition = $this->decorated->getDefinition($plugin_id, FALSE);
+
     list($base_plugin_id, $derivative_id) = $this->decodePluginId($plugin_id);
-    $base_plugin_definition = $this->decorated->getDefinition($base_plugin_id);
+    $base_plugin_definition = $this->decorated->getDefinition($base_plugin_id, $exception_on_invalid);
     if ($base_plugin_definition) {
       $derivative_fetcher = $this->getDerivativeFetcher($base_plugin_id, $base_plugin_definition);
       if ($derivative_fetcher) {
diff --git a/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryCachedTrait.php b/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryCachedTrait.php
new file mode 100644
index 0000000..d342f99
--- /dev/null
+++ b/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryCachedTrait.php
@@ -0,0 +1,33 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Component\Plugin\Discovery\DiscoveryCachedTrait.
+ */
+
+namespace Drupal\Component\Plugin\Discovery;
+
+trait DiscoveryCachedTrait {
+
+  use DiscoveryTrait;
+
+  /**
+   * Cached definitions array.
+   *
+   * @var array
+   */
+  protected $definitions;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDefinition($plugin_id, $exception_on_invalid = TRUE) {
+    // Fetch definitions if they're not loaded yet.
+    if (!isset($this->definitions)) {
+      $this->getDefinitions();
+    }
+
+    return $this->doGetDefinition($this->definitions, $plugin_id, $exception_on_invalid);
+  }
+
+}
diff --git a/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryInterface.php b/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryInterface.php
index dac8a5f..d7e0798 100644
--- a/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryInterface.php
+++ b/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryInterface.php
@@ -18,11 +18,17 @@
    *
    * @param string $plugin_id
    *   A plugin id.
+   * @param bool $exception_on_invalid
+   *   (optional) If TRUE, an invalid plugin ID will throw an exception.
    *
    * @return mixed
-   *   A plugin definition, or NULL if no definition was found for $plugin_id.
+   *   A plugin definition, or NULL if the plugin ID is invalid and
+   *   $exception_on_invalid is FALSE.
+   *
+   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
+   *   Thrown if $plugin_id is invalid and $exception_on_invalid is TRUE.
    */
-  public function getDefinition($plugin_id);
+  public function getDefinition($plugin_id, $exception_on_invalid = TRUE);
 
   /**
    * Gets the definition of all plugins for this type.
@@ -33,4 +39,15 @@ public function getDefinition($plugin_id);
    */
   public function getDefinitions();
 
+  /**
+   * Indicates if a specific plugin definition exists.
+   *
+   * @param string $plugin_id
+   *   A plugin ID.
+   *
+   * @return bool
+   *   TRUE if the definition exists, FALSE otherwise.
+   */
+  public function hasDefinition($plugin_id);
+
 }
diff --git a/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryTrait.php b/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryTrait.php
new file mode 100644
index 0000000..20007d1
--- /dev/null
+++ b/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryTrait.php
@@ -0,0 +1,67 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Component\Plugin\Discovery\DiscoveryTrait.
+ */
+
+namespace Drupal\Component\Plugin\Discovery;
+
+use Drupal\Component\Plugin\Exception\PluginNotFoundException;
+
+/**
+ * @see Drupal\Component\Plugin\Discovery\DiscoveryInterface
+ */
+trait DiscoveryTrait {
+
+  /**
+   * {@inheritdoc}
+   */
+  abstract public function getDefinitions();
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDefinition($plugin_id, $exception_on_invalid = TRUE) {
+    $definitions = $this->getDefinitions();
+    return $this->doGetDefinition($definitions, $plugin_id, $exception_on_invalid);
+  }
+
+  /**
+   * Gets a specific plugin definition.
+   *
+   * @param array $definitions
+   *   An array of the available plugin definitions.
+   * @param string $plugin_id
+   *   A plugin id.
+   * @param bool $exception_on_invalid
+   *   (optional) If TRUE, an invalid plugin ID will throw an exception.
+   *   Defaults to FALSE.
+   *
+   * @return array|null
+   *   A plugin definition, or NULL if the plugin ID is invalid and
+   *   $exception_on_invalid is TRUE.
+   *
+   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
+   *   Thrown if $plugin_id is invalid and $exception_on_invalid is TRUE.
+   */
+  protected function doGetDefinition(array $definitions, $plugin_id, $exception_on_invalid) {
+    // Avoid using a ternary that would create a copy of the array.
+    if (isset($definitions[$plugin_id])) {
+      return $definitions[$plugin_id];
+    }
+    elseif (!$exception_on_invalid) {
+      return NULL;
+    }
+
+    throw new PluginNotFoundException($plugin_id, sprintf('The "%s" plugin does not exist.', $plugin_id));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasDefinition($plugin_id) {
+    return (bool) $this->getDefinition($plugin_id, FALSE);
+  }
+
+}
diff --git a/core/lib/Drupal/Component/Plugin/Discovery/ProcessDecorator.php b/core/lib/Drupal/Component/Plugin/Discovery/ProcessDecorator.php
index fee6518..1a88123 100644
--- a/core/lib/Drupal/Component/Plugin/Discovery/ProcessDecorator.php
+++ b/core/lib/Drupal/Component/Plugin/Discovery/ProcessDecorator.php
@@ -15,6 +15,8 @@
  */
 class ProcessDecorator implements DiscoveryInterface {
 
+  use DiscoveryTrait;
+
   /**
    * The Discovery object being decorated.
    *
@@ -47,16 +49,6 @@ public function __construct(DiscoveryInterface $decorated, $process_callback) {
   }
 
   /**
-   * Implements \Drupal\Component\Plugin\Discovery\DicoveryInterface::getDefinition().
-   */
-  public function getDefinition($plugin_id) {
-    $definitions = $this->getDefinitions();
-    if (isset($definitions[$plugin_id])) {
-      return $definitions[$plugin_id];
-    }
-  }
-
-  /**
    * Implements \Drupal\Component\Plugin\Discovery\DicoveryInterface::getDefinitions().
    */
   public function getDefinitions() {
diff --git a/core/lib/Drupal/Component/Plugin/Discovery/StaticDiscovery.php b/core/lib/Drupal/Component/Plugin/Discovery/StaticDiscovery.php
index de74fb5..18f51b7 100644
--- a/core/lib/Drupal/Component/Plugin/Discovery/StaticDiscovery.php
+++ b/core/lib/Drupal/Component/Plugin/Discovery/StaticDiscovery.php
@@ -13,24 +13,15 @@
  */
 class StaticDiscovery implements DiscoveryInterface {
 
-  /**
-   * The array of plugin definitions, keyed by plugin id.
-   *
-   * @var array
-   */
-  protected $definitions = array();
-
-  /**
-   * Implements Drupal\Component\Plugin\Discovery\DiscoveryInterface::getDefinition().
-   */
-  public function getDefinition($base_plugin_id) {
-    return isset($this->definitions[$base_plugin_id]) ? $this->definitions[$base_plugin_id] : NULL;
-  }
+  use DiscoveryCachedTrait;
 
   /**
    * Implements Drupal\Component\Plugin\Discovery\DiscoveryInterface::getDefinitions().
    */
   public function getDefinitions() {
+    if (!$this->definitions) {
+      $this->definitions = array();
+    }
     return $this->definitions;
   }
 
diff --git a/core/lib/Drupal/Component/Plugin/Discovery/StaticDiscoveryDecorator.php b/core/lib/Drupal/Component/Plugin/Discovery/StaticDiscoveryDecorator.php
index cf8bb39..ab31eac 100644
--- a/core/lib/Drupal/Component/Plugin/Discovery/StaticDiscoveryDecorator.php
+++ b/core/lib/Drupal/Component/Plugin/Discovery/StaticDiscoveryDecorator.php
@@ -41,14 +41,14 @@ public function __construct(DiscoveryInterface $decorated, $registerDefinitions
   }
 
   /**
-   * Implements Drupal\Component\Plugin\Discovery\DiscoveryInterface::getDefinition().
+   * {@inheritdoc}
    */
-  public function getDefinition($base_plugin_id) {
+  public function getDefinition($base_plugin_id, $exception_on_invalid = TRUE) {
     if (isset($this->registerDefinitions)) {
       call_user_func($this->registerDefinitions);
     }
     $this->definitions += $this->decorated->getDefinitions();
-    return parent::getDefinition($base_plugin_id);
+    return parent::getDefinition($base_plugin_id, $exception_on_invalid);
   }
 
   /**
diff --git a/core/lib/Drupal/Component/Plugin/PluginManagerBase.php b/core/lib/Drupal/Component/Plugin/PluginManagerBase.php
index 1fe5160..f3a19b0 100644
--- a/core/lib/Drupal/Component/Plugin/PluginManagerBase.php
+++ b/core/lib/Drupal/Component/Plugin/PluginManagerBase.php
@@ -8,12 +8,15 @@
 namespace Drupal\Component\Plugin;
 
 use Drupal\Component\Plugin\Discovery\CachedDiscoveryInterface;
+use Drupal\Component\Plugin\Discovery\DiscoveryTrait;
 
 /**
  * Base class for plugin managers.
  */
 abstract class PluginManagerBase implements PluginManagerInterface, CachedDiscoveryInterface {
 
+  use DiscoveryTrait;
+
   /**
    * The object that discovers plugins managed by this manager.
    *
@@ -38,8 +41,8 @@
   /**
    * {@inheritdoc}
    */
-  public function getDefinition($plugin_id) {
-    return $this->discovery->getDefinition($plugin_id);
+  public function getDefinition($plugin_id, $exception_on_invalid = TRUE) {
+    return $this->discovery->getDefinition($plugin_id, $exception_on_invalid);
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Config/TypedConfigManager.php b/core/lib/Drupal/Core/Config/TypedConfigManager.php
index 647d00f..a02007c 100644
--- a/core/lib/Drupal/Core/Config/TypedConfigManager.php
+++ b/core/lib/Drupal/Core/Config/TypedConfigManager.php
@@ -140,9 +140,9 @@ public function createInstance($plugin_id, array $configuration = array(), $name
   }
 
   /**
-   * Implements Drupal\Component\Plugin\Discovery\DiscoveryInterface::getDefinition().
+   * {@inheritdoc}
    */
-  public function getDefinition($base_plugin_id) {
+  public function getDefinition($base_plugin_id, $exception_on_invalid = TRUE) {
     $definitions = $this->getDefinitions();
     if (isset($definitions[$base_plugin_id])) {
       $type = $base_plugin_id;
@@ -159,7 +159,7 @@ public function getDefinition($base_plugin_id) {
     $definition = $definitions[$type];
     // Check whether this type is an extension of another one and compile it.
     if (isset($definition['type'])) {
-      $merge = $this->getDefinition($definition['type']);
+      $merge = $this->getDefinition($definition['type'], $exception_on_invalid);
       $definition = NestedArray::mergeDeep($merge, $definition);
       // Unset type so we try the merge only once per type.
       unset($definition['type']);
diff --git a/core/lib/Drupal/Core/Entity/EntityManager.php b/core/lib/Drupal/Core/Entity/EntityManager.php
index 3fe2c54..9f95984 100644
--- a/core/lib/Drupal/Core/Entity/EntityManager.php
+++ b/core/lib/Drupal/Core/Entity/EntityManager.php
@@ -191,8 +191,8 @@ public function clearCachedDefinitions() {
   /**
    * {@inheritdoc}
    */
-  public function getDefinition($entity_type_id, $exception_on_invalid = FALSE) {
-    if (($entity_type = parent::getDefinition($entity_type_id)) && class_exists($entity_type->getClass())) {
+  public function getDefinition($entity_type_id, $exception_on_invalid = TRUE) {
+    if (($entity_type = parent::getDefinition($entity_type_id, FALSE)) && class_exists($entity_type->getClass())) {
       return $entity_type;
     }
     elseif (!$exception_on_invalid) {
@@ -206,7 +206,7 @@ public function getDefinition($entity_type_id, $exception_on_invalid = FALSE) {
    * {@inheritdoc}
    */
   public function hasController($entity_type, $controller_type) {
-    if ($definition = $this->getDefinition($entity_type)) {
+    if ($definition = $this->getDefinition($entity_type, FALSE)) {
       return $definition->hasControllerClass($controller_type);
     }
     return FALSE;
@@ -281,7 +281,7 @@ public function getAccessController($entity_type) {
    */
   public function getController($entity_type, $controller_type, $controller_class_getter = NULL) {
     if (!isset($this->controllers[$controller_type][$entity_type])) {
-      $definition = $this->getDefinition($entity_type, TRUE);
+      $definition = $this->getDefinition($entity_type);
       if ($controller_class_getter) {
         $class = $definition->{$controller_class_getter}();
       }
@@ -312,7 +312,7 @@ public function getController($entity_type, $controller_type, $controller_class_
    * {@inheritdoc}
    */
   public function getAdminRouteInfo($entity_type_id, $bundle) {
-    if (($entity_type = $this->getDefinition($entity_type_id)) && $admin_form = $entity_type->getLinkTemplate('admin-form')) {
+    if (($entity_type = $this->getDefinition($entity_type_id, FALSE)) && $admin_form = $entity_type->getLinkTemplate('admin-form')) {
       return array(
         'route_name' => $admin_form,
         'route_parameters' => array(
diff --git a/core/lib/Drupal/Core/Entity/EntityManagerInterface.php b/core/lib/Drupal/Core/Entity/EntityManagerInterface.php
index 4a93c8a..39b39be 100644
--- a/core/lib/Drupal/Core/Entity/EntityManagerInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityManagerInterface.php
@@ -274,28 +274,16 @@ public function getExtraFields($entity_type_id, $bundle);
   public function getTranslationFromContext(EntityInterface $entity, $langcode = NULL, $context = array());
 
   /**
-   * Returns the entity type info for a specific entity type.
-   *
-   * @param string $entity_type_id
-   *   The ID of the entity type.
-   * @param bool $exception_on_invalid
-   *   (optional) If TRUE, an invalid entity type ID will throw an exception.
-   *   Defaults to FALSE.
+   * {@inheritdoc}
    *
    * @return \Drupal\Core\Entity\EntityTypeInterface|null
-   *   Returns the entity type object, or NULL if the entity type ID is invalid
-   *   and $exception_on_invalid is TRUE.
-   *
-   * @throws \InvalidArgumentException
-   *   Thrown if $entity_type_id is invalid and $exception_on_invalid is TRUE.
    */
-  public function getDefinition($entity_type_id, $exception_on_invalid = FALSE);
+  public function getDefinition($entity_type_id, $exception_on_invalid = TRUE);
 
   /**
-   * Returns an array of entity type info, keyed by entity type name.
+   * {@inheritdoc}
    *
    * @return \Drupal\Core\Entity\EntityTypeInterface[]
-   *   An array of entity type objects.
    */
   public function getDefinitions();
 
diff --git a/core/lib/Drupal/Core/Field/FieldTypePluginManager.php b/core/lib/Drupal/Core/Field/FieldTypePluginManager.php
index a4ccd78..31d07c4 100644
--- a/core/lib/Drupal/Core/Field/FieldTypePluginManager.php
+++ b/core/lib/Drupal/Core/Field/FieldTypePluginManager.php
@@ -51,7 +51,7 @@ public function processDefinition(&$definition, $plugin_id) {
    * {@inheritdoc}
    */
   public function getDefaultSettings($type) {
-    $plugin_definition = $this->getDefinition($type);
+    $plugin_definition = $this->getDefinition($type, FALSE);
     if (!empty($plugin_definition['class'])) {
       $plugin_class = DefaultFactory::getPluginClass($type, $plugin_definition);
       return $plugin_class::defaultSettings();
@@ -63,7 +63,7 @@ public function getDefaultSettings($type) {
    * {@inheritdoc}
    */
   public function getDefaultInstanceSettings($type) {
-    $plugin_definition = $this->getDefinition($type);
+    $plugin_definition = $this->getDefinition($type, FALSE);
     if (!empty($plugin_definition['class'])) {
       $plugin_class = DefaultFactory::getPluginClass($type, $plugin_definition);
       return $plugin_class::defaultInstanceSettings();
diff --git a/core/lib/Drupal/Core/Field/FormatterPluginManager.php b/core/lib/Drupal/Core/Field/FormatterPluginManager.php
index 85e9589..586fcb1 100644
--- a/core/lib/Drupal/Core/Field/FormatterPluginManager.php
+++ b/core/lib/Drupal/Core/Field/FormatterPluginManager.php
@@ -113,7 +113,7 @@ public function getInstance(array $options) {
     // Switch back to default formatter if either:
     // - $type_info doesn't exist (the widget type is unknown),
     // - the field type is not allowed for the widget.
-    $definition = $this->getDefinition($configuration['type']);
+    $definition = $this->getDefinition($configuration['type'], FALSE);
     if (!isset($definition['class']) || !in_array($field_type, $definition['field_types'])) {
       // Grab the default widget for the field type.
       $field_type_definition = $this->fieldTypeManager->getDefinition($field_type);
@@ -201,7 +201,7 @@ public function getOptions($field_type = NULL) {
    *   definition, or an empty array if type or settings are undefined.
    */
   public function getDefaultSettings($type) {
-    $plugin_definition = $this->getDefinition($type);
+    $plugin_definition = $this->getDefinition($type, FALSE);
     if (!empty($plugin_definition['class'])) {
       $plugin_class = DefaultFactory::getPluginClass($type, $plugin_definition);
       return $plugin_class::defaultSettings();
diff --git a/core/lib/Drupal/Core/Field/WidgetPluginManager.php b/core/lib/Drupal/Core/Field/WidgetPluginManager.php
index 4b60213..ce78441 100644
--- a/core/lib/Drupal/Core/Field/WidgetPluginManager.php
+++ b/core/lib/Drupal/Core/Field/WidgetPluginManager.php
@@ -99,7 +99,7 @@ public function getInstance(array $options) {
     // Switch back to default widget if either:
     // - $type_info doesn't exist (the widget type is unknown),
     // - the field type is not allowed for the widget.
-    $definition = $this->getDefinition($configuration['type']);
+    $definition = $this->getDefinition($configuration['type'], FALSE);
     if (!isset($definition['class']) || !in_array($field_type, $definition['field_types'])) {
       // Grab the default widget for the field type.
       $field_type_definition = $this->fieldTypeManager->getDefinition($field_type);
@@ -203,7 +203,7 @@ public function getOptions($field_type = NULL) {
    *   definition, or an empty array if type or settings are undefined.
    */
   public function getDefaultSettings($type) {
-    $plugin_definition = $this->getDefinition($type);
+    $plugin_definition = $this->getDefinition($type, FALSE);
     if (!empty($plugin_definition['class'])) {
       $plugin_class = DefaultFactory::getPluginClass($type, $plugin_definition);
       return $plugin_class::defaultSettings();
diff --git a/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php b/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
index e9c4ce9..3ae5aab 100644
--- a/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
+++ b/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
@@ -8,6 +8,8 @@
 namespace Drupal\Core\Plugin;
 
 use Drupal\Component\Plugin\Discovery\CachedDiscoveryInterface;
+use Drupal\Component\Plugin\Discovery\DiscoveryCachedTrait;
+use Drupal\Component\Plugin\Exception\PluginNotFoundException;
 use Drupal\Core\Plugin\Discovery\ContainerDerivativeDiscoveryDecorator;
 use Drupal\Component\Plugin\PluginManagerBase;
 use Drupal\Component\Plugin\PluginManagerInterface;
@@ -25,12 +27,7 @@
  */
 class DefaultPluginManager extends PluginManagerBase implements PluginManagerInterface, CachedDiscoveryInterface {
 
-  /**
-   * Cached definitions array.
-   *
-   * @var array
-   */
-  protected $definitions;
+  use DiscoveryCachedTrait;
 
   /**
    * Cache backend instance.
@@ -164,20 +161,6 @@ protected function alterInfo($alter_hook) {
   /**
    * {@inheritdoc}
    */
-  public function getDefinition($plugin_id) {
-    // Fetch definitions if they're not loaded yet.
-    if (!isset($this->definitions)) {
-      $this->getDefinitions();
-    }
-    // Avoid using a ternary that would create a copy of the array.
-    if (isset($this->definitions[$plugin_id])) {
-      return $this->definitions[$plugin_id];
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public function getDefinitions() {
     $definitions = $this->getCachedDefinitions();
     if (!isset($definitions)) {
diff --git a/core/lib/Drupal/Core/Plugin/Discovery/AlterDecorator.php b/core/lib/Drupal/Core/Plugin/Discovery/AlterDecorator.php
index 05388b8..0a7cf86 100644
--- a/core/lib/Drupal/Core/Plugin/Discovery/AlterDecorator.php
+++ b/core/lib/Drupal/Core/Plugin/Discovery/AlterDecorator.php
@@ -8,11 +8,15 @@
 namespace Drupal\Core\Plugin\Discovery;
 
 use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
+use Drupal\Component\Plugin\Discovery\DiscoveryTrait;
 
 /**
  * Enables altering of discovered plugin definitions.
  */
 class AlterDecorator implements DiscoveryInterface {
+
+  use DiscoveryTrait;
+
   /**
    * The name of the alter hook that will be implemented by this discovery instance.
    *
@@ -43,15 +47,6 @@ public function __construct(DiscoveryInterface $decorated, $hook) {
   }
 
   /**
-   * 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() {
diff --git a/core/lib/Drupal/Core/Plugin/Discovery/CacheDecorator.php b/core/lib/Drupal/Core/Plugin/Discovery/CacheDecorator.php
index e5bdffd..9fd2146 100644
--- a/core/lib/Drupal/Core/Plugin/Discovery/CacheDecorator.php
+++ b/core/lib/Drupal/Core/Plugin/Discovery/CacheDecorator.php
@@ -8,6 +8,7 @@
 namespace Drupal\Core\Plugin\Discovery;
 
 use Drupal\Component\Plugin\Discovery\CachedDiscoveryInterface;
+use Drupal\Component\Plugin\Discovery\DiscoveryCachedTrait;
 use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
 use Drupal\Core\Cache\Cache;
 
@@ -16,6 +17,8 @@
  */
 class CacheDecorator implements CachedDiscoveryInterface {
 
+  use DiscoveryCachedTrait;
+
   /**
    * The cache key used to store the definition list.
    *
@@ -45,13 +48,6 @@ class CacheDecorator implements CachedDiscoveryInterface {
   protected $cacheTags;
 
   /**
-   * The plugin definitions of the decorated discovery class.
-   *
-   * @var array
-   */
-  protected $definitions;
-
-  /**
    * The Discovery object being decorated.
    *
    * @var \Drupal\Component\Plugin\Discovery\DiscoveryInterface
@@ -84,28 +80,6 @@ public function __construct(DiscoveryInterface $decorated, $cache_key, $cache_bi
   }
 
   /**
-   * Implements Drupal\Component\Plugin\Discovery\DicoveryInterface::getDefinition().
-   */
-  public function getDefinition($plugin_id) {
-    // Optimize for fast access to definitions if they are already in memory.
-    if (isset($this->definitions)) {
-      // Avoid using a ternary that would create a copy of the array.
-      if (isset($this->definitions[$plugin_id])) {
-        return $this->definitions[$plugin_id];
-      }
-      else {
-        return;
-      }
-    }
-
-    $definitions = $this->getDefinitions();
-    // Avoid using a ternary that would create a copy of the array.
-    if (isset($definitions[$plugin_id])) {
-      return $definitions[$plugin_id];
-    }
-  }
-
-  /**
    * Implements Drupal\Component\Plugin\Discovery\DicoveryInterface::getDefinitions().
    */
   public function getDefinitions() {
diff --git a/core/lib/Drupal/Core/Plugin/Discovery/HookDiscovery.php b/core/lib/Drupal/Core/Plugin/Discovery/HookDiscovery.php
index 035d402..8d0b869 100644
--- a/core/lib/Drupal/Core/Plugin/Discovery/HookDiscovery.php
+++ b/core/lib/Drupal/Core/Plugin/Discovery/HookDiscovery.php
@@ -8,6 +8,7 @@
 namespace Drupal\Core\Plugin\Discovery;
 
 use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
+use Drupal\Component\Plugin\Discovery\DiscoveryTrait;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 
 /**
@@ -15,6 +16,8 @@
  */
 class HookDiscovery implements DiscoveryInterface {
 
+  use DiscoveryTrait;
+
   /**
    * The name of the hook that will be implemented by this discovery instance.
    *
@@ -44,14 +47,6 @@ function __construct(ModuleHandlerInterface $module_handler, $hook) {
   }
 
   /**
-   * Implements Drupal\Component\Plugin\Discovery\DicoveryInterface::getDefinition().
-   */
-  public function getDefinition($plugin_id) {
-    $plugins = $this->getDefinitions();
-    return isset($plugins[$plugin_id]) ? $plugins[$plugin_id] : NULL;
-  }
-
-  /**
    * Implements Drupal\Component\Plugin\Discovery\DicoveryInterface::getDefinitions().
    */
   public function getDefinitions() {
diff --git a/core/lib/Drupal/Core/Plugin/Discovery/InfoHookDecorator.php b/core/lib/Drupal/Core/Plugin/Discovery/InfoHookDecorator.php
index 4733c8c..e546ebf 100644
--- a/core/lib/Drupal/Core/Plugin/Discovery/InfoHookDecorator.php
+++ b/core/lib/Drupal/Core/Plugin/Discovery/InfoHookDecorator.php
@@ -8,12 +8,15 @@
 namespace Drupal\Core\Plugin\Discovery;
 
 use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
+use Drupal\Component\Plugin\Discovery\DiscoveryTrait;
 
 /**
  * Allows info hook implementations to enhance discovered plugin definitions.
  */
 class InfoHookDecorator implements DiscoveryInterface {
 
+  use DiscoveryTrait;
+
   /**
    * The Discovery object being decorated.
    *
@@ -42,14 +45,6 @@ public function __construct(DiscoveryInterface $decorated, $hook) {
   }
 
   /**
-   * 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() {
diff --git a/core/lib/Drupal/Core/Plugin/Discovery/YamlDiscovery.php b/core/lib/Drupal/Core/Plugin/Discovery/YamlDiscovery.php
index 516704b..0b7d10f6 100644
--- a/core/lib/Drupal/Core/Plugin/Discovery/YamlDiscovery.php
+++ b/core/lib/Drupal/Core/Plugin/Discovery/YamlDiscovery.php
@@ -9,12 +9,15 @@
 
 use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
 use Drupal\Component\Discovery\YamlDiscovery as ComponentYamlDiscovery;
+use Drupal\Component\Plugin\Discovery\DiscoveryTrait;
 
 /**
  * Allows YAML files to define plugin definitions.
  */
 class YamlDiscovery implements DiscoveryInterface {
 
+  use DiscoveryTrait;
+
   /**
    * YAML file discovery and parsing handler.
    *
@@ -38,14 +41,6 @@ function __construct($name, array $directories) {
   /**
    * {@inheritdoc}
    */
-  public function getDefinition($plugin_id) {
-    $definitions = $this->getDefinitions();
-    return isset($definitions[$plugin_id]) ? $definitions[$plugin_id] : NULL;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public function getDefinitions() {
     $plugins = $this->discovery->findAll();
 
diff --git a/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php b/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php
index b0d9333..66e4bd6 100644
--- a/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php
+++ b/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php
@@ -174,8 +174,7 @@ public function calculateDependencies() {
       }
       // Create a dependency on the module that provides the formatter or
       // widget.
-      if (isset($component['type'])) {
-        $definition = $this->pluginManager->getDefinition($component['type']);
+      if (isset($component['type']) && $definition = $this->pluginManager->getDefinition($component['type'], FALSE)) {
         $this->addDependency('module', $definition['provider']);
       }
     }
diff --git a/core/modules/entity_reference/entity_reference.module b/core/modules/entity_reference/entity_reference.module
index 93544a7..7a0d2b5 100644
--- a/core/modules/entity_reference/entity_reference.module
+++ b/core/modules/entity_reference/entity_reference.module
@@ -207,7 +207,7 @@ function entity_reference_query_entity_reference_alter(AlterableInterface $query
  */
 function entity_reference_create_instance($entity_type, $bundle, $field_name, $field_label, $target_entity_type, $selection_handler = 'default', $selection_handler_settings = array(), $cardinality = 1) {
   // If a field type we know should exist isn't found, clear the field cache.
-  if (!\Drupal::service('plugin.manager.field.field_type')->getDefinition('entity_reference')) {
+  if (!\Drupal::service('plugin.manager.field.field_type')->hasDefinition('entity_reference')) {
     field_cache_clear();
   }
 
diff --git a/core/modules/field/field.views.inc b/core/modules/field/field.views.inc
index 05b65ef..3b7f367 100644
--- a/core/modules/field/field.views.inc
+++ b/core/modules/field/field.views.inc
@@ -68,9 +68,7 @@ function field_views_data_alter(&$data) {
  */
 function _field_views_is_sql_entity_type(FieldConfigInterface $field) {
   $entity_manager = \Drupal::entityManager();
-  if ($entity_manager->getDefinition($field->entity_type) && $entity_manager->getStorage($field->entity_type) instanceof ContentEntityDatabaseStorage) {
-    return TRUE;
-  }
+  return $entity_manager->hasDefinition($field->entity_type) && $entity_manager->getStorage($field->entity_type) instanceof ContentEntityDatabaseStorage;
 }
 
 /**
@@ -115,7 +113,7 @@ function field_views_field_default_views_data(FieldConfigInterface $field) {
   $data = array();
 
   // Check the field type is available.
-  if (!\Drupal::service('plugin.manager.field.field_type')->getDefinition($field->getType())) {
+  if (!\Drupal::service('plugin.manager.field.field_type')->hasDefinition($field->getType())) {
     return $data;
   }
   // Check the field has instances.
diff --git a/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php b/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php
index ad31ede..600f44c 100644
--- a/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php
+++ b/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php
@@ -311,7 +311,7 @@ protected function preSaveNew(EntityStorageInterface $storage) {
     }
 
     // Check that the field type is known.
-    $field_type = $field_type_manager->getDefinition($this->type);
+    $field_type = $field_type_manager->getDefinition($this->type, FALSE);
     if (!$field_type) {
       throw new FieldException(format_string('Attempt to create a field of unknown type %type.', array('%type' => $this->type)));
     }
diff --git a/core/modules/field/lib/Drupal/field/FieldInfo.php b/core/modules/field/lib/Drupal/field/FieldInfo.php
index 808a31b..4e5c500 100644
--- a/core/modules/field/lib/Drupal/field/FieldInfo.php
+++ b/core/modules/field/lib/Drupal/field/FieldInfo.php
@@ -438,7 +438,7 @@ public function getBundleInstances($entity_type, $bundle) {
     $fields = array();
 
     // Do not return anything for unknown entity types.
-    if (\Drupal::entityManager()->getDefinition($entity_type) && !empty($field_map[$entity_type])) {
+    if (\Drupal::entityManager()->hasDefinition($entity_type) && !empty($field_map[$entity_type])) {
 
       // Collect names of fields and instances involved in the bundle, using the
       // field map. The field map is already filtered to non-deleted fields and
diff --git a/core/modules/field/tests/modules/field_test/field_test.info.yml b/core/modules/field/tests/modules/field_test/field_test.info.yml
index 48bb2ae..d9a12fb 100644
--- a/core/modules/field/tests/modules/field_test/field_test.info.yml
+++ b/core/modules/field/tests/modules/field_test/field_test.info.yml
@@ -4,3 +4,6 @@ description: 'Support module for the Field API tests.'
 core: 8.x
 package: Testing
 version: VERSION
+dependencies:
+  - entity_test
+
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php
index 212df05..9669ec7 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php
@@ -114,7 +114,7 @@ function manageFieldsPage($type = '') {
     $url = base_path() . "admin/structure/types/manage/$type/fields/node.$type.body";
     $this->assertIdentical($url, (string) $result[0]['href']);
     $this->assertIdentical("$url/field", (string) $result[1]['href']);
-    $this->assertIdentical("$url/delete", (string) $result[2]['href']);
+    $this->assertIdentical("$url/delete", (string) $result[3]['href']);
   }
 
   /**
diff --git a/core/modules/filter/lib/Drupal/filter/FilterPluginManager.php b/core/modules/filter/lib/Drupal/filter/FilterPluginManager.php
index 2be9e4a..15a2257 100644
--- a/core/modules/filter/lib/Drupal/filter/FilterPluginManager.php
+++ b/core/modules/filter/lib/Drupal/filter/FilterPluginManager.php
@@ -47,10 +47,14 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac
   /**
    * {@inheritdoc}
    */
-  public function getDefinition($plugin_id) {
-    $plugins = $this->getDefinitions();
+  public function getDefinition($plugin_id, $exception_on_invalid = TRUE) {
+    $definitions = $this->getDefinitions();
+    // Avoid using a ternary that would create a copy of the array.
+    if (isset($definitions[$plugin_id])) {
+      return $definitions[$plugin_id];
+    }
     // If the requested filter is missing, use the null filter.
-    return isset($plugins[$plugin_id]) ? $plugins[$plugin_id] : $plugins['filter_null'];
+    return $definitions['filter_null'];
   }
 
 }
diff --git a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityContentBase.php b/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityContentBase.php
index ba1dd46..9928e0b 100644
--- a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityContentBase.php
+++ b/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityContentBase.php
@@ -89,7 +89,7 @@ public function import(Row $row, array $old_destination_id_values = array()) {
       $field_definitions = $this->entityManager->getFieldDefinitions($this->storage->getEntityTypeId(), $bundle);
       foreach ($field_definitions as $field_name => $field_definition) {
         $field_type = $field_definition->getType();
-        if ($this->migrateEntityFieldPluginManager->getDefinition($field_type)) {
+        if ($this->migrateEntityFieldPluginManager->getDefinition($field_type, FALSE)) {
           $destination_value = $this->migrateEntityFieldPluginManager->createInstance($field_type)->import($field_definition, $row->getDestinationProperty($field_name));
           // @TODO: check for NULL return? Add an unset to $row? Maybe needed in
           // exception handling? Propagate exception?
diff --git a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateCckFieldRevisionTest.php b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateCckFieldRevisionTest.php
index 2c4ec30..17171c2 100644
--- a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateCckFieldRevisionTest.php
+++ b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateCckFieldRevisionTest.php
@@ -19,7 +19,7 @@ class MigrateCckFieldRevisionTest extends MigrateNodeTestBase {
    *
    * @var array
    */
-  public static $modules = array('node', 'text');
+  public static $modules = array('field', 'filter', 'node', 'text');
 
   /**
    * {@inheritdoc}
diff --git a/core/modules/system/lib/Drupal/system/Tests/Plugin/CacheDecoratorTest.php b/core/modules/system/lib/Drupal/system/Tests/Plugin/CacheDecoratorTest.php
index aa09289..94ffb96 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Plugin/CacheDecoratorTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Plugin/CacheDecoratorTest.php
@@ -123,7 +123,7 @@ public function testClearCachedDefinitions() {
     $this->discovery->setDefinition('banana', $this->expectedDefinitions['banana']);
 
     // Check that the new definition is not found.
-    $definition = $this->discovery->getDefinition('banana');
+    $definition = $this->discovery->getDefinition('banana', FALSE);
     $this->assertNull($definition, 'Newly added definition is not found.');
 
     // Clear cached definitions, and check that the new definition is found.
diff --git a/core/modules/system/lib/Drupal/system/Tests/Plugin/DerivativeTest.php b/core/modules/system/lib/Drupal/system/Tests/Plugin/DerivativeTest.php
index 4456808..8feeff6 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Plugin/DerivativeTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Plugin/DerivativeTest.php
@@ -35,8 +35,8 @@ function testDerivativeDecorator() {
     // Ensure that NULL is returned as the definition of a non-existing base
     // plugin, a non-existing derivative plugin, or a base plugin that may not
     // be used without deriving.
-    $this->assertIdentical($this->mockBlockManager->getDefinition('non_existing'), NULL, 'NULL returned as the definition of a non-existing base plugin.');
-    $this->assertIdentical($this->mockBlockManager->getDefinition('menu:non_existing'), NULL, 'NULL returned as the definition of a non-existing derivative plugin.');
-    $this->assertIdentical($this->mockBlockManager->getDefinition('menu'), NULL, 'NULL returned as the definition of a base plugin that may not be used without deriving.');
+    $this->assertIdentical($this->mockBlockManager->getDefinition('non_existing', FALSE), NULL, 'NULL returned as the definition of a non-existing base plugin.');
+    $this->assertIdentical($this->mockBlockManager->getDefinition('menu:non_existing', FALSE), NULL, 'NULL returned as the definition of a non-existing derivative plugin.');
+    $this->assertIdentical($this->mockBlockManager->getDefinition('menu', FALSE), NULL, 'NULL returned as the definition of a base plugin that may not be used without deriving.');
   }
 }
diff --git a/core/modules/system/lib/Drupal/system/Tests/Plugin/Discovery/DiscoveryTestBase.php b/core/modules/system/lib/Drupal/system/Tests/Plugin/Discovery/DiscoveryTestBase.php
index aa5cf5b..9d0be54 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Plugin/Discovery/DiscoveryTestBase.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Plugin/Discovery/DiscoveryTestBase.php
@@ -56,7 +56,7 @@ function testDiscoveryInterface() {
     $this->assertIdentical($this->emptyDiscovery->getDefinitions(), array(), 'array() returned if no plugin definitions are found.');
 
     // Ensure that NULL is returned as the definition of a non-existing plugin.
-    $this->assertIdentical($this->emptyDiscovery->getDefinition('non_existing'), NULL, 'NULL returned as the definition of a non-existing plugin.');
+    $this->assertIdentical($this->emptyDiscovery->getDefinition('non_existing', FALSE), NULL, 'NULL returned as the definition of a non-existing plugin.');
   }
 }
 
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php
index 4ed08e4..8752531 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php
@@ -793,7 +793,7 @@ protected function defaultDisplayOptions() {
     // Load the plugin ID and module.
     $base_field = $data['table']['base']['field'];
     $display_options['fields'][$base_field]['plugin_id'] = $data[$base_field]['field']['id'];
-    if ($definition = Views::pluginManager('field')->getDefinition($display_options['fields'][$base_field]['plugin_id'])) {
+    if ($definition = Views::pluginManager('field')->getDefinition($display_options['fields'][$base_field]['plugin_id'], FALSE)) {
       $display_options['fields'][$base_field]['provider'] = isset($definition['provider']) ? $definition['provider'] : 'views';
     }
 
diff --git a/core/modules/views/lib/Drupal/views/Tests/Plugin/DisplayFeedTest.php b/core/modules/views/lib/Drupal/views/Tests/Plugin/DisplayFeedTest.php
index 34403c8..42b8ac1 100644
--- a/core/modules/views/lib/Drupal/views/Tests/Plugin/DisplayFeedTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/Plugin/DisplayFeedTest.php
@@ -26,7 +26,7 @@ class DisplayFeedTest extends PluginTestBase {
    *
    * @var array
    */
-  public static $modules = array('node', 'views_ui');
+  public static $modules = array('block', 'node', 'views_ui');
 
   public static function getInfo() {
     return array(
diff --git a/core/modules/views/lib/Drupal/views/Tests/Plugin/DisplayTest.php b/core/modules/views/lib/Drupal/views/Tests/Plugin/DisplayTest.php
index a99bfcd..413ee29 100644
--- a/core/modules/views/lib/Drupal/views/Tests/Plugin/DisplayTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/Plugin/DisplayTest.php
@@ -248,7 +248,7 @@ public function testInvalidDisplayPlugins() {
 
     $this->drupalGet('test_display_invalid');
     $this->assertResponse(200);
-    $this->assertText(t('The plugin (invalid) did not specify an instance class.'));
+    $this->assertText('The "invalid" plugin does not exist.');
 
     // Rebuild the router, and ensure that the path is not accessible anymore.
     views_invalidate_cache();
@@ -278,7 +278,7 @@ public function testInvalidDisplayPlugins() {
     // plugin warning message.
     $this->drupalGet('<front>');
     $this->assertResponse(200);
-    $this->assertText(t('The plugin (invalid) did not specify an instance class.'));
+    $this->assertText('The "invalid" plugin does not exist.');
     $this->assertNoBlockAppears($block);
   }
 
diff --git a/core/modules/views/lib/Drupal/views/ViewExecutable.php b/core/modules/views/lib/Drupal/views/ViewExecutable.php
index 5eb82a6..ae17eec 100644
--- a/core/modules/views/lib/Drupal/views/ViewExecutable.php
+++ b/core/modules/views/lib/Drupal/views/ViewExecutable.php
@@ -1897,7 +1897,7 @@ public function addHandler($display_id, $type, $table, $field, $options = array(
     $data = Views::viewsData()->get($table);
     if (isset($data[$field][$handler_type]['id'])) {
       $fields[$id]['plugin_id'] = $data[$field][$handler_type]['id'];
-      if ($definition = Views::pluginManager($handler_type)->getDefinition($fields[$id]['plugin_id'])) {
+      if ($definition = Views::pluginManager($handler_type)->getDefinition($fields[$id]['plugin_id'], FALSE)) {
         $fields[$id]['provider'] = isset($definition['provider']) ? $definition['provider'] : 'views';
       }
     }
diff --git a/core/modules/views_ui/tests/Drupal/views_ui/Tests/ViewListBuilderTest.php b/core/modules/views_ui/tests/Drupal/views_ui/Tests/ViewListBuilderTest.php
index 3ead6d9..e6c6c03 100644
--- a/core/modules/views_ui/tests/Drupal/views_ui/Tests/ViewListBuilderTest.php
+++ b/core/modules/views_ui/tests/Drupal/views_ui/Tests/ViewListBuilderTest.php
@@ -46,6 +46,7 @@ public function testBuildRowEntityList() {
       ->will($this->returnValueMap(array(
         array(
           'default',
+          TRUE,
           array(
             'id' => 'default',
             'title' => 'Master',
@@ -55,6 +56,7 @@ public function testBuildRowEntityList() {
         ),
         array(
           'page',
+          TRUE,
           array(
             'id' => 'page',
             'title' => 'Page',
@@ -67,6 +69,7 @@ public function testBuildRowEntityList() {
         ),
         array(
           'embed',
+          TRUE,
           array(
             'id' => 'embed',
             'title' => 'embed',
diff --git a/core/tests/Drupal/Tests/Core/Entity/EntityManagerTest.php b/core/tests/Drupal/Tests/Core/Entity/EntityManagerTest.php
index 100ad29..ed56971 100644
--- a/core/tests/Drupal/Tests/Core/Entity/EntityManagerTest.php
+++ b/core/tests/Drupal/Tests/Core/Entity/EntityManagerTest.php
@@ -8,6 +8,7 @@
 namespace Drupal\Tests\Core\Entity;
 
 use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
+use Drupal\Component\Plugin\Exception\PluginNotFoundException;
 use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
 use Drupal\Core\Entity\ContentEntityInterface;
@@ -135,16 +136,22 @@ protected function setUp() {
    */
   protected function setUpEntityManager($definitions = array()) {
     $class = $this->getMockClass('Drupal\Core\Entity\EntityInterface');
-    $definitions_map = array();
     foreach ($definitions as $entity_type_id => $entity_type) {
       $entity_type->expects($this->any())
         ->method('getClass')
         ->will($this->returnValue($class));
-      $definitions_map[] = array($entity_type_id, $entity_type);
     }
     $this->discovery->expects($this->any())
       ->method('getDefinition')
-      ->will($this->returnValueMap($definitions_map));
+      ->will($this->returnCallback(function ($entity_type_id, $exception_on_invalid = FALSE) use ($definitions) {
+        if (isset($definitions[$entity_type_id])) {
+          return $definitions[$entity_type_id];
+        }
+        elseif (!$exception_on_invalid) {
+          return NULL;
+        }
+        else throw new PluginNotFoundException($entity_type_id);
+      }));
     $this->discovery->expects($this->any())
       ->method('getDefinitions')
       ->will($this->returnValue($definitions));
@@ -182,7 +189,7 @@ public function testGetDefinition($entity_type_id, $expected) {
       'banana' => $entity,
     ));
 
-    $entity_type = $this->entityManager->getDefinition($entity_type_id);
+    $entity_type = $this->entityManager->getDefinition($entity_type_id, FALSE);
     if ($expected) {
       $this->assertInstanceOf('Drupal\Core\Entity\EntityTypeInterface', $entity_type);
     }
diff --git a/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php b/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php
index 4862ac7..c6c706a 100644
--- a/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php
+++ b/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php
@@ -89,7 +89,7 @@ public function testDefaultPluginManagerWithDisabledModule() {
 
     $plugin_manager = new TestPluginManager($this->namespaces, $definitions, $module_handler, 'test_alter_hook');
 
-    $this->assertEmpty($plugin_manager->getDefinition('cherry'), 'Plugin information of a disabled module is not available');
+    $this->assertEmpty($plugin_manager->getDefinition('cherry', FALSE), 'Plugin information of a disabled module is not available');
   }
 
   /**
diff --git a/core/tests/Drupal/Tests/Core/Plugin/Discovery/HookDiscoveryTest.php b/core/tests/Drupal/Tests/Core/Plugin/Discovery/HookDiscoveryTest.php
index 3a120c8..7ff9702 100644
--- a/core/tests/Drupal/Tests/Core/Plugin/Discovery/HookDiscoveryTest.php
+++ b/core/tests/Drupal/Tests/Core/Plugin/Discovery/HookDiscoveryTest.php
@@ -116,7 +116,7 @@ public function testGetDefinition() {
         )
       ));
 
-    $this->assertNull($this->hookDiscovery->getDefinition('test_non_existant'));
+    $this->assertNull($this->hookDiscovery->getDefinition('test_non_existant', FALSE));
 
     $plugin_definition = $this->hookDiscovery->getDefinition('test_id_1');
     $this->assertEquals($plugin_definition['class'], 'Drupal\plugin_test\Plugin\plugin_test\fruit\Apple');
@@ -131,6 +131,21 @@ public function testGetDefinition() {
     $this->assertEquals($plugin_definition['module'], 'hook_discovery_test2');
   }
 
+  /**
+   * Tests the getDefinition method with an unknown plugin ID.
+   *
+   * @see \Drupal\Core\Plugin\Discovery::getDefinition()
+   *
+   * @expectedException \Drupal\Component\Plugin\Exception\PluginNotFoundException
+   */
+  public function testGetDefinitionWithUnknownID() {
+    $this->moduleHandler->expects($this->once())
+      ->method('getImplementations')
+      ->will($this->returnValue(array()));
+
+    $this->hookDiscovery->getDefinition('test_non_existant', TRUE);
+  }
+
 }
 
 }
