diff --git a/core/lib/Drupal/Component/Plugin/Definition/PluginDefinition.php b/core/lib/Drupal/Component/Plugin/Definition/PluginDefinition.php
new file mode 100644
index 0000000..8a37721
--- /dev/null
+++ b/core/lib/Drupal/Component/Plugin/Definition/PluginDefinition.php
@@ -0,0 +1,69 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Component\Plugin\PluginDefinition.
+ */
+
+namespace Drupal\Component\Plugin\Definition;
+
+/**
+ * Provides a plugin definition.
+ *
+ * @ingroup Plugin
+ */
+class PluginDefinition implements PluginDefinitionInterface {
+
+  /**
+   * The plugin ID.
+   *
+   * @var string
+   */
+  protected $id;
+
+  /**
+   * The class.
+   *
+   * @var string
+   *   A class that implements
+   *   \Drupal\Component\Plugin\PluginInspectionInterface.
+   */
+  protected $class;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setId($id) {
+    $this->id = $id;
+
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getId() {
+    return $this->id;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setClass($class) {
+    if (!class_exists($class)) {
+      throw new \InvalidArgumentException(sprintf('Class %s does not exist.', $class));
+    }
+
+    $this->class = $class;
+
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getClass() {
+    return $this->class;
+  }
+
+}
diff --git a/core/lib/Drupal/Component/Plugin/Definition/PluginDefinitionInterface.php b/core/lib/Drupal/Component/Plugin/Definition/PluginDefinitionInterface.php
new file mode 100644
index 0000000..fff4f26
--- /dev/null
+++ b/core/lib/Drupal/Component/Plugin/Definition/PluginDefinitionInterface.php
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Component\Plugin\PluginDefinitionInterface.
+ */
+
+namespace Drupal\Component\Plugin\Definition;
+
+/**
+ * Defines a plugin definition.
+ *
+ * @ingroup Plugin
+ */
+interface PluginDefinitionInterface {
+
+  /**
+   * Sets the plugin ID.
+   *
+   * @param string $id
+   *   The plugin ID.
+   *
+   * @return $this
+   */
+  public function setId($id);
+
+  /**
+   * Gets the plugin ID.
+   *
+   * @return string
+   *   The plugin ID.
+   */
+  public function getId();
+
+  /**
+   * Sets the class.
+   *
+   * @param string $class
+   *   A fully qualified class name.
+   *
+   * @return $this
+   *
+   * @throws \InvalidArgumentException
+   */
+  public function setClass($class);
+
+  /**
+   * Gets the class.
+   *
+   * @return string
+   *   A fully qualified class name.
+   */
+  public function getClass();
+
+}
diff --git a/core/lib/Drupal/Component/Plugin/Definition/PluginDeriverDefinitionInterface.php b/core/lib/Drupal/Component/Plugin/Definition/PluginDeriverDefinitionInterface.php
new file mode 100644
index 0000000..bfd013f
--- /dev/null
+++ b/core/lib/Drupal/Component/Plugin/Definition/PluginDeriverDefinitionInterface.php
@@ -0,0 +1,39 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Component\Plugin\PluginDeriverDefinitionInterface.
+ */
+
+namespace Drupal\Component\Plugin\Definition;
+
+/**
+ * Defines a plugin definition that includes a deriver.
+ *
+ * @ingroup Plugin
+ */
+interface PluginDeriverDefinitionInterface {
+
+  /**
+   * Sets the deriver class.
+   *
+   * @param string $class
+   *   The fully qualified name of a class that implements
+   *   \Drupal\Component\Plugin\Derivative\DeriverInterface.
+   *
+   * @return $this
+   *
+   * @throws \InvalidArgumentException
+   */
+  public function setDeriverClass($class);
+
+  /**
+   * Gets the deriver class.
+   *
+   * @return string
+   *   The fully qualified name of a class that implements
+   *   \Drupal\Component\Plugin\Derivative\DeriverInterface.
+   */
+  public function getDeriverClass();
+
+}
diff --git a/core/lib/Drupal/Component/Plugin/Definition/PluginDeriverDefinitionTrait.php b/core/lib/Drupal/Component/Plugin/Definition/PluginDeriverDefinitionTrait.php
new file mode 100644
index 0000000..f74b9fa
--- /dev/null
+++ b/core/lib/Drupal/Component/Plugin/Definition/PluginDeriverDefinitionTrait.php
@@ -0,0 +1,46 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Component\Plugin\PluginDeriverDefinitionTrait.
+ */
+
+namespace Drupal\Component\Plugin\Definition;
+
+/**
+ * Implements \Drupal\Component\Plugin\Definition\PluginDeriverDefinitionInterface.
+ *
+ * @ingroup Plugin
+ */
+trait PluginDeriverDefinitionTrait {
+
+  /**
+   * The deriver class.
+   *
+   * @var string|null
+   *   A class that implements
+   *   \Drupal\Component\Plugin\Derivative\DeriverInterface or null.
+   */
+  protected $deriverClass;
+
+  /**
+   * Implements \Drupal\Component\Plugin\Definition\PluginDeriverDefinitionInterface::setDeriverClass().
+   */
+  public function setDeriverClass($class) {
+    if (!is_subclass_of($class, 'Drupal\Component\Plugin\Derivative\DeriverInterface')) {
+      throw new \InvalidArgumentException('Plugin deriver classes must implement \Drupal\Component\Plugin\Derivative\DeriverInterface.');
+    }
+
+    $this->deriverClass = $class;
+
+    return $this;
+  }
+
+  /**
+   * Implements \Drupal\Component\Plugin\Definition\PluginDeriverDefinitionInterface::getDeriverClass().
+   */
+  public function getDeriverClass() {
+    return $this->deriverClass;
+  }
+
+}
diff --git a/core/lib/Drupal/Component/Plugin/Definition/PluginLabelDefinitionInterface.php b/core/lib/Drupal/Component/Plugin/Definition/PluginLabelDefinitionInterface.php
new file mode 100644
index 0000000..a54e2ab
--- /dev/null
+++ b/core/lib/Drupal/Component/Plugin/Definition/PluginLabelDefinitionInterface.php
@@ -0,0 +1,35 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Component\Plugin\PluginLabelDefinitionInterface .
+ */
+
+namespace Drupal\Component\Plugin\Definition;
+
+/**
+ * Defines a plugin definition that includes a human-readable label.
+ *
+ * @ingroup Plugin
+ */
+interface PluginLabelDefinitionInterface {
+
+  /**
+   * Sets the human-readable plugin label.
+   *
+   * @param string $label
+   *   The label.
+   *
+   * @return $this
+   */
+  public function setLabel($label);
+
+  /**
+   * Gets the human-readable plugin label.
+   *
+   * @return string
+   *   The label.
+   */
+  public function getLabel();
+
+}
diff --git a/core/lib/Drupal/Component/Plugin/Definition/PluginLabelDefinitionTrait.php b/core/lib/Drupal/Component/Plugin/Definition/PluginLabelDefinitionTrait.php
new file mode 100644
index 0000000..1fed30a
--- /dev/null
+++ b/core/lib/Drupal/Component/Plugin/Definition/PluginLabelDefinitionTrait.php
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Component\Plugin\PluginLabelDefinitionTrait.
+ */
+
+namespace Drupal\Component\Plugin\Definition;
+
+/**
+ * Implements \Drupal\Component\Plugin\Definition\PluginLabelDefinitionInterface.
+ *
+ * @ingroup Plugin
+ */
+trait PluginLabelDefinitionTrait {
+
+  /**
+   * The human-readable plugin label.
+   *
+   * @var string
+   */
+  protected $label;
+
+  /**
+   * Implements \Drupal\Component\Plugin\Definition\PluginLabelDefinitionInterface::setLabel().
+   */
+  public function setLabel($label) {
+    $this->label = $label;
+
+    return $this;
+  }
+
+  /**
+   * Implements \Drupal\Component\Plugin\Definition\PluginLabelDefinitionInterface::getLabel().
+   */
+  public function getLabel() {
+    return $this->label;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Entity/EntityType.php b/core/lib/Drupal/Core/Entity/EntityType.php
index e121d75..27e5c15 100644
--- a/core/lib/Drupal/Core/Entity/EntityType.php
+++ b/core/lib/Drupal/Core/Entity/EntityType.php
@@ -7,9 +7,12 @@
 
 namespace Drupal\Core\Entity;
 
+use Drupal\Component\Plugin\Definition\PluginDefinition;
+use Drupal\Component\Plugin\Definition\PluginLabelDefinitionTrait;
 use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Entity\Exception\EntityTypeIdLengthException;
+use Drupal\Core\Plugin\Definition\PluginProviderDefinitionTrait;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 
 /**
@@ -17,8 +20,10 @@
  *
  * @ingroup entity_api
  */
-class EntityType implements EntityTypeInterface {
+class EntityType extends PluginDefinition implements EntityTypeInterface {
 
+  use PluginLabelDefinitionTrait;
+  use PluginProviderDefinitionTrait;
   use StringTranslationTrait;
 
   /**
@@ -50,27 +55,6 @@ class EntityType implements EntityTypeInterface {
   protected $entity_keys = array();
 
   /**
-   * The unique identifier of this entity type.
-   *
-   * @var string
-   */
-  protected $id;
-
-  /**
-   * The name of the provider of this entity type.
-   *
-   * @var string
-   */
-  protected $provider;
-
-  /**
-   * The name of the entity type class.
-   *
-   * @var string
-   */
-  protected $class;
-
-  /**
    * The name of the original entity type class.
    *
    * This is only set if the class name is changed.
@@ -172,13 +156,6 @@ class EntityType implements EntityTypeInterface {
   protected $translatable = FALSE;
 
   /**
-   * The human-readable name of the type.
-   *
-   * @var string
-   */
-  protected $label = '';
-
-  /**
    * A callable that can be used to provide the entity URI.
    *
    * @var callable|null
@@ -350,28 +327,25 @@ public function id() {
   /**
    * {@inheritdoc}
    */
-  public function getProvider() {
-    return $this->provider;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getClass() {
-    return $this->class;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public function getOriginalClass() {
     return $this->originalClass ?: $this->class;
   }
 
   /**
-   * {@inheritdoc}
+   * Sets the class.
+   *
+   * @param string $class
+   *   A class that implements \Drupal\Core\Entity\EntityInterface.
+   *
+   * @return $this
+   *
+   * @throws \InvalidArgumentException
    */
   public function setClass($class) {
+    if (!is_subclass_of($class, 'Drupal\Core\Entity\EntityInterface')) {
+      throw new \InvalidArgumentException('Entity classes must implement \Drupal\Core\Entity\EntityInterface.');
+    }
+
     if (!$this->originalClass && $this->class) {
       // If the original class is currently not set, set it to the current
       // class, assume that is the original class name.
@@ -675,13 +649,6 @@ public function getDataTable() {
   /**
    * {@inheritdoc}
    */
-  public function getLabel() {
-    return (string) $this->label;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public function getLowercaseLabel() {
     return Unicode::strtolower($this->getLabel());
   }
diff --git a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
index 46c2058..fdc9081 100644
--- a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
@@ -7,6 +7,10 @@
 
 namespace Drupal\Core\Entity;
 
+use Drupal\Component\Plugin\Definition\PluginDefinitionInterface;
+use Drupal\Component\Plugin\Definition\PluginLabelDefinitionInterface;
+use Drupal\Core\Plugin\Definition\PluginProviderDefinitionInterface;
+
 /**
  * Provides an interface for an entity type and its metadata.
  *
@@ -15,7 +19,7 @@
  * implemented to alter existing data and fill-in defaults. Module-specific
  * properties should be documented in the hook implementations defining them.
  */
-interface EntityTypeInterface {
+interface EntityTypeInterface extends PluginDefinitionInterface, PluginLabelDefinitionInterface, PluginProviderDefinitionInterface {
 
   /**
    * The maximum length of ID, in characters.
@@ -59,22 +63,6 @@ public function set($property, $value);
   public function id();
 
   /**
-   * Gets the name of the provider of this entity type.
-   *
-   * @return string
-   *   The name of the provider of this entity type.
-   */
-  public function getProvider();
-
-  /**
-   * Gets the name of the entity type class.
-   *
-   * @return string
-   *   The name of the entity type class.
-   */
-  public function getClass();
-
-  /**
    * Gets the name of the original entity type class.
    *
    * In case the class name was changed with setClass(), this will return
@@ -171,16 +159,6 @@ public function isRenderCacheable();
   public function isPersistentlyCacheable();
 
   /**
-   * Sets the name of the entity type class.
-   *
-   * @param string $class
-   *   The name of the entity type class.
-   *
-   * @return $this
-   */
-  public function setClass($class);
-
-  /**
    * Determines if there is a handler for a given type.
    *
    * @param string $handler_type
diff --git a/core/lib/Drupal/Core/Plugin/Definition/ArrayPluginDefinitionDecorator.php b/core/lib/Drupal/Core/Plugin/Definition/ArrayPluginDefinitionDecorator.php
new file mode 100644
index 0000000..d259100
--- /dev/null
+++ b/core/lib/Drupal/Core/Plugin/Definition/ArrayPluginDefinitionDecorator.php
@@ -0,0 +1,129 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Plugin\ArrayPluginDefinitionDecorator.
+ */
+
+namespace Drupal\Core\Plugin\Definition;
+
+use Drupal\Component\Plugin\Definition\PluginDefinitionInterface;
+use Drupal\Component\Plugin\Definition\PluginLabelDefinitionInterface;
+use Drupal\Component\Plugin\Definition\PluginDeriverDefinitionInterface;
+
+/**
+ * Decorates an array plugin definition.
+ *
+ * This class wraps array definitions in an objects for use in APIs that expect
+ * object definitions only. The arrays are decorated by reference.
+ *
+ * @ingroup Plugin
+ */
+class ArrayPluginDefinitionDecorator implements PluginDefinitionInterface, PluginLabelDefinitionInterface, PluginDeriverDefinitionInterface, PluginProviderDefinitionInterface {
+
+  /**
+   * The decorated array definition.
+   *
+   * @var array
+   */
+  protected $definition = [];
+
+  /**
+   * Constructs a new instance.
+   *
+   * @param array $definition
+   *   The decorated array definition.
+   */
+  public function __construct(array &$definition) {
+    $this->definition = &$definition;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setId($id) {
+    $this->definition['id'] = $id;
+
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getId() {
+    return $this->definition['id'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setClass($class) {
+    if (!class_exists($class)) {
+      throw new \InvalidArgumentException(sprintf('Class %s does not exist.', $class));
+    }
+
+    $this->definition['class'] = $class;
+
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getClass() {
+    return isset($this->definition['class']) ? $this->definition['class'] : '';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setProvider($provider) {
+    $this->definition['provider'] = $provider;
+
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getProvider() {
+    return isset($this->definition['provider']) ? $this->definition['provider'] : '';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setLabel($label) {
+    $this->definition['label'] = $label;
+
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getLabel() {
+    return isset($this->definition['label']) ? $this->definition['label'] : '';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setDeriverClass($class) {
+    if (!is_subclass_of($class, 'Drupal\Component\Plugin\Derivative\DeriverInterface')) {
+      throw new \InvalidArgumentException('Plugin deriver classes must implement \Drupal\Component\Plugin\Derivative\DeriverInterface.');
+    }
+
+    $this->definition['deriver'] = $class;
+
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDeriverClass() {
+    return isset($this->definition['deriver']) ? $this->definition['deriver'] : '';
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Plugin/Definition/PluginProviderDefinitionInterface.php b/core/lib/Drupal/Core/Plugin/Definition/PluginProviderDefinitionInterface.php
new file mode 100644
index 0000000..46355c5
--- /dev/null
+++ b/core/lib/Drupal/Core/Plugin/Definition/PluginProviderDefinitionInterface.php
@@ -0,0 +1,39 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Plugin\PluginProviderDefinitionInterface.
+ */
+
+namespace Drupal\Core\Plugin\Definition;
+
+/**
+ * Defines a plugin definition that includes a provider.
+ *
+ * @ingroup Plugin
+ */
+interface PluginProviderDefinitionInterface {
+
+  /**
+   * Sets the plugin provider.
+   *
+   * The provider is the name of the module that provides the plugin.
+   *
+   * @param string $provider
+   *   The provider.
+   *
+   * @return $this
+   */
+  public function setProvider($provider);
+
+  /**
+   * Gets the plugin provider.
+   *
+   * The provider is the name of the module that provides the plugin.
+   *
+   * @return string
+   *   The provider.
+   */
+  public function getProvider();
+
+}
diff --git a/core/lib/Drupal/Core/Plugin/Definition/PluginProviderDefinitionTrait.php b/core/lib/Drupal/Core/Plugin/Definition/PluginProviderDefinitionTrait.php
new file mode 100644
index 0000000..6fa1239
--- /dev/null
+++ b/core/lib/Drupal/Core/Plugin/Definition/PluginProviderDefinitionTrait.php
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Plugin\PluginProviderDefinitionTrait.
+ */
+
+namespace Drupal\Core\Plugin\Definition;
+
+/**
+ * Implements \Drupal\Core\Plugin\Definition\PluginProviderDefinitionInterface.
+ *
+ * @ingroup Plugin
+ */
+trait PluginProviderDefinitionTrait {
+
+  /**
+   * The provider.
+   *
+   * @var string
+   */
+  protected $provider;
+
+  /**
+   * Implements \Drupal\Core\Plugin\Definition\PluginProviderDefinitionInterface::setProvider().
+   */
+  public function setProvider($provider) {
+    $this->provider = $provider;
+
+    return $this;
+  }
+
+  /**
+   * Implements \Drupal\Core\Plugin\Definition\PluginProviderDefinitionInterface::getProvider().
+   */
+  public function getProvider() {
+    return $this->provider;
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Component/Plugin/Definition/PluginDefinitionTest.php b/core/tests/Drupal/Tests/Component/Plugin/Definition/PluginDefinitionTest.php
new file mode 100644
index 0000000..126a047
--- /dev/null
+++ b/core/tests/Drupal/Tests/Component/Plugin/Definition/PluginDefinitionTest.php
@@ -0,0 +1,58 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Component\Plugin\Definition\PluginDefinitionTest.
+ */
+
+namespace Drupal\Tests\Component\Plugin\Definition;
+
+use Drupal\Component\Plugin\Definition\PluginDefinition;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\Component\Plugin\Definition\PluginDefinition
+ *
+ * @group Plugin
+ */
+class PluginDefinitionTest extends UnitTestCase {
+
+  /**
+   * The class under test.
+   *
+   * @var \Drupal\Component\Plugin\Definition\PluginDefinition
+   */
+  protected $sut;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+
+    $this->sut = new PluginDefinition();
+  }
+
+  /**
+   * @covers ::setId
+   * @covers ::getId
+   */
+  public function testGetId() {
+    $id = $this->randomMachineName();
+
+    $this->assertSame($this->sut, $this->sut->setId($id));
+    $this->assertSame($id, $this->sut->getId());
+  }
+
+  /**
+   * @covers ::setClass
+   * @covers ::getClass
+   */
+  public function testGetClass() {
+    $class = get_class($this->getMock('\Drupal\Component\Plugin\PluginInspectionInterface'));
+
+    $this->assertSame($this->sut, $this->sut->setClass($class));
+    $this->assertSame($class, $this->sut->getClass());
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Component/Plugin/Definition/PluginDeriverDefinitionTraitTest.php b/core/tests/Drupal/Tests/Component/Plugin/Definition/PluginDeriverDefinitionTraitTest.php
new file mode 100644
index 0000000..a98d00b
--- /dev/null
+++ b/core/tests/Drupal/Tests/Component/Plugin/Definition/PluginDeriverDefinitionTraitTest.php
@@ -0,0 +1,59 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Component\Plugin\Definition\PluginDeriverDefinitionTraitTest.
+ */
+
+namespace Drupal\Tests\Component\Plugin;
+
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\Component\Plugin\Definition\PluginDeriverDefinitionTrait
+ *
+ * @group Plugin
+ */
+class PluginDeriverDefinitionTraitTest extends UnitTestCase {
+
+  /**
+   * The class under test.
+   *
+   * @var \Drupal\Component\Plugin\Definition\PluginDeriverDefinitionTrait
+   */
+  protected $sut;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+
+    $this->sut = $this->getMockForTrait('\Drupal\Component\Plugin\Definition\PluginDeriverDefinitionTrait');
+  }
+
+  /**
+   * @covers ::setDeriverClass
+   * @covers ::getDeriverClass
+   */
+  public function testGetDeriverClass() {
+    $class = get_class($this->getMock('\Drupal\Component\Plugin\Derivative\DeriverInterface'));
+
+    $this->assertSame($this->sut, $this->sut->setDeriverClass($class));
+    $this->assertSame($class, $this->sut->getDeriverClass());
+  }
+
+  /**
+   * @covers ::setDeriverClass
+   *
+   * @depends testGetDeriverClass
+   *
+   * @expectedException \InvalidArgumentException
+   */
+  public function testGetDeriverClassWithInvalidDeriverClass() {
+    $class = '\stdClass';
+
+    $this->sut->setDeriverClass($class);
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Component/Plugin/Definition/PluginLabelDefinitionTraitTest.php b/core/tests/Drupal/Tests/Component/Plugin/Definition/PluginLabelDefinitionTraitTest.php
new file mode 100644
index 0000000..b22e986
--- /dev/null
+++ b/core/tests/Drupal/Tests/Component/Plugin/Definition/PluginLabelDefinitionTraitTest.php
@@ -0,0 +1,46 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Component\Plugin\PluginLabelDefinitionTraitTest.
+ */
+
+namespace Drupal\Tests\Component\Plugin;
+
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\Component\Plugin\Definition\PluginLabelDefinitionTrait
+ *
+ * @group Plugin
+ */
+class PluginLabelDefinitionTraitTest extends UnitTestCase {
+
+  /**
+   * The class under test.
+   *
+   * @var \Drupal\Component\Plugin\Definition\PluginLabelDefinitionTrait
+   */
+  protected $sut;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+
+    $this->sut = $this->getMockForTrait('\Drupal\Component\Plugin\Definition\PluginLabelDefinitionTrait');
+  }
+
+  /**
+   * @covers ::setLabel
+   * @covers ::getLabel
+   */
+  public function testGetLabel() {
+    $label = $this->randomMachineName();
+
+    $this->assertSame($this->sut, $this->sut->setLabel($label));
+    $this->assertSame($label, $this->sut->getLabel());
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/Entity/EntityTypeTest.php b/core/tests/Drupal/Tests/Core/Entity/EntityTypeTest.php
index c350b48..83c4ebc 100644
--- a/core/tests/Drupal/Tests/Core/Entity/EntityTypeTest.php
+++ b/core/tests/Drupal/Tests/Core/Entity/EntityTypeTest.php
@@ -212,23 +212,30 @@ public function testgetOriginalClassUnchanged() {
   }
 
   /**
+   * @covers ::getClass
    * @covers ::setClass
    * @covers ::getOriginalClass
    */
   public function testgetOriginalClassChanged() {
-    $class = $this->randomMachineName();
-    $entity_type = $this->setUpEntityType(array('class' => $class));
-    $entity_type->setClass($this->randomMachineName());
-    $this->assertEquals($class, $entity_type->getOriginalClass());
+    $original_class = get_class($this->getMock('\Drupal\Core\Entity\EntityInterface'));
+    $new_class = get_class($this->getMock('\Drupal\Core\Entity\EntityInterface'));
+    $entity_type = $this->setUpEntityType(array('class' => $original_class));
+    $this->assertEquals($original_class, $entity_type->getClass());
+    $entity_type->setClass($new_class);
+    $this->assertEquals($original_class, $entity_type->getOriginalClass());
+    $this->assertEquals($new_class, $entity_type->getClass());
   }
 
   /**
    * @covers ::id
+   * @covers ::setId
+   * @covers ::getId
    */
   public function testId() {
     $id = $this->randomMachineName(32);
     $entity_type = $this->setUpEntityType(array('id' => $id));
     $this->assertEquals($id, $entity_type->id());
+    $this->assertEquals($id, $entity_type->getId());
   }
 
   /**
diff --git a/core/tests/Drupal/Tests/Core/Plugin/Definition/ArrayPluginDefinitionDecoratorTest.php b/core/tests/Drupal/Tests/Core/Plugin/Definition/ArrayPluginDefinitionDecoratorTest.php
new file mode 100644
index 0000000..18fb4c5
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Plugin/Definition/ArrayPluginDefinitionDecoratorTest.php
@@ -0,0 +1,115 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\Plugin\Definition\ArrayPluginDefinitionDecoratorTest.
+ */
+
+namespace Drupal\Tests\Core\Plugin\Definition;
+
+use Drupal\Core\Plugin\Definition\ArrayPluginDefinitionDecorator;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\Core\Plugin\Definition\ArrayPluginDefinitionDecorator
+ *
+ * @group Plugin
+ */
+class ArrayPluginDefinitionDecoratorTest extends UnitTestCase {
+
+  /**
+   * The decorated array plugin definition.
+   *
+   * @var mixed[]
+   */
+  protected $arrayDefinition = [];
+
+  /**
+   * The class under test.
+   *
+   * @var \Drupal\Core\Plugin\Definition\ArrayPluginDefinitionDecorator
+   */
+  protected $sut;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+
+    $this->sut = new ArrayPluginDefinitionDecorator($this->arrayDefinition);
+  }
+
+  /**
+   * @covers ::setId
+   * @covers ::getId
+   */
+  public function testGetId() {
+    $id = $this->randomMachineName();
+
+    $this->assertSame($this->sut, $this->sut->setId($id));
+    $this->assertSame($id, $this->sut->getId());
+    $this->assertSame($id, $this->arrayDefinition['id']);
+  }
+
+  /**
+   * @covers ::setClass
+   * @covers ::getClass
+   */
+  public function testGetClass() {
+    $class = get_class($this->getMock('\Drupal\Component\Plugin\PluginInspectionInterface'));
+
+    $this->assertSame($this->sut, $this->sut->setClass($class));
+    $this->assertSame($class, $this->sut->getClass());
+  }
+
+  /**
+   * @covers ::setLabel
+   * @covers ::getLabel
+   */
+  public function testGetLabel() {
+    $label = $this->randomMachineName();
+
+    $this->assertSame($this->sut, $this->sut->setLabel($label));
+    $this->assertSame($label, $this->sut->getLabel());
+    $this->assertSame($label, $this->arrayDefinition['label']);
+  }
+
+  /**
+   * @covers ::setDeriverClass
+   * @covers ::getDeriverClass
+   */
+  public function testGetDeriverClass() {
+    $class = get_class($this->getMock('\Drupal\Component\Plugin\Derivative\DeriverInterface'));
+
+    $this->assertSame($this->sut, $this->sut->setDeriverClass($class));
+    $this->assertSame($class, $this->sut->getDeriverClass());
+    $this->assertSame($class, $this->arrayDefinition['deriver']);
+  }
+
+  /**
+   * @covers ::setDeriverClass
+   *
+   * @depends testGetDeriverClass
+   *
+   * @expectedException \InvalidArgumentException
+   */
+  public function testGetDeriverClassWithInvalidDeriverClass() {
+    $class = '\stdClass';
+
+    $this->sut->setDeriverClass($class);
+  }
+
+  /**
+   * @covers ::setProvider
+   * @covers ::getProvider
+   */
+  public function testGetProviderClass() {
+    $provider = $this->randomMachineName();
+
+    $this->assertSame($this->sut, $this->sut->setProvider($provider));
+    $this->assertSame($provider, $this->sut->getProvider());
+    $this->assertSame($provider, $this->arrayDefinition['provider']);
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/Plugin/Definition/PluginProviderDefinitionTraitTest.php b/core/tests/Drupal/Tests/Core/Plugin/Definition/PluginProviderDefinitionTraitTest.php
new file mode 100644
index 0000000..600567b
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Plugin/Definition/PluginProviderDefinitionTraitTest.php
@@ -0,0 +1,46 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\Plugin\Definition\PluginProviderDefinitionTraitTest.
+ */
+
+namespace Drupal\Tests\Core\Plugin;
+
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\Core\Plugin\Definition\PluginProviderDefinitionTrait
+ *
+ * @group Plugin
+ */
+class PluginProviderDefinitionTraitTest extends UnitTestCase {
+
+  /**
+   * The class under test.
+   *
+   * @var \Drupal\Core\Plugin\Definition\PluginProviderDefinitionTrait
+   */
+  protected $sut;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+
+    $this->sut = $this->getMockForTrait('\Drupal\Core\Plugin\Definition\PluginProviderDefinitionTrait');
+  }
+
+  /**
+   * @covers ::setProvider
+   * @covers ::getProvider
+   */
+  public function testGetProviderClass() {
+    $provider = $this->randomMachineName();
+
+    $this->assertSame($this->sut, $this->sut->setProvider($provider));
+    $this->assertSame($provider, $this->sut->getProvider());
+  }
+
+}
