 .../Plugin/Discovery/DiscoveryInterface.php        |  5 +-
 .../Plugin/Discovery/AnnotatedClassDiscovery.php   |  2 +-
 .../Core/Plugin/Discovery/CacheDecorator.php       |  2 +-
 .../Drupal/Core/Plugin/Discovery/HookDiscovery.php |  2 +-
 .../Discovery/AnnotatedClassDiscoveryTest.php      | 51 ++++++++++++++++++
 .../Tests/Plugin/Discovery/DiscoveryTestBase.php   | 62 ++++++++++++++++++++++
 .../Tests/Plugin/Discovery/StaticDiscoveryTest.php | 57 ++++++++++++++++++++
 .../Drupal/system/Tests/Plugin/DiscoveryTest.php   | 38 -------------
 .../plugin_test/Plugin/plugin_test/fruit/Apple.php | 20 +++++++
 .../Plugin/plugin_test/fruit/Cherry.php            | 20 +++++++
 .../Plugin/plugin_test/fruit/Orange.php            | 20 +++++++
 .../Plugin/plugin_test/fruit/README.txt            |  3 ++
 12 files changed, 239 insertions(+), 43 deletions(-)

diff --git a/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryInterface.php b/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryInterface.php
index dee79ea..2872f07 100644
--- a/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryInterface.php
+++ b/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryInterface.php
@@ -20,7 +20,7 @@
    *   A plugin id.
    *
    * @return array
-   *   A plugin definition.
+   *   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 a8b1643..4b1dcd4 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 9df7ef6..7a57395 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 37786be..0c77a2f 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/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 0000000..ae9deb1
--- /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 0000000..e95d238
--- /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 0000000..c0adf9f
--- /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 32637c6..0000000
--- 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 0000000..5b8cfa8
--- /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 0000000..97e10ce
--- /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 0000000..b00ca39
--- /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 0000000..433798b
--- /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
