diff --git a/core/lib/Drupal/Core/Plugin/Discovery/AnnotatedClassDiscovery.php b/core/lib/Drupal/Core/Plugin/Discovery/AnnotatedClassDiscovery.php
index bd89a92..144eda0 100644
--- a/core/lib/Drupal/Core/Plugin/Discovery/AnnotatedClassDiscovery.php
+++ b/core/lib/Drupal/Core/Plugin/Discovery/AnnotatedClassDiscovery.php
@@ -21,6 +21,39 @@
 class AnnotatedClassDiscovery implements DiscoveryInterface {
 
   /**
+   * @var array $custom_location
+   *
+   *   key: namespace of you class.
+   *   value is an array containing:
+   *     dir: the directory to scan.
+   *     class_base: namespace of you class.
+   */
+  protected $custom_location = array();
+
+  /**
+   * Sets the custom location(s) to scan.
+   *
+   * @param array $custom_locations
+   *
+   *   key: namespace of you class.
+   *   value is an array containing:
+   *     dir: the directory to scan.
+   *     class_base: namespace of you class.
+   */
+  public function setCustomLocation(array $custom_locations) {
+    $this->custom_location = $custom_locations;
+  }
+
+  /**
+   * Gets the custom locations.
+   *
+   * @return array
+   */
+  public function getCustomLocation() {
+    return $this->custom_location;
+  }
+
+  /**
    * Constructs an AnnotatedClassDiscovery object.
    */
   function __construct($owner, $type) {
@@ -49,33 +82,42 @@ public function getDefinitions() {
     AnnotationRegistry::registerAutoloadNamespace('Drupal\Core\Annotation', array(DRUPAL_ROOT . '/core/lib'));
     // Get all PSR-0 namespaces.
     $namespaces = drupal_classloader()->getNamespaces();
+    // Rewrite all directories.
     foreach ($namespaces as $ns => $namespace_dirs) {
-
       // OS-Safe directory separators.
       $ns = str_replace('\\', DIRECTORY_SEPARATOR, $ns);
+      // Check for the pre-determined directory structure to find plugins.
+      $prefix = implode(DIRECTORY_SEPARATOR, array(
+        $ns,
+        'Plugin',
+        $this->owner,
+        $this->type
+      ));
+      foreach ($namespace_dirs as $key => $dir) {
+        $namespaces[$ns][$key] = array(
+          'dir' => $dir .= DIRECTORY_SEPARATOR . $prefix,
+          'class_base' => str_replace(
+            DIRECTORY_SEPARATOR,
+            '\\',
+            $prefix
+          ),
+        );
+      }
+    }
+    // Merge in the custom locations.
+    if (!empty($this->custom_location)) {
+      $namespaces += $this->custom_location;
+    }
 
-      foreach ($namespace_dirs as $dir) {
-        // Check for the pre-determined directory structure to find plugins.
-        $prefix = implode(DIRECTORY_SEPARATOR, array(
-          $ns,
-          'Plugin',
-          $this->owner,
-          $this->type
-        ));
-        $dir .= DIRECTORY_SEPARATOR . $prefix;
-
-        // If the directory structure exists, look for classes.
+    foreach ($namespaces as $ns => $namespace_dirs) {
+      foreach ($namespace_dirs as $dir_info) {
+        $dir = $dir_info['dir'];
         if (file_exists($dir)) {
           $directories = new DirectoryIterator($dir);
           foreach ($directories as $fileinfo) {
             // @todo Once core requires 5.3.6, use $fileinfo->getExtension().
             if (pathinfo($fileinfo->getFilename(), PATHINFO_EXTENSION) == 'php') {
-              $class = str_replace(
-                DIRECTORY_SEPARATOR,
-                '\\',
-                $prefix . DIRECTORY_SEPARATOR . $fileinfo->getBasename('.php')
-              );
-
+              $class = $dir_info['class_base'] . '\\' . $fileinfo->getBasename('.php');
               // The filename is already known, so there is no need to find the
               // file. However, StaticReflectionParser needs a finder, so use a
               // mock version.
