diff --git a/core/lib/Drupal/Core/Annotation/Access.php b/core/lib/Drupal/Core/Annotation/Access.php
new file mode 100644
index 0000000..271e1f8
--- /dev/null
+++ b/core/lib/Drupal/Core/Annotation/Access.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace Drupal\Core\Annotation;
+
+/**
+ * @Annotation
+ */
+class Access {
+  protected $callable;
+  protected $arguments;
+
+  public function __construct($values) {
+    $this->callable = $values['value'];
+    $this->arguments = !empty($values['arguments']) ? $values['arguments'] : array();
+  }
+
+  public function getAccess() {
+    return call_user_func_array($this->callable, $this->arguments);
+  }
+}
diff --git a/core/lib/Drupal/Core/Annotation/Plugin.php b/core/lib/Drupal/Core/Annotation/Plugin.php
new file mode 100644
index 0000000..affcfc7
--- /dev/null
+++ b/core/lib/Drupal/Core/Annotation/Plugin.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace Drupal\Core\Annotation;
+
+use Drupal\Core\Annotation\Translation;
+use Drupal\Core\Annotation\Access;
+
+/**
+ * @Annotation
+ */
+class Plugin {
+  protected $definition;
+
+  public function __construct($values) {
+    foreach ($values as $key => $value) {
+      if ($value instanceof Translation) {
+        $this->definition[$key] = $value->getTranslation();
+      }
+      elseif ($value instanceof Access) {
+        $this->definition[$key] = $value->getAccess();
+      }
+      else {
+        $this->definition[$key] = $value;
+      }
+    }
+  }
+
+  public function getDefinition() {
+    return $this->definition;
+  }
+}
diff --git a/core/lib/Drupal/Core/Annotation/Translation.php b/core/lib/Drupal/Core/Annotation/Translation.php
new file mode 100644
index 0000000..44d5e8b
--- /dev/null
+++ b/core/lib/Drupal/Core/Annotation/Translation.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace Drupal\Core\Annotation;
+
+/**
+ * @Annotation
+ */
+class Translation {
+  protected $translation;
+
+  public function __construct($values) {
+    $string = $values['value'];
+    $options = array();
+    if (!empty($values['context'])) {
+      $options = array(
+        'context' => $values['context'],
+      );
+    }
+    $this->translation = t($string, array(), $options);
+  }
+
+  public function getTranslation() {
+    return $this->translation;
+  }
+}
diff --git a/core/lib/Drupal/Core/Plugin/Discovery/DirectoryDiscovery.php b/core/lib/Drupal/Core/Plugin/Discovery/DirectoryDiscovery.php
new file mode 100644
index 0000000..4fc5f5f
--- /dev/null
+++ b/core/lib/Drupal/Core/Plugin/Discovery/DirectoryDiscovery.php
@@ -0,0 +1,69 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\Component\Plugin\Discovery\DirectoryDiscovery.
+ */
+
+namespace Drupal\Core\Plugin\Discovery;
+
+use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
+use DirectoryIterator;
+use ReflectionClass;
+use Doctrine\Common\Annotations\AnnotationReader;
+use Doctrine\Common\Annotations\AnnotationRegistry;
+use Drupal\Core\Annotation\Plugin;
+
+/**
+ * A discovery mechanism finds annotated plugins in PSR-0 namespaces.
+ */
+class DirectoryDiscovery implements DiscoveryInterface {
+  function __construct($owner, $type) {
+    $this->owner = $owner;
+    $this->type = $type;
+  }
+
+  /**
+   * Implements DerivativeAwareDiscovery::getBasePluginDefinition().
+   */
+  public function getDefinition($plugin_id) {
+    $plugins = $this->getDefinitions();
+    return isset($plugins[$plugin_id]) ? $plugins[$plugin_id] : array();
+  }
+
+  /**
+   * Implements DerivativeAwareDiscovery::getBasePluginDefinitions().
+   */
+  public function getDefinitions() {
+    $definitions = array();
+    $reader = new AnnotationReader();
+    AnnotationRegistry::registerAutoloadNamespace('Drupal\Core\Annotation', array(DRUPAL_ROOT . '/core/lib'));
+    $namespaces = drupal_classloader()->getNamespaces();
+    foreach ($namespaces as $ns => $namespace_dirs) {
+      $ns = str_replace('\\', DIRECTORY_SEPARATOR, $ns);
+      foreach ($namespace_dirs as $dir) {
+        $prefix = implode(DIRECTORY_SEPARATOR, array(
+          $ns,
+          'Plugins',
+          $this->owner,
+          $this->type
+        ));
+        $dir .= DIRECTORY_SEPARATOR . $prefix;
+        if (file_exists($dir)) {
+          foreach (new DirectoryIterator($dir) as $fileinfo) {
+            if ($fileinfo->getExtension() == 'php') {
+              $reflectionClass = new ReflectionClass(str_replace(DIRECTORY_SEPARATOR, '\\', "$prefix/". $fileinfo->getBasename('.php')));
+              if ($annotation = $reader->getClassAnnotation($reflectionClass, 'Drupal\Core\Annotation\Plugin')) {
+                $definition = $annotation->getDefinition();
+                $definition['class'] = $reflectionClass->name;
+                $definitions[$definition['plugin_id']] = $definition;
+              }
+            }
+          }
+        }
+      }
+    }
+    return $definitions;
+  }
+}
+
