diff --git a/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryInterface.php b/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryInterface.php
index dee79eae09ec8d3b63d0d3702f230c641f7ae45e..aaf47437665933b90b6b46b76dd7d6d369a5e6a5 100644
--- a/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryInterface.php
+++ b/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryInterface.php
@@ -19,8 +19,8 @@ interface DiscoveryInterface {
    * @param string $plugin_id
    *   A plugin id.
    *
-   * @return array
-   *   A plugin definition.
+   * @return array|null
+   *   A plugin definition, or NULL if no definition was found for $plugin_id.
    */
   public function getDefinition($plugin_id);
 
@@ -28,7 +28,8 @@ public function getDefinition($plugin_id);
    * Gets the definition of all plugins for this type.
    *
    * @return array
-   *   An array of plugin definitions.
+   *   An array of plugin definitions (empty array if no definitions were
+   *   found).
    */
   public function getDefinitions();
 
diff --git a/core/lib/Drupal/Core/Plugin/Discovery/AnnotatedClassDiscovery.php b/core/lib/Drupal/Core/Plugin/Discovery/AnnotatedClassDiscovery.php
index a8b16434582d475da02659806fd0e320df9d7f05..4b1dcd4a4e14d6c40fd855ca914656ed987293bd 100644
--- a/core/lib/Drupal/Core/Plugin/Discovery/AnnotatedClassDiscovery.php
+++ b/core/lib/Drupal/Core/Plugin/Discovery/AnnotatedClassDiscovery.php
@@ -33,7 +33,7 @@ function __construct($owner, $type) {
    */
   public function getDefinition($plugin_id) {
     $plugins = $this->getDefinitions();
-    return isset($plugins[$plugin_id]) ? $plugins[$plugin_id] : array();
+    return isset($plugins[$plugin_id]) ? $plugins[$plugin_id] : NULL;
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Plugin/Discovery/CacheDecorator.php b/core/lib/Drupal/Core/Plugin/Discovery/CacheDecorator.php
index 9df7ef66ee382fd1632619769a4b625a41173fd7..7a57395497f64ad25f25b009140b4ee41d342e8d 100644
--- a/core/lib/Drupal/Core/Plugin/Discovery/CacheDecorator.php
+++ b/core/lib/Drupal/Core/Plugin/Discovery/CacheDecorator.php
@@ -65,7 +65,7 @@ public function __construct(DiscoveryInterface $decorated, $cache_key, $cache_bi
    */
   public function getDefinition($plugin_id) {
     $definitions = $this->getDefinitions();
-    return isset($definitions[$plugin_id]) ? $definitions[$plugin_id] : array();
+    return isset($definitions[$plugin_id]) ? $definitions[$plugin_id] : NULL;
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Plugin/Discovery/HookDiscovery.php b/core/lib/Drupal/Core/Plugin/Discovery/HookDiscovery.php
index 37786bea375c633e97f606334912fd2b8f1f3e82..0c77a2fa210ac2e37f2990c8dabea66371e72be8 100644
--- a/core/lib/Drupal/Core/Plugin/Discovery/HookDiscovery.php
+++ b/core/lib/Drupal/Core/Plugin/Discovery/HookDiscovery.php
@@ -37,7 +37,7 @@ function __construct($hook) {
    */
   public function getDefinition($plugin_id) {
     $plugins = $this->getDefinitions();
-    return isset($plugins[$plugin_id]) ? $plugins[$plugin_id] : array();
+    return isset($plugins[$plugin_id]) ? $plugins[$plugin_id] : NULL;
   }
 
   /**
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 de82360040dcc0a57395af4a7f870f9673cfb421..3ee904868dbb34b6bee709eefaab6b822c435830 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
@@ -61,19 +61,6 @@ public function clearDefinitions() {
     cache($this->cache_bin)->delete($this->cache_id);
   }
 
-  /**
-   * Overrides Drupal\Component\Plugin\PluginManagerBase::getDefinition().
-   *
-   * @todo Remove when http://drupal.org/node/1778942 is fixed.
-   */
-  public function getDefinition($plugin_id) {
-    $definition = $this->discovery->getDefinition($plugin_id);
-    if (!empty($definition)) {
-      $this->processDefinition($definition, $plugin_id);
-      return $definition;;
-    }
-  }
-
   /**
    * Overrides Drupal\Component\Plugin\PluginManagerBase::getInstance().
    */
diff --git a/core/modules/system/lib/Drupal/system/Tests/Plugin/Discovery/AnnotatedClassDiscoveryTest.php b/core/modules/system/lib/Drupal/system/Tests/Plugin/Discovery/AnnotatedClassDiscoveryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ae9deb1770b2ec393ba8dd051836537d1197da81
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/Plugin/Discovery/AnnotatedClassDiscoveryTest.php
@@ -0,0 +1,51 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\system\Tests\Plugin\Discovery\AnnotatedClassDiscoveryTest.
+ */
+
+namespace Drupal\system\Tests\Plugin\Discovery;
+
+use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
+
+/**
+ * Tests that plugins with annotated classes are correctly discovered.
+ */
+class AnnotatedClassDiscoveryTest extends DiscoveryTestBase {
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Annotated class discovery',
+      'description' => 'Tests that plugins are correctly discovered using annotated classes.',
+      'group' => 'Plugin API',
+    );
+  }
+
+  public function setUp() {
+    parent::setUp();
+    $this->expectedDefinitions = array(
+      'apple' => array(
+        'id' => 'apple',
+        'label' => 'Apple',
+        'color' => 'green',
+        'class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\Apple',
+      ),
+      'cherry' => array(
+        'id' => 'cherry',
+        'label' => 'Cherry',
+        'color' => 'red',
+        'class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\Cherry',
+      ),
+      'orange' => array(
+        'id' => 'orange',
+        'label' => 'Orange',
+        'color' => 'orange',
+        'class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\Orange',
+      ),
+    );
+    $this->discovery = new AnnotatedClassDiscovery('plugin_test', 'fruit');
+    $this->emptyDiscovery = new AnnotatedClassDiscovery('non_existing_module', 'non_existing_plugin_type');
+  }
+}
+
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
new file mode 100644
index 0000000000000000000000000000000000000000..e95d238b0616eda028179fe45afadf6daa67c165
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/Plugin/Discovery/DiscoveryTestBase.php
@@ -0,0 +1,62 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\system\Tests\Plugin\Discovery\DiscoveryTestBase.
+ */
+
+namespace Drupal\system\Tests\Plugin\Discovery;
+
+use Drupal\simpletest\UnitTestBase;
+
+/**
+ * Tests that plugins are correctly discovered.
+ */
+class DiscoveryTestBase extends UnitTestBase {
+
+  /**
+   * The discovery component to test.
+   *
+   * @var \Drupal\Component\Plugin\Discovery\DiscoveryInterface
+   */
+  protected $discovery;
+
+  /**
+   * The plugin definitions the discovery component is expected to discover.
+   *
+   * @var array
+   */
+  protected $expectedDefinitions;
+
+  /**
+   * An empty discovery component.
+   *
+   * This will be tested to ensure that the case where no plugin information is
+   * found, is handled correctly.
+   *
+   * @var \Drupal\Component\Plugin\Discovery\DiscoveryInterface
+   */
+  protected $emptyDiscovery;
+
+  /**
+   * Tests getDefinitions() and getDefinition().
+   */
+  function testDiscoveryInterface() {
+    // Ensure that getDefinitions() returns the expected definitions.
+    // For the arrays to be identical (instead of only equal), they must be
+    // sorted equally, which seems unneccessary here.
+    $this->assertEqual($this->discovery->getDefinitions(), $this->expectedDefinitions);
+
+    // Ensure that getDefinition() returns the expected definition.
+    foreach ($this->expectedDefinitions as $id => $definition) {
+      $this->assertIdentical($this->discovery->getDefinition($id), $definition);
+    }
+
+    // Ensure that an empty array is returned if no plugin definitions are found.
+    $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.');
+  }
+}
+
diff --git a/core/modules/system/lib/Drupal/system/Tests/Plugin/Discovery/StaticDiscoveryTest.php b/core/modules/system/lib/Drupal/system/Tests/Plugin/Discovery/StaticDiscoveryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..c0adf9ffdef8c85356e2bd5021df1313d0536e7a
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/Plugin/Discovery/StaticDiscoveryTest.php
@@ -0,0 +1,57 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\system\Tests\Plugin\Discovery\StaticDiscoveryTest.
+ */
+
+namespace Drupal\system\Tests\Plugin\Discovery;
+
+use Drupal\Component\Plugin\Discovery\StaticDiscovery;
+
+/**
+ * Tests that plugins are correctly discovered.
+ */
+class StaticDiscoveryTest extends DiscoveryTestBase {
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Static discovery',
+      'description' => 'Tests that plugins using static discovery are correctly discovered.',
+      'group' => 'Plugin API',
+    );
+  }
+
+  public function setUp() {
+    parent::setUp();
+    $this->expectedDefinitions = array(
+      'apple' => array(
+        'label' => 'Apple',
+        'color' => 'green',
+      ),
+      'cherry' => array(
+        'label' => 'Cherry',
+        'color' => 'red',
+      ),
+      'orange' => array(
+        'label' => 'Orange',
+        'color' => 'orange',
+      ),
+    );
+    // Instead of registering the empty discovery component first and then
+    // setting the plugin definitions, we set them first and then delete them
+    // again. This implicitly tests StaticDiscovery::deleteDefinition() (in
+    // addition to StaticDiscovery::setDefinition() which we need to use
+    // anyway).
+    $discovery = new StaticDiscovery();
+    foreach ($this->expectedDefinitions as $plugin_id => $definition) {
+      $discovery->setDefinition($plugin_id, $definition);
+    }
+    $this->discovery = clone $discovery;
+    foreach ($this->expectedDefinitions as $plugin_id => $definition) {
+      $discovery->deleteDefinition($plugin_id);
+    }
+    $this->emptyDiscovery = $discovery;
+  }
+}
+
diff --git a/core/modules/system/lib/Drupal/system/Tests/Plugin/DiscoveryTest.php b/core/modules/system/lib/Drupal/system/Tests/Plugin/DiscoveryTest.php
deleted file mode 100644
index 32637c672887204c846c7af8c43b18978a217b0a..0000000000000000000000000000000000000000
--- a/core/modules/system/lib/Drupal/system/Tests/Plugin/DiscoveryTest.php
+++ /dev/null
@@ -1,38 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\system\Tests\Plugin\DiscoveryTest.
- */
-
-namespace Drupal\system\Tests\Plugin;
-
-/**
- * Tests that plugins are correctly discovered.
- */
-class DiscoveryTest extends PluginTestBase {
-
-  public static function getInfo() {
-    return array(
-      'name' => 'Discovery',
-      'description' => 'Tests that plugins are correctly discovered.',
-      'group' => 'Plugin API',
-    );
-  }
-
-  /**
-   * Tests getDefinitions() and getDefinition().
-   */
-  function testDiscoveryInterface() {
-    // Ensure that getDefinitions() returns the expected definitions.
-    $this->assertIdentical($this->testPluginManager->getDefinitions(), $this->testPluginExpectedDefinitions);
-
-    // Ensure that getDefinition() returns the expected definition.
-    foreach ($this->testPluginExpectedDefinitions as $id => $definition) {
-      $this->assertIdentical($this->testPluginManager->getDefinition($id), $definition);
-    }
-
-    // Ensure that NULL is returned as the definition of a non-existing plugin.
-    $this->assertIdentical($this->testPluginManager->getDefinition('non_existing'), NULL, 'NULL returned as the definition of a non-existing base plugin.');
-  }
-}
diff --git a/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/plugin_test/fruit/Apple.php b/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/plugin_test/fruit/Apple.php
new file mode 100644
index 0000000000000000000000000000000000000000..5b8cfa812b884f5863ca433e4c959e35f77615d2
--- /dev/null
+++ b/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/plugin_test/fruit/Apple.php
@@ -0,0 +1,20 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\plugin_test\Plugin\plugin_test\fruit\Apple.
+ */
+
+namespace Drupal\plugin_test\Plugin\plugin_test\fruit;
+
+use Drupal\Core\Annotation\Plugin;
+
+/**
+ * @Plugin(
+ *   id = "apple",
+ *   label = "Apple",
+ *   color = "green"
+ * )
+ */
+class Apple {}
+
diff --git a/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/plugin_test/fruit/Cherry.php b/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/plugin_test/fruit/Cherry.php
new file mode 100644
index 0000000000000000000000000000000000000000..97e10ce79713fb9476a2726e402084d08b2ef1a3
--- /dev/null
+++ b/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/plugin_test/fruit/Cherry.php
@@ -0,0 +1,20 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\plugin_test\Plugin\plugin_test\fruit\Cherry.
+ */
+
+namespace Drupal\plugin_test\Plugin\plugin_test\fruit;
+
+use Drupal\Core\Annotation\Plugin;
+
+/**
+ * @Plugin(
+ *   id = "cherry",
+ *   label = "Cherry",
+ *   color = "red"
+ * )
+ */
+class Cherry {}
+
diff --git a/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/plugin_test/fruit/Orange.php b/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/plugin_test/fruit/Orange.php
new file mode 100644
index 0000000000000000000000000000000000000000..b00ca39457bcf0ff52332001a2380f20d69427be
--- /dev/null
+++ b/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/plugin_test/fruit/Orange.php
@@ -0,0 +1,20 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\plugin_test\Plugin\plugin_test\fruit\Orange.
+ */
+
+namespace Drupal\plugin_test\Plugin\plugin_test\fruit;
+
+use Drupal\Core\Annotation\Plugin;
+
+/**
+ * @Plugin(
+ *   id = "orange",
+ *   label = "Orange",
+ *   color = "orange"
+ * )
+ */
+class Orange {}
+
diff --git a/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/plugin_test/fruit/README.txt b/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/plugin_test/fruit/README.txt
new file mode 100644
index 0000000000000000000000000000000000000000..433798b462ff9c6f3feb01c990a663ba47748440
--- /dev/null
+++ b/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/plugin_test/fruit/README.txt
@@ -0,0 +1,3 @@
+The classes in this directory act as a mock plugin type to test annotated class
+discovery. See the corresponding test file:
+/core/modules/system/lib/Drupal/system/Tests/Plugin/Discovery/AnnotatedClassDiscoveryTest.php