diff --git a/plugin_type_example/plugin_type_example.module b/plugin_type_example/plugin_type_example.module
index 426781e..eea5ec8 100644
--- a/plugin_type_example/plugin_type_example.module
+++ b/plugin_type_example/plugin_type_example.module
@@ -11,45 +11,61 @@
  * @{
  * Example of how to define a plugin type.
  *
- * Our example defines a Sandwich plugin type.  Sandwich's come in many flavors,
- * each having their unique qualities, but also sharing things in common.  Our
+ * Our example defines a Sandwich plugin type. Sandwich's come in many flavors,
+ * each having their unique qualities, but also sharing things in common. Our
  * Sandwich plugins will be very simple, each providing a unique description
- * or themselves.  Sandwich plugins also have an id and a property called
- * foobar, which we'll use to demonstrate how you can alter a plugin using an
- * alter hook.
+ * of themselves. In addition to the id property required by all plugin types,
+ * sandwich plugins have description, and calories properties.
+ *
+ * Defining a new plugin type requires the following steps:
+ * - Define an annotation class for your plugin type used to provide
+ *   documentation about the meta-data needed by your plugin type.
+ * - Define an interface for plugins of your new type to implement.
+ * - Define a new plugin manager.
+ * - Provide an optional base class that implements your plugin type's interface
+ *   as a starting point for other plugin implementations.
  *
  * Start at the class \Drupal\plugin_type_example\SandwichPluginManager, which
- * defines our plugin type manager.  Our plugin type manager is exposed to
- * Drupal as a service in the plugin_type_example.services.yml file.
+ * defines our plugin manager. Our plugin manager is exposed to Drupal as a
+ * service in the plugin_type_example.services.yml file, and is used to glue
+ * our Drupal\plugin_type_example\SandwichInterface, and
+ * \Drupal\plugin_type_example\Annotation\Sandwich annotation definition
+ * together into a new plugin type.
  *
  * We've also defined two implementations of our plugin type,
  * \Drupal\plugin_type_example\Plugin\Sandwich\ExampleHamSandwich and
  * \Drupal\plugin_type_example\Plugin\Sandwich\ExampleMeatballSandwich. Take a
- * look at each.  These plugins use annotated plugin discovery, and as such have
- * an annotation block in the doc block for the class.  Other than that, they
+ * look at each. These plugins use annotated plugin discovery, and as such have
+ * an annotation block in the doc block for the class. Other than that, they
  * implement the \Drupal\plugin_type_example\SandwichInterface, which is
  * required, since we've set that interface for the plugin type in
  * \Drupal\plugin_type_example\SandwichPluginManager::__construct.
  *
- * To see the plugins in action visit /examples/plugin_type_example.  The output
+ * In plugin_type_example_sandwich_info_alter() we'll demonstrate how you can
+ * alter a plugin definition using an alter hook.
+ *
+ * To see the plugins in action visit /examples/plugin_type_example. The output
  * is rendered in
  * Drupal\plugin_type_example\Controller\PluginTypeExampleController::description().
- * Read through that method to see how to use plugins using the
+ * Read through that method to see how to make use of plugins using the
  * plugin.manager.sandwich service.
  */
 
 /**
  * Implements hook_sandwich_info_alter().
+ *
+ * Any module can implement hook_sandwich_info_alter() and alter the definitions
+ * of all plugins discovered by the plugin manager.
+ *
+ * Note: Plugin definitions are cached after initially being discovered, and
+ * altered. Any changes you make here will require a cache clear to take effect.
+ *
+ * @see \Drupal\plugin_type_example\SandwichPluginManager
  */
 function plugin_type_example_sandwich_info_alter(&$sandwich_plugin_info) {
-  // Let's change the 'foobar' property for all sandwiches.
+  // Let's change the 'description' property for all sandwiches.
   foreach ($sandwich_plugin_info as $plugin_id => $plugin_definition) {
-    $sandwich_plugin_info[$plugin_id]['foobar'] = t('We have altered this in the alter hook');
+    // Always uppercase the word rocket in sandwich descriptions.
+    $sandwich_plugin_info[$plugin_id]['description'] = str_replace(t('rocket'), t('ROCKET'), $sandwich_plugin_info[$plugin_id]['description']);
   }
-
-  // The ham sandwich is more calorific in our system.  Note that the string
-  // 'ham_sandwich' is the id name of the Ham Sandwich plugin, which is set
-  // in the annotation in
-  // \Drupal\plugin_type_example\Plugin\Sandwich\ExampleHamSandwich.
-  $sandwich_plugin_info['ham_sandwich']['calories'] = 500;
 }
diff --git a/plugin_type_example/plugin_type_example.services.yml b/plugin_type_example/plugin_type_example.services.yml
index bd9c129..db658ff 100644
--- a/plugin_type_example/plugin_type_example.services.yml
+++ b/plugin_type_example/plugin_type_example.services.yml
@@ -1,19 +1,11 @@
-# This declares the plugin manager to the service container.
-# For background information on the service container, see
-# http://symfony.com/doc/current/book/service_container.html.
-# Services declaration files such as this one are compiled to PHP code in
-# sites/default/files/php/service_container, so changes here require that folder
-# to be deleted in order to have Drupal notice them.
+# This declares the plugin manager to the service container. For background
+# information on the service container, see https://www.drupal.org/node/2133171.
+# Changes here require that the cache be cleared in order to have Drupal notice
+# them.
 services:
   # The machine name of the service. This is the string that must be passed to
   # Drupal::service() to get the instantiated plugin manager.
   plugin.manager.sandwich:
     # This tells the service container the name of our plugin manager class.
     class: Drupal\plugin_type_example\SandwichPluginManager
-    # The default parameters to pass to the class constructor,
-    # SandwichPluginManager::__construct().
-    # Arguments beginning with @ are the names of other services that are being
-    # injected into this service. Many common ones are found in
-    # /core/core.services.yml.
-    # See https://drupal.org/node/2133171 for more detail.
-    arguments: ['@container.namespaces', '@cache.default', '@module_handler']
+    parent: default_plugin_manager
diff --git a/plugin_type_example/src/Annotation/Sandwich.php b/plugin_type_example/src/Annotation/Sandwich.php
new file mode 100644
index 0000000..211fdf2
--- /dev/null
+++ b/plugin_type_example/src/Annotation/Sandwich.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace Drupal\plugin_type_example\Annotation;
+
+use Drupal\Component\Annotation\Plugin;
+
+/**
+ * Defines a Sandwich annotation object.
+ *
+ * Provides an example of how to define a new annotation type for use in
+ * defining a plugin type. Demonstrates documenting the various properties that
+ * can be used in annotations for plugins of this type.
+ *
+ * Note that the "@ Annotation" line below is required and should be the last
+ * line in the docblock. It's used for discovery of Annotation definitions.
+ *
+ * @see \Drupal\plugin_type_example\SandwichPluginManager
+ * @see plugin_api
+ *
+ * @Annotation
+ */
+class Sandwich extends Plugin {
+
+  /**
+   * The plugin ID.
+   *
+   * @var string
+   */
+  public $id;
+
+  /**
+   * A brief, human readable, description of the sandwich type.
+   *
+   * This property is designated as being translatable because it will appear
+   * in the user interface. This provides a hint to other developers that they
+   * should use the Translation() construct in their annotation when declaring
+   * this property.
+   *
+   * @var \Drupal\Core\Annotation\Translation
+   *
+   * @ingroup plugin_translatable
+   */
+  public $description;
+
+  /**
+   * The number of calories per serving of this sandwich type.
+   *
+   * This property is a float value, so we indicate that to other developers
+   * who are writing annotations for a Sandwich plugin.
+   *
+   * @var int
+   */
+  public $calories;
+
+}
diff --git a/plugin_type_example/src/Controller/PluginTypeExampleController.php b/plugin_type_example/src/Controller/PluginTypeExampleController.php
index f1cf8ee..90ca345 100644
--- a/plugin_type_example/src/Controller/PluginTypeExampleController.php
+++ b/plugin_type_example/src/Controller/PluginTypeExampleController.php
@@ -35,10 +35,14 @@ class PluginTypeExampleController extends ControllerBase {
    * Displays a page with an overview of our plugin type and plugins.
    *
    * Lists all the Sandwich plugin definitions by using methods on the
-   * \Drupal\plugin_type_example\SandwichPluginManager class.  Lists out the
+   * \Drupal\plugin_type_example\SandwichPluginManager class. Lists out the
    * description for each plugin found by invoking methods defined on the
-   * plugins themselves.  You can find the plugins we have defined in the
+   * plugins themselves. You can find the plugins we have defined in the
    * \Drupal\plugin_type_example\Plugin\Sandwich namespace.
+   *
+   * @return array
+   *   Render API array with content for the page at
+   *   /examples/plugin_type_example.
    */
   public function description() {
     $build = array();
@@ -48,9 +52,8 @@ class PluginTypeExampleController extends ControllerBase {
     );
 
     // Get the list of all the sandwich plugins defined on the system from the
-    // plugin manager.
-    // Note that at this point, what we have is *definitions* of plugins, not
-    // the plugins themselves.
+    // plugin manager. Note that at this point, what we have is *definitions* of
+    // plugins, not the plugins themselves.
     $sandwich_plugin_definitions = $this->sandwichManager->getDefinitions();
 
     // Let's output a list of the plugin definitions we now have.
@@ -58,11 +61,11 @@ class PluginTypeExampleController extends ControllerBase {
     foreach ($sandwich_plugin_definitions as $sandwich_plugin_definition) {
       // Here we use various properties from the plugin definition. These values
       // are defined in the annotation at the top of the plugin class: see
-      // ExampleHamSandwich.
-      $items[] = t("@id (calories: @calories, foobar: @foobar )", array(
-        '@id'       => $sandwich_plugin_definition['id'],
+      // \Drupal\plugin_type_example\Plugin\Sandwich\ExampleHamSandwich.
+      $items[] = t("@id (calories: @calories, description: @description )", array(
+        '@id' => $sandwich_plugin_definition['id'],
         '@calories' => $sandwich_plugin_definition['calories'],
-        '@foobar'   => $sandwich_plugin_definition['foobar'],
+        '@description' => $sandwich_plugin_definition['description'],
       ));
     }
 
@@ -75,18 +78,20 @@ class PluginTypeExampleController extends ControllerBase {
 
     // If we want just a single plugin definition, we can use getDefinition().
     // This requires us to know the ID of the plugin we want. This is set in the
-    // annotation on the plugin class: see ExampleHamSandwich.
-    $ham_sandwich_plugin_definition = $this->sandwichManager->getDefinition('ham_sandwich');
-
-    // To get an actual plugin, we call createInstance() on the plugin manager,
-    // passing the ID of the plugin we want to load. Let's output a list of the
-    // actual plugins.
+    // annotation on the plugin class: see
+    // \Drupal\plugin_type_example\Plugin\Sandwich\ExampleHamSandwich.
+    $ham_sandwich_plugin_definition = $this->sandwichManager->getDefinition('meatball_sandwich');
+
+    // To get an instance of a plugin, we call createInstance() on the plugin
+    // manager, passing the ID of the plugin we want to load. Let's output a
+    // list of the plugins by loading an instance of each plugin definition and
+    // collecting the description from each.
     $items = array();
     // The array of plugin definitions is keyed by plugin id, so we can just use
-    // that to load our plugins.
+    // that to load our plugin instances.
     foreach ($sandwich_plugin_definitions as $plugin_id => $sandwich_plugin_definition) {
-      // We now have a plugin! From here on it can be treated just as any other
-      // object: have its properties examined, methods called, etc.
+      // We now have a plugin instance. From here on it can be treated just as
+      // any other object; have its properties examined, methods called, etc.
       $plugin = $this->sandwichManager->createInstance($plugin_id, array('of' => 'configuration values'));
       $items[] = $plugin->description();
     }
@@ -103,21 +108,17 @@ class PluginTypeExampleController extends ControllerBase {
   /**
    * {@inheritdoc}
    *
-   * Override the parent method so that we can inject out sandwich plugin
-   * manager service into the controller.  This is dependancy injection at work
-   * for a controller.  Rather than access the global service container via
-   * \Drupal::service(), it's best practice to use dependancy injection.  Notice
-   * our controller extends ControllerBase, which implements the
-   * ContainerInjectionInterface interface.  As such we can implement a create
-   * method to control how our controller in instantiated.  We do just that,
-   * passing in the sandwich plugin manager service that we need.
+   * Override the parent method so that we can inject our sandwich plugin
+   * manager service into the controller.
+   *
+   * For more about how dependency injection works read
+   * https://www.drupal.org/node/2133171
+   *
+   * @see container
    */
   public static function create(ContainerInterface $container) {
-    // Use the service container to instantiate a new instance of our
-    // controller.  The string we pass is the machine name of the service,
-    // which is set in the plugin_type_example.services.yml file.  We get back
-    // an instance of our SandwichPluginManager class, which is passed to the
-    // controller's constructor.
+    // Inject the plugin.manager.sandwich service that represents our plugin
+    // manager as defined in the plugin_type_example.services.yml file.
     return new static($container->get('plugin.manager.sandwich'));
   }
 
diff --git a/plugin_type_example/src/Plugin/Sandwich/ExampleHamSandwich.php b/plugin_type_example/src/Plugin/Sandwich/ExampleHamSandwich.php
index f09c837..5e39eba 100644
--- a/plugin_type_example/src/Plugin/Sandwich/ExampleHamSandwich.php
+++ b/plugin_type_example/src/Plugin/Sandwich/ExampleHamSandwich.php
@@ -2,15 +2,15 @@
 
 namespace Drupal\plugin_type_example\Plugin\Sandwich;
 
-use Drupal\Core\Plugin\PluginBase;
-use Drupal\plugin_type_example\SandwichInterface;
+use Drupal\plugin_type_example\SandwichBase;
 
 /**
  * Provides a ham sandwich.
  *
  * Because the plugin manager class for our plugins uses annotated class
- * discovery, our ham sandwich only needs to exist within the Plugin\Sandwich
- * namespace to be declared as a plugin. This is defined in
+ * discovery, our meatball sandwich only needs to exist within the
+ * Plugin\Sandwich namespace, and provide a Sandwich annotation to be declared
+ *  as a plugin. This is defined in
  * \Drupal\plugin_type_example\SandwichPluginManager::__construct().
  *
  * The following is the plugin annotation. This is parsed by Doctrine to make
@@ -22,22 +22,30 @@ use Drupal\plugin_type_example\SandwichInterface;
  * available plugins where the user selects one. This means many plugin
  * annotations can be reduced to a plugin ID, a label and perhaps a description.
  *
- * @Plugin(
+ * @Sandwich(
  *   id = "ham_sandwich",
- *   foobar = @Translation("This is an example value that is defined in the annotation."),
- *   calories = 426,
+ *   description = @Translation("Ham, mustard, rocket, sun-dried tomatoes."),
+ *   calories = 426
  * )
  */
-class ExampleHamSandwich extends PluginBase implements SandwichInterface {
+class ExampleHamSandwich extends SandwichBase {
 
   /**
-   * Get a description of the sandwich fillings.
+   * Place an order for a sandwich.
    *
    * This is just an example method on our plugin that we can call to get
    * something back.
+   *
+   * @param array $extras
+   *   Array of extras to include with this order.
+   *
+   * @return string
+   *   A description of the sandwich ordered.
    */
-  public function description() {
-    return $this->t('Ham, mustard, rocket, sun-dried tomatoes.');
+  public function order(array $extras) {
+    $ingredients = array('ham, mustard', 'rocket', 'sun-dried tomatoes');
+    $sandwich = array_merge($ingredients, $extras);
+    return 'You ordered an ' . implode(', ', $sandwich) . ' sandwich. Enjoy!';
   }
 
 }
diff --git a/plugin_type_example/src/Plugin/Sandwich/ExampleMeatballSandwich.php b/plugin_type_example/src/Plugin/Sandwich/ExampleMeatballSandwich.php
index 4922769..9df63c7 100644
--- a/plugin_type_example/src/Plugin/Sandwich/ExampleMeatballSandwich.php
+++ b/plugin_type_example/src/Plugin/Sandwich/ExampleMeatballSandwich.php
@@ -2,15 +2,19 @@
 
 namespace Drupal\plugin_type_example\Plugin\Sandwich;
 
-use Drupal\Core\Plugin\PluginBase;
-use Drupal\plugin_type_example\SandwichInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\Core\StringTranslation\TranslationInterface;
+use Drupal\plugin_type_example\SandwichBase;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Provides a meatball sandwich.
  *
  * Because the plugin manager class for our plugins uses annotated class
  * discovery, our meatball sandwich only needs to exist within the
- * Plugin\Sandwich namespace to be declared as a plugin. This is defined in
+ * Plugin\Sandwich namespace, and provide a Sandwich annotation to be declared
+ * as a plugin. This is defined in
  * \Drupal\plugin_type_example\SandwichPluginManager::__construct().
  *
  * The following is the plugin annotation. This is parsed by Doctrine to make
@@ -22,22 +26,81 @@ use Drupal\plugin_type_example\SandwichInterface;
  * available plugins where the user selects one. This means many plugin
  * annotations can be reduced to a plugin ID, a label and perhaps a description.
  *
- * @Plugin(
+ * @Sandwich(
  *   id = "meatball_sandwich",
- *   foobar = @Translation("Right around that corner there is a sandwich shop. They sell meatball sandwiches, the best I ever tasted. Would you go get me two? Come on partner. Thank you. Utah! Get me two!"),
- *   calories = 1200,
+ *   description = @Translation("Italian style meatballs drenched in irresistible marinara sauce, served on freshly baked bread."),
+ *   calories = "1200"
  * )
  */
-class ExampleMeatballSandwich extends PluginBase implements SandwichInterface {
+class ExampleMeatballSandwich extends SandwichBase implements ContainerFactoryPluginInterface {
+
+  // Use Drupal\Core\StringTranslation\StringTranslationTrait to define
+  // $this->t() for string translations in our plugin.
+  use StringTranslationTrait;
 
   /**
-   * Get a description of the sandwich fillings.
+   * The day the sandwich is ordered.
+   *
+   * Since meatball sandwiches have a special behavior on Sundays, and since we
+   * want to test that behavior on days other than Sunday, we have to store the
+   * day as a property so we can test it.
+   *
+   * This is the string representation of the day of the week you get from
+   * date('D').
    *
-   * This is just an example method on our plugin that we can call to get
-   * something back.
+   * @var string
+   */
+  protected $day;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    // This class needs to translate strings, so we need to inject the string
+    // translation service from the container. This means our plugin class has
+    // to implement ContainerFactoryPluginInterface. This requires that we make
+    // this create() method, and use it to inject services from the container.
+    // @see https://www.drupal.org/node/2012118
+    $sandwich = new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('string_translation')
+    );
+    return $sandwich;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, TranslationInterface $translation) {
+    // Store the translation service.
+    $this->setStringTranslation($translation);
+    // Store the day so we can generate a special description on Sundays.
+    $this->day = date('D');
+    // Pass the other parameters up to the parent constructor.
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function order(array $extras) {
+    $ingredients = array('meatballs', 'irresistible marinara sauce');
+    $sandwich = array_merge($ingredients, $extras);
+    return 'You ordered an ' . implode(', ', $sandwich) . ' sandwich. Enjoy!';
+  }
+
+  /**
+   * {@inheritdoc}
    */
   public function description() {
-    return $this->t('Enjoy Italian style meatballs drenched in irresistible marinara sauce, served on freshly baked bread.');
+    // We override the description() method in order to change the description
+    // text based on the date. On Sunday we only have day old bread.
+    if ($this->day == 'Sun') {
+      return $this->t("Italian style meatballs drenched in irresistible marinara sauce, served on day old bread.");
+    }
+    return parent::description();
   }
 
 }
diff --git a/plugin_type_example/src/SandwichBase.php b/plugin_type_example/src/SandwichBase.php
new file mode 100644
index 0000000..8a1cfc8
--- /dev/null
+++ b/plugin_type_example/src/SandwichBase.php
@@ -0,0 +1,53 @@
+<?php
+
+namespace Drupal\plugin_type_example;
+
+use Drupal\Component\Plugin\PluginBase;
+
+/**
+ * A base class to help developers implement their own sandwich plugins.
+ *
+ * This is a helper class which makes it easier for other developers to
+ * implement sandwich plugins in their own modules. In SandwichBase we provide
+ * some generic methods for handling tasks that are common to pretty much all
+ * sandwich plugins. Thereby reducing the amount of boilerplate code required to
+ * implement a sandwich plugin.
+ *
+ * In this case both the description and calories properties can be read from
+ * the @Sandwich annotation. In most cases it is probably fine to just use that
+ * value without any additional processing. However, if an individual plugin
+ * needed to provide special handling around either of these things it could
+ * just override the method in that class definition for that plugin.
+ *
+ * We intentionally declare our base class as abstract, and don't implement the
+ * order() method required by \Drupal\plugin_type_example\SandwichInterface.
+ * This way even if they are using our base class, developers will always be
+ * required to define an order() method for their custom sandwich type.
+ *
+ * @see \Drupal\plugin_type_example\Annotation\Sandwich
+ * @see \Drupal\plugin_type_example\SandwichInterface
+ */
+abstract class SandwichBase extends PluginBase implements SandwichInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function description() {
+    // Retrieve the @description property from the annotation and return it.
+    return $this->pluginDefinition['description'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function calories() {
+    // Retrieve the @calories property from the annotation and return it.
+    return (float) $this->pluginDefinition['calories'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  abstract public function order(array $extras);
+
+}
diff --git a/plugin_type_example/src/SandwichInterface.php b/plugin_type_example/src/SandwichInterface.php
index aa5576f..e8a5fe3 100644
--- a/plugin_type_example/src/SandwichInterface.php
+++ b/plugin_type_example/src/SandwichInterface.php
@@ -4,6 +4,20 @@ namespace Drupal\plugin_type_example;
 
 /**
  * An interface for all Sandwich type plugins.
+ *
+ * When defining a new plugin type you need to define an interface that all
+ * plugins of the new type will implement. This ensures that consumers of the
+ * plugin type have a consistent way of accessing the plugin's functionality. It
+ * should include access to any public properties, and methods for accomplishing
+ * whatever business logic anyone accessing the plugin might want to use.
+ *
+ * For example, an image manipulation plugin might have a "process" method that
+ * takes a known input, probably an image file, and returns the processed
+ * version of the file.
+ *
+ * In our case we'll define methods for accessing the human readable description
+ * of a sandwich and the number of calories per serving. As well as a method for
+ * ordering a sandwich.
  */
 interface SandwichInterface {
 
@@ -15,4 +29,26 @@ interface SandwichInterface {
    */
   public function description();
 
+  /**
+   * Provide the number of calories per serving for the sandwich.
+   *
+   * @return float
+   *   The number of calories per serving.
+   */
+  public function calories();
+
+  /**
+   * Place an order for a sandwich.
+   *
+   * This is just an example method on our plugin that we can call to get
+   * something back.
+   *
+   * @param array $extras
+   *   An array of extra ingredients to include with this sandwich.
+   *
+   * @return string
+   *   Description of the sandwich that was just ordered.
+   */
+  public function order(array $extras);
+
 }
diff --git a/plugin_type_example/src/SandwichPluginManager.php b/plugin_type_example/src/SandwichPluginManager.php
index 4a457c2..c6485c3 100644
--- a/plugin_type_example/src/SandwichPluginManager.php
+++ b/plugin_type_example/src/SandwichPluginManager.php
@@ -5,15 +5,22 @@ namespace Drupal\plugin_type_example;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Plugin\DefaultPluginManager;
+use Drupal\plugin_type_example\Annotation\Sandwich;
 
 /**
- * Manages sandwich plugins.
+ * A plugin manager for sandwich plugins.
  *
  * The SandwichPluginManager class extends the DefaultPluginManager to provide
- * a way to manage sandwich plugins.
+ * a way to manage sandwich plugins. A plugin manager defines a new plugin type
+ * and how instances of any plugin of that type will be discovered, instantiated
+ * and more.
  *
- * As well as this class definition, we need to declare our plugin manager class
- * as a service, in the plugin_type_example.services.yml file.
+ * Using the DefaultPluginManager as a starting point sets up our sandwich
+ * plugin type to use annotated discovery.
+ *
+ * The plugin manager is also declared as a service in
+ * plugin_type_example.services.yml so that it can be easily accessed and used
+ * anytime we need to work with sandwich plugins.
  */
 class SandwichPluginManager extends DefaultPluginManager {
 
@@ -30,17 +37,20 @@ class SandwichPluginManager extends DefaultPluginManager {
    */
   public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
     // We replace the $subdir parameter with our own value.
-    // This tells the plugin system to look for plugins in the 'Plugin/Sandwich'
-    // subfolder inside modules' 'src' folder.
+    // This tells the plugin manager to look for Sandwich plugins in the
+    // 'src/Plugin/Sandwich' subdirectory of any enabled modules. This also
+    // serves to define the PSR-4 subnamespace in which sandwich plugins will
+    // live. Modules can put a plugin class in their own namespace such as
+    // Drupal\{module_name}\Plugin\Sandwich\MySandwichPlugin.
     $subdir = 'Plugin/Sandwich';
 
-    // The name of the interface that plugins should adhere to.  Drupal will
-    // enforce this as a requirement.  If a plugin does not implement this
-    // interface, than Drupal will throw an error.
-    $plugin_interface = 'Drupal\plugin_type_example\SandwichInterface';
+    // The name of the interface that plugins should adhere to. Drupal will
+    // enforce this as a requirement. If a plugin does not implement this
+    // interface, Drupal will throw an error.
+    $plugin_interface = SandwichInterface::class;
 
     // The name of the annotation class that contains the plugin definition.
-    $plugin_definition_annotation_name = 'Drupal\Component\Annotation\Plugin';
+    $plugin_definition_annotation_name = Sandwich::class;
 
     parent::__construct($subdir, $namespaces, $module_handler, $plugin_interface, $plugin_definition_annotation_name);
 
@@ -50,15 +60,17 @@ class SandwichPluginManager extends DefaultPluginManager {
     // see plugin_type_example_sandwich_info_alter().
     $this->alterInfo('sandwich_info');
 
-    // This sets the caching method for our plugin definitions.  Plugin
-    // definitions are cached using the provided cache backend.  For our
-    // Sandwich plugin type, we've specified the @cache.default service be used
-    // in the plugin_type_example.services.yml file.  The second argument is a
-    // cache key prefix.  Out of the box Drupal with the default cache backend
-    // setup will store our plugin definition in the cache_default table using
-    // the sandwich_info key.  All that is implementation details however,
-    // all we care about it that caching for our plugin definition is taken
-    // care of by this call.
+    // This sets the caching method for our plugin definitions. Plugin
+    // definitions are discovered by examining the $subdir defined above, for
+    // any classes with an $plugin_definition_annotation_name. The annotations
+    // are read, and then the resulting data is cached using the provided cache
+    // backend. For our Sandwich plugin type, we've specified the @cache.default
+    // service be used in the plugin_type_example.services.yml file. The second
+    // argument is a cache key prefix. Out of the box Drupal with the default
+    // cache backend setup will store our plugin definition in the cache_default
+    // table using the sandwich_info key. All that is implementation details
+    // however, all we care about it that caching for our plugin definition is
+    // taken care of by this call.
     $this->setCacheBackend($cache_backend, 'sandwich_info');
   }
 
diff --git a/plugin_type_example/src/Tests/PluginTypeExampleTest.php b/plugin_type_example/src/Tests/PluginTypeExampleTest.php
index a9a4d54..6ac3eb8 100644
--- a/plugin_type_example/src/Tests/PluginTypeExampleTest.php
+++ b/plugin_type_example/src/Tests/PluginTypeExampleTest.php
@@ -3,6 +3,7 @@
 namespace Drupal\plugin_type_example\Tests;
 
 use Drupal\simpletest\WebTestBase;
+use Drupal\plugin_type_example\Plugin\Sandwich\ExampleHamSandwich;
 
 /**
  * Test the functionality of the Plugin Type Example module.
@@ -32,24 +33,36 @@ class PluginTypeExampleTest extends WebTestBase {
    * Test the plugin manager can be loaded, and the plugins are registered.
    */
   public function testPluginExample() {
-    $manager = \Drupal::service('plugin.manager.sandwich');
+    /* @var $manager \Drupal\plugin_type_example\SandwichPluginManager */
+    $manager = $this->container->get('plugin.manager.sandwich');
 
     $sandwich_plugin_definitions = $manager->getDefinitions();
 
-    // Check we have only one sandwich plugin.
+    // Ensure we have two sandwich plugins defined.
     $this->assertEqual(count($sandwich_plugin_definitions), 2, 'There are two sandwich plugins defined.');
 
     // Check some of the properties of the ham sandwich plugin definition.
     $sandwich_plugin_definition = $sandwich_plugin_definitions['ham_sandwich'];
-    $this->assertEqual($sandwich_plugin_definition['calories'], 500, 'The ham sandwich plugin definition\'s calories property is set.');
+    $this->assertEqual($sandwich_plugin_definition['calories'], 426, 'The ham sandwich plugin definition\'s calories property is set.');
 
     // Check the alter hook fired and changed a property.
-    $this->assertEqual($sandwich_plugin_definition['foobar'], 'We have altered this in the alter hook', 'The ham sandwich plugin definition\'s foobar property is set, and was correctly altered by the plugin info alter hook.');
+    $this->assertIdentical($sandwich_plugin_definition['description'], 'Ham, mustard, ROCKET, sun-dried tomatoes.', 'The ham sandwich plugin definition\'s description property is set, and was correctly altered by the plugin info alter hook.');
 
     // Create an instance of the ham sandwich plugin to check it works.
     $plugin = $manager->createInstance('ham_sandwich', array('of' => 'configuration values'));
 
-    $this->assertEqual(get_class($plugin), 'Drupal\plugin_type_example\Plugin\Sandwich\ExampleHamSandwich', 'The ham sandwich plugin is instantiated and of the correct class.');
+    $this->assertEqual(get_class($plugin), ExampleHamSandwich::class, 'The ham sandwich plugin is instantiated and of the correct class.');
+
+    // Create a meatball sandwich so we can check it's special behavior on
+    // Sundays.
+    /* @var $meatball \Drupal\plugin_type_example\SandwichInterface */
+    $meatball = $manager->createInstance('meatball_sandwich');
+    // Set the $day property to 'Sun'.
+    $ref_day = new \ReflectionProperty($meatball, 'day');
+    $ref_day->setAccessible(TRUE);
+    $ref_day->setValue($meatball, 'Sun');
+    // Check the special description on Sunday.
+    $this->assertEqual($meatball->description(), 'Italian style meatballs drenched in irresistible marinara sauce, served on day old bread.');
   }
 
   /**
@@ -63,7 +76,7 @@ class PluginTypeExampleTest extends WebTestBase {
     $this->assertText(t('ham_sandwich'), 'The plugin ID is output.');
 
     // Check we see the plugin description.
-    $this->assertText(t('Ham, mustard, rocket, sun-dried tomatoes.'), 'The plugin description is output.');
+    $this->assertText(t('Ham, mustard, ROCKET, sun-dried tomatoes.'), 'The plugin description is output.');
   }
 
 }
