diff --git a/core/lib/Drupal/Component/Plugin/Derivative/DerivativeInterface.php b/core/lib/Drupal/Component/Plugin/Derivative/DerivativeInterface.php
index 281a4ca..ad2e04b 100644
--- a/core/lib/Drupal/Component/Plugin/Derivative/DerivativeInterface.php
+++ b/core/lib/Drupal/Component/Plugin/Derivative/DerivativeInterface.php
@@ -11,9 +11,6 @@ namespace Drupal\Component\Plugin\Derivative;
  */
 interface DerivativeInterface {
 
-
-  public function __construct($scope, $type, $plugin, array $config);
-
   /**
    * Set a specific derivative for the instance to return.
    *
@@ -31,6 +28,6 @@ interface DerivativeInterface {
    *   An array of Configuration objects for all potential derivatives of this
    *   plugin implementation.
    */
-  public function getDerivatives();
+  public static function getDerivatives();
 
 }
diff --git a/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryAbstract.php b/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryAbstract.php
new file mode 100644
index 0000000..2aeeb51
--- /dev/null
+++ b/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryAbstract.php
@@ -0,0 +1,54 @@
+<?php
+
+/**
+ * @file
+ * ...
+ */
+
+namespace Drupal\Component\Plugin\Discovery;
+
+use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
+
+abstract class DiscoveryAbstract implements DiscoveryInterface {
+
+  public function getPluginDefinition($plugin_id) {}
+
+  public function getPluginDefinitions() {}
+
+  public function derivePluginId($plugin) {
+    @list($plugin_id, $derivative) = explode(':', $plugin, 2);
+    return array($plugin_id, $derivative);
+  }
+
+  public function getDerivative(array $definition, $derivative) {
+    if (!empty($definition['derivative'])) {
+      if (!empty($derivative) && class_exists($definition['derivative'])) {
+        $derviative_mapper = new $definition['derivative']();
+        $config = $derviative_mapper->getDerivative($derivative);
+        return $config + $definition;
+      }
+      return !empty($definition['use_base']) ? $definition : array();
+    }
+    return $definition;
+  }
+
+  /**
+   * Implements DiscoveryInterface::getPluginDefinitions().
+   */
+  public function getDerivatives($definition, $plugin_id) {
+    $definitions = array();
+    if (isset($definition['derivative'])) {
+      foreach ($definition['derivative']::getDerivatives() as $derivative_id => $derivative) {
+        $definitions["$plugin_id:$derivative_id"] = $derivative += $definition;
+      }
+      if (!empty($definition['use_base'])) {
+        $definitions[$plugin_id] = $definition;
+      }
+    }
+    else {
+      $definitions[$plugin_id] = $definition;
+    }
+    return $definitions;
+  }
+
+}
diff --git a/core/lib/Drupal/Component/Plugin/Discovery/StaticDiscovery.php b/core/lib/Drupal/Component/Plugin/Discovery/StaticDiscovery.php
index 97bd093..59ce7b3 100644
--- a/core/lib/Drupal/Component/Plugin/Discovery/StaticDiscovery.php
+++ b/core/lib/Drupal/Component/Plugin/Discovery/StaticDiscovery.php
@@ -10,7 +10,7 @@ use Drupal\Component\Plugin\PluginTypeInterface;
 /**
  *
  */
-class StaticDiscovery implements DiscoveryInterface {
+class StaticDiscovery implements DiscoveryAbstract {
 
   /**
    * The plugin type object.
@@ -29,14 +29,24 @@ class StaticDiscovery implements DiscoveryInterface {
    * Implements DiscoveryInterface::getPluginDefinition().
    */
   public function getPluginDefinition($plugin_id) {
-    return isset($this->plugin_definitions[$plugin_id]) ? $this->plugin_definitions[$plugin_id] : array();
+    list($plugin_id, $derivative) = $this->derivePluginId($plugin_id);
+    if (isset($this->plugin_definitions[$plugin_id])) {
+      return $this->getDerivative($this->plugin_definitions[$plugin_id], $derivative);
+    }
+    return array();
   }
 
   /**
    * Implements DiscoveryInterface::getPluginDefinitions().
    */
   public function getPluginDefinitions() {
-    return isset($this->plugin_definitions) ? $this->plugin_definitions : array();
+    $definitions = array();
+    if (isset($this->plugin_definitions)) {
+      foreach ($this->plugin_definitions as $id => $definition) {
+        $definitions += $this->getDerivatives($definition, $id);
+      }
+    }
+    return $definitions;
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Plugin/Discovery/ConfigDiscovery.php b/core/lib/Drupal/Core/Plugin/Discovery/ConfigDiscovery.php
index 2f690e8..ade610d 100644
--- a/core/lib/Drupal/Core/Plugin/Discovery/ConfigDiscovery.php
+++ b/core/lib/Drupal/Core/Plugin/Discovery/ConfigDiscovery.php
@@ -6,10 +6,10 @@
  */
 
 namespace Drupal\Core\Plugin\Discovery;
-use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
+use Drupal\Component\Plugin\Discovery\DiscoveryAbstract;
 use Drupal\Component\Plugin\PluginTypeInterface;
 
-class ConfigDiscovery implements DiscoveryInterface {
+class ConfigDiscovery extends DiscoveryAbstract {
 
   /**
    * The plugin type object.
@@ -29,30 +29,23 @@ class ConfigDiscovery implements DiscoveryInterface {
    * Implements DicoveryInterface::getPluginDefinition().
    */
   public function getPluginDefinition($plugin_id) {
-    $config = config("{$this->definition_root}.$plugin_id")->get();
-    if ($config['derivative']) {
-      $derviative_mapper = new $config['derivative']($this->definition_root, $plugin_id, $config);
-      $config = $derviative_mapper->getDerviative($plugin_id);
-    }
-    return $this->pluginType->processPluginDefinition($config);
+    list($plugin_id, $derivative) = $this->derivePluginId($plugin_id);
+    $definition = config("{$this->definition_root}.$plugin_id")->get();
+    $this->pluginType->processPluginDefinition($definition);
+    return $this->getDerivative($definition, $derivative);
   }
 
   /**
    * Implements DicoveryInterface::getPluginDefinitions().
    */
   public function getPluginDefinitions() {
-    $plugins = array();
-    foreach (config_get_signed_file_storage_names_with_prefix($this->definition_root) as $plugin_id) {
-      $plugins[$plugin_id] = config($plugin_id)->get();
-      if (!empty($plugins[$plugin_id]['derivative'])) {
-        $derviative_mapper = new $plugins[$plugin_id]['derivative']($this->definition_root, $plugin_id, $plugins[$plugin_id]);
-        $derivatives = $derviative_mapper->getDerivatives();
-        foreach ($derivatives as $derivative_id => $derivative) {
-          $plugins[$derivative_id] = $this->pluginType->processPluginDefinition($derivative);
-        }
-        unset($plugins[$plugin_id]);
-      }
+    $definitions = array();
+    foreach (config_get_signed_file_storage_names_with_prefix($this->definition_root) as $config_name) {
+      $plugin_id = substr($config_name, strlen($this->definition_root) + 1);
+      $definition = config($config_name)->get();
+      $this->pluginType->processPluginDefinition($definition);
+      $definitions += $this->getDerivatives($definition, $pluging_id);
     }
-    return $plugins;
+    return $definitions;
   }
 }
diff --git a/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/Derivative/DerivativeTest.php b/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/Derivative/DerivativeTest.php
new file mode 100644
index 0000000..3f8ab06
--- /dev/null
+++ b/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/Derivative/DerivativeTest.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace Drupal\plugin_test\Plugin\Derivative;
+
+use Drupal\Component\Plugin\Derivative\DerivativeInterface;
+
+class DerivativeTest implements DerivativeInterface {
+  /**
+   * Implement DerivativeInterface::getDerivative().
+   */
+  public function getDerivative($key) {
+    $derivatives = $this->getDerivatives();
+    return isset($derivatives[$key]) ? $derivatives[$key] : FALSE;
+  }
+
+  /**
+   * Implement DerivativeInterface::getDerivatives().
+   */
+  public static function getDerivatives() {
+    return array(
+      'test1' => array(
+        'string' => 'Test String 1',
+      ),
+      'test2' => array(
+        'string' => 'Test String 2',
+      ),
+    );
+  }
+}
\ No newline at end of file
diff --git a/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/TestPluginInstanceClass.php b/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/TestPluginInstanceClass.php
index 0febf83..c063a5a 100644
--- a/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/TestPluginInstanceClass.php
+++ b/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/TestPluginInstanceClass.php
@@ -9,4 +9,7 @@ namespace Drupal\plugin_test\Plugin;
 use Drupal\Component\Plugin\PluginAbstract;
 
 class TestPluginInstanceClass extends PluginAbstract {
+  public function string() {
+    return $this->config['string'];
+  }
 }
diff --git a/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/Type/TestPluginType.php b/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/Type/TestPluginType.php
index d54e4d0..ff633c1 100644
--- a/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/Type/TestPluginType.php
+++ b/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/Type/TestPluginType.php
@@ -18,6 +18,17 @@ class TestPluginType extends PluginType {
       'string' => 'oh yeah',
       'class' => 'Drupal\plugin_test\Plugin\TestPluginInstanceClass',
     ));
+    $this->discovery->setPluginDefinition('beer', array(
+      'string' => 'derivative test',
+      'class' => 'Drupal\plugin_test\Plugin\TestPluginInstanceClass',
+      'derivative' => 'Drupal\plugin_test\Plugin\Derivative\DerivativeTest',
+      'use_base' => TRUE,
+    ));
+    $this->discovery->setPluginDefinition('wine', array(
+      'string' => 'derivative test',
+      'class' => 'Drupal\plugin_test\Plugin\TestPluginInstanceClass',
+      'derivative' => 'Drupal\plugin_test\Plugin\Derivative\DerivativeTest',
+    ));
     $this->factory = new DefaultFactory($this, 'class');
     $this->mapper = new DefaultMapper($this);
   }
diff --git a/core/modules/system/tests/plugins.test b/core/modules/system/tests/plugins.test
index 0966593..112c037 100644
--- a/core/modules/system/tests/plugins.test
+++ b/core/modules/system/tests/plugins.test
@@ -68,7 +68,74 @@ class PluginTestCase extends PluginUnitTestCase {
   }
 
   function testPluginInstanceFetching() {
-    $plugin = $this->TestPluginType->createPluginInstance('coolaid');
+    $plugin = $this->TestPluginType->createPluginInstance('coolaid', array('config' => array('string' => 'this is a test')));
     $this->assertEqual(get_class($plugin), 'Drupal\plugin_test\Plugin\TestPluginInstanceClass', 'Correct plugin instance implementation returned by the test plugin type.');
+    $this->assertEqual($plugin->string(), 'this is a test', 'Plugin instance returns the proper string');
+  }
+
+  function testPluginDerivativeDefintionFetching() {
+    $plugin_definition = $this->TestPluginType->getPluginDefinition('beer:test1');
+    $this->assertEqual($plugin_definition['string'], 'Test String 1', 'Plugin derivative definition retrievable by the test plugin type.');
+  }
+
+  function testPluginEmptyDerivativeDefintionFetching() {
+    $plugin_definition = $this->TestPluginType->getPluginDefinition('beer');
+    $this->assertEqual($plugin_definition['string'], 'derivative test', 'Plugin derivative base returns the proper string');
+  }
+
+  function testPluginInstanceDerivativeFetching() {
+    $plugin_definition = $this->TestPluginType->getPluginDefinition('beer:test1');
+    $plugin = $this->TestPluginType->createPluginInstance('beer:test1', array('config' => $plugin_definition));
+    $this->assertEqual($plugin->string(), 'Test String 1', 'Plugin derivative instance 1 returns the proper string');
+
+    $plugin_definition = $this->TestPluginType->getPluginDefinition('beer:test2');
+    $plugin = $this->TestPluginType->createPluginInstance('beer:test2', array('config' => $plugin_definition));
+    $this->assertEqual($plugin->string(), 'Test String 2', 'Plugin derivative instance 2 returns the proper string');
+  }
+
+  function testPluginEmptyDerivativeInstanceFetching() {
+    try {
+      // This test is working against a plugin definition which does not
+      // use_base => TRUE, and so it should throw an exception.
+      $plugin = $this->TestPluginType->createPluginInstance('wine');
+      $this->fail('Drupal\Component\Plugin\PluginException expected');
+    }
+    catch (Exception $e) {
+      if ($e instanceof Drupal\Component\Plugin\PluginException) {
+        $this->pass('Drupal\Component\Plugin\PluginException expected and caught.');
+      }
+      else {
+        $this->fail('Drupal\Component\Plugin\PluginException expected');
+      }
+    }
+    try {
+      // This test is working against a plugin definition which does
+      // use_base => TRUE, and so it should not throw an exception.
+      $plugin = $this->TestPluginType->createPluginInstance('beer');
+      $this->pass('Drupal\Component\Plugin\PluginException not thrown');
+    }
+    catch (Exception $e) {
+      $this->fail('An unexpected exception was thrown.');
+    }
+  }
+
+  function testPluginGetDefinitions() {
+    $definitions = $this->TestPluginType->getPluginDefinitions();
+    $set = array (
+      'coolaid',
+      'beer:test1',
+      'beer:test2',
+      'beer',
+      'wine:test1',
+      'wine:test2',
+    );
+    $test = FALSE;
+    foreach ($set as $plugin_id) {
+      if (!array_key_exists($plugin_id, $definitions)) {
+        $this->fail('An expected plugin id was not defined.');
+        return;
+      }
+    }
+    $this->pass('All plugin ids and derivatives that were expected were found.');
   }
 }
