diff --git a/core/core.services.yml b/core/core.services.yml
index 2f7da56..39b0a04 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -569,6 +569,9 @@ services:
   entity.autocomplete_matcher:
     class: Drupal\Core\Entity\EntityAutocompleteMatcher
     arguments: ['@plugin.manager.entity_reference_selection']
+  plugin_form.manager:
+    class: Drupal\Core\Plugin\PluginFormManager
+    arguments: ['@class_resolver']
   plugin.manager.entity_reference_selection:
     class: Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManager
     parent: default_plugin_manager
diff --git a/core/lib/Drupal/Core/Form/OperationAwareFormInterface.php b/core/lib/Drupal/Core/Form/OperationAwareFormInterface.php
new file mode 100644
index 0000000..8172bd7
--- /dev/null
+++ b/core/lib/Drupal/Core/Form/OperationAwareFormInterface.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace Drupal\Core\Form;
+
+/**
+ * Interface for forms that are aware of what operation they are performing.
+ */
+interface OperationAwareFormInterface {
+
+  /**
+   * Sets the operation for this form.
+   *
+   * @param string $operation
+   *   The name of the current operation.
+   *
+   * @return $this
+   */
+  public function setOperation($operation);
+
+}
diff --git a/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php b/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
index 06365fa..7e4c0bc 100644
--- a/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
+++ b/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
@@ -242,6 +242,12 @@ public function processDefinition(&$definition, $plugin_id) {
     if (!empty($this->defaults) && is_array($this->defaults)) {
       $definition = NestedArray::mergeDeep($this->defaults, $definition);
     }
+
+    // If no default form is defined and this plugin implements
+    // \Drupal\Core\Plugin\PluginFormInterface, use that for the default form.
+    if (!isset($definition['form']['default']) && is_subclass_of($definition['class'], PluginFormInterface::class)) {
+      $definition['form']['default'] = $definition['class'];
+    }
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Plugin/PluginFormManager.php b/core/lib/Drupal/Core/Plugin/PluginFormManager.php
new file mode 100644
index 0000000..491f6cb
--- /dev/null
+++ b/core/lib/Drupal/Core/Plugin/PluginFormManager.php
@@ -0,0 +1,67 @@
+<?php
+
+namespace Drupal\Core\Plugin;
+
+use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
+use Drupal\Component\Plugin\PluginInspectionInterface;
+use Drupal\Core\DependencyInjection\ClassResolverInterface;
+use Drupal\Core\Form\OperationAwareFormInterface;
+
+/**
+ * Provides form discovery capabilities for plugins.
+ */
+class PluginFormManager implements PluginFormManagerInterface {
+
+  /**
+   * The class resolver.
+   *
+   * @var \Drupal\Core\DependencyInjection\ClassResolverInterface
+   */
+  protected $classResolver;
+
+  /**
+   * PluginFormManager constructor.
+   *
+   * @param \Drupal\Core\DependencyInjection\ClassResolverInterface $class_resolver
+   */
+  public function __construct(ClassResolverInterface $class_resolver) {
+    $this->classResolver = $class_resolver;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormObject(PluginInspectionInterface $plugin, $operation) {
+    $definition = $plugin->getPluginDefinition();
+
+    if (!isset($definition['form'][$operation])) {
+      // Use the default form class if no form is specified for this operation.
+      if (isset($definition['form']['default'])) {
+        $operation = 'default';
+      }
+      else {
+        throw new InvalidPluginDefinitionException($plugin->getPluginId(), sprintf('The "%s" plugin did not specify a "%s" form class', $plugin->getPluginId(), $operation));
+      }
+    }
+
+    // If the form specified is the plugin itself, use it directly.
+    if (get_class($plugin) === $definition['form'][$operation]) {
+      $form_object = $plugin;
+    }
+    else {
+      $form_object = $this->classResolver->getInstanceFromDefinition($definition['form'][$operation]);
+    }
+
+    // Ensure the resulting object is a plugin form.
+    if (!$form_object instanceof PluginFormInterface) {
+      throw new InvalidPluginDefinitionException($plugin->getPluginId(), sprintf('The "%s" plugin did not specify a valid "%s" form class, must implement \Drupal\Core\Plugin\PluginFormInterface', $plugin->getPluginId(), $operation));
+    }
+
+    if ($form_object instanceof OperationAwareFormInterface) {
+      $form_object->setOperation($operation);
+    }
+
+    return $form_object;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Plugin/PluginFormManagerInterface.php b/core/lib/Drupal/Core/Plugin/PluginFormManagerInterface.php
new file mode 100644
index 0000000..d22ca04
--- /dev/null
+++ b/core/lib/Drupal/Core/Plugin/PluginFormManagerInterface.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace Drupal\Core\Plugin;
+
+use Drupal\Component\Plugin\PluginInspectionInterface;
+
+/**
+ * Provides form discovery capabilities for block plugins.
+ */
+interface PluginFormManagerInterface {
+
+  /**
+   * Creates a new form instance.
+   *
+   * @param \Drupal\Component\Plugin\PluginInspectionInterface $plugin
+   *   The plugin the form is for.
+   * @param string $operation
+   *   The name of the operation to use, e.g., 'default'.
+   *
+   * @return \Drupal\Core\Plugin\PluginFormInterface
+   *   A plugin form instance.
+   *
+   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
+   */
+  public function getFormObject(PluginInspectionInterface $plugin, $operation);
+
+}
diff --git a/core/modules/block/src/BlockForm.php b/core/modules/block/src/BlockForm.php
index eeec4d3..47c4bb6 100644
--- a/core/modules/block/src/BlockForm.php
+++ b/core/modules/block/src/BlockForm.php
@@ -3,6 +3,8 @@
 namespace Drupal\block;
 
 use Drupal\Component\Utility\Html;
+use Drupal\Core\Plugin\PluginFormManagerInterface;
+use Drupal\Core\Block\BlockPluginInterface;
 use Drupal\Core\Entity\EntityForm;
 use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Executable\ExecutableManagerInterface;
@@ -69,6 +71,13 @@ class BlockForm extends EntityForm {
   protected $contextRepository;
 
   /**
+   * The plugin form manager.
+   *
+   * @var \Drupal\Core\Plugin\PluginFormManagerInterface
+   */
+  protected $pluginFormManager;
+
+  /**
    * Constructs a BlockForm object.
    *
    * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
@@ -81,13 +90,16 @@ class BlockForm extends EntityForm {
    *   The language manager.
    * @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler
    *   The theme handler.
+   * @param \Drupal\Core\Plugin\PluginFormManagerInterface $plugin_form_manager
+   *   The plugin form manager.
    */
-  public function __construct(EntityManagerInterface $entity_manager, ExecutableManagerInterface $manager, ContextRepositoryInterface $context_repository, LanguageManagerInterface $language, ThemeHandlerInterface $theme_handler) {
+  public function __construct(EntityManagerInterface $entity_manager, ExecutableManagerInterface $manager, ContextRepositoryInterface $context_repository, LanguageManagerInterface $language, ThemeHandlerInterface $theme_handler, \Drupal\Core\Plugin\PluginFormManagerInterface $plugin_form_manager) {
     $this->storage = $entity_manager->getStorage('block');
     $this->manager = $manager;
     $this->contextRepository = $context_repository;
     $this->language = $language;
     $this->themeHandler = $theme_handler;
+    $this->pluginFormManager = $plugin_form_manager;
   }
 
   /**
@@ -99,7 +111,8 @@ public static function create(ContainerInterface $container) {
       $container->get('plugin.manager.condition'),
       $container->get('context.repository'),
       $container->get('language_manager'),
-      $container->get('theme_handler')
+      $container->get('theme_handler'),
+      $container->get('plugin_form.manager')
     );
   }
 
@@ -120,7 +133,7 @@ public function form(array $form, FormStateInterface $form_state) {
     $form_state->setTemporaryValue('gathered_contexts', $this->contextRepository->getAvailableContexts());
 
     $form['#tree'] = TRUE;
-    $form['settings'] = $entity->getPlugin()->buildConfigurationForm(array(), $form_state);
+    $form['settings'] = $this->getPluginForm($this->entity->getPlugin())->buildConfigurationForm(array(), $form_state);
     $form['visibility'] = $this->buildVisibilityInterface([], $form_state);
 
     // If creating a new block, calculate a safe default machine name.
@@ -282,7 +295,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
     // settings form element, so just pass that to the block for validation.
     $settings = (new FormState())->setValues($form_state->getValue('settings'));
     // Call the plugin validate handler.
-    $this->entity->getPlugin()->validateConfigurationForm($form, $settings);
+    $this->getPluginForm($this->entity->getPlugin())->validateConfigurationForm($form, $settings);
     // Update the original form values.
     $form_state->setValue('settings', $settings->getValues());
     $this->validateVisibility($form, $form_state);
@@ -322,15 +335,14 @@ protected function validateVisibility(array $form, FormStateInterface $form_stat
   public function submitForm(array &$form, FormStateInterface $form_state) {
     parent::submitForm($form, $form_state);
 
-    $entity = $this->entity;
     // The Block Entity form puts all block plugin form elements in the
     // settings form element, so just pass that to the block for submission.
     // @todo Find a way to avoid this manipulation.
     $settings = (new FormState())->setValues($form_state->getValue('settings'));
 
     // Call the plugin submit handler.
-    $entity->getPlugin()->submitConfigurationForm($form, $settings);
-    $block = $entity->getPlugin();
+    $block = $this->entity->getPlugin();
+    $this->getPluginForm($block)->submitConfigurationForm($form, $settings);
     // If this block is context-aware, set the context mapping.
     if ($block instanceof ContextAwarePluginInterface && $block->getContextDefinitions()) {
       $context_mapping = $settings->getValue('context_mapping', []);
@@ -339,7 +351,30 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     // Update the original form values.
     $form_state->setValue('settings', $settings->getValues());
 
-    // Submit visibility condition settings.
+    $this->submitVisibility($form, $form_state);
+
+    // Save the settings of the plugin.
+    $this->entity->save();
+
+    drupal_set_message($this->t('The block configuration has been saved.'));
+    $form_state->setRedirect(
+      'block.admin_display_theme',
+      array(
+        'theme' => $form_state->getValue('theme'),
+      ),
+      array('query' => array('block-placement' => Html::getClass($this->entity->id())))
+    );
+  }
+
+  /**
+   * Helper function to independently submit the visibility UI.
+   *
+   * @param array $form
+   *   A nested array form elements comprising the form.
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   The current state of the form.
+   */
+  protected function submitVisibility(array $form, FormStateInterface $form_state) {
     foreach ($form_state->getValue('visibility') as $condition_id => $values) {
       // Allow the condition to submit the form.
       $condition = $form_state->get(['conditions', $condition_id]);
@@ -354,20 +389,8 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       $condition_configuration = $condition->getConfiguration();
       $form_state->setValue(['visibility', $condition_id], $condition_configuration);
       // Update the visibility conditions on the block.
-      $entity->getVisibilityConditions()->addInstanceId($condition_id, $condition_configuration);
+      $this->entity->getVisibilityConditions()->addInstanceId($condition_id, $condition_configuration);
     }
-
-    // Save the settings of the plugin.
-    $entity->save();
-
-    drupal_set_message($this->t('The block configuration has been saved.'));
-    $form_state->setRedirect(
-      'block.admin_display_theme',
-      array(
-        'theme' => $form_state->getValue('theme'),
-      ),
-      array('query' => array('block-placement' => Html::getClass($this->entity->id())))
-    );
   }
 
   /**
@@ -402,4 +425,17 @@ public function getUniqueMachineName(BlockInterface $block) {
     return $machine_default;
   }
 
+  /**
+   * Retrieves the plugin form for a given block and operation.
+   *
+   * @param \Drupal\Core\Block\BlockPluginInterface $block
+   *   The block plugin.
+   *
+   * @return \Drupal\Core\Plugin\PluginFormInterface
+   *   The plugin form for the block.
+   */
+  protected function getPluginForm(BlockPluginInterface $block) {
+    return $this->pluginFormManager->getFormObject($block, $this->operation);
+  }
+
 }
diff --git a/core/modules/block/tests/modules/block_test/src/Form/SecondaryBlockForm.php b/core/modules/block/tests/modules/block_test/src/Form/SecondaryBlockForm.php
new file mode 100644
index 0000000..3095963
--- /dev/null
+++ b/core/modules/block/tests/modules/block_test/src/Form/SecondaryBlockForm.php
@@ -0,0 +1,47 @@
+<?php
+
+namespace Drupal\block_test\Form;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Form\OperationAwareFormInterface;
+use Drupal\Core\Plugin\PluginFormInterface;
+
+/**
+ * @todo.
+ */
+class SecondaryBlockForm implements PluginFormInterface, OperationAwareFormInterface {
+
+  /**
+   * @var string
+   */
+  protected $operation;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setOperation($operation) {
+    $this->operation = $operation;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
+    // Intentionally empty.
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
+    // Intentionally empty.
+  }
+
+}
diff --git a/core/modules/block/tests/modules/block_test/src/Plugin/Block/TestMultipleFormsBlock.php b/core/modules/block/tests/modules/block_test/src/Plugin/Block/TestMultipleFormsBlock.php
new file mode 100644
index 0000000..ff5ced3
--- /dev/null
+++ b/core/modules/block/tests/modules/block_test/src/Plugin/Block/TestMultipleFormsBlock.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace Drupal\block_test\Plugin\Block;
+
+use Drupal\Core\Block\BlockBase;
+
+/**
+ * @todo.
+ *
+ * @Block(
+ *   id = "test_multiple_forms_block",
+ *   form = {
+ *     "secondary" = "\Drupal\block_test\Form\SecondaryBlockForm"
+ *   },
+ *   admin_label = @Translation("Multiple forms test block")
+ * )
+ */
+class TestMultipleFormsBlock extends BlockBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function build() {
+    return [];
+  }
+
+}
diff --git a/core/modules/block/tests/src/Unit/BlockFormTest.php b/core/modules/block/tests/src/Unit/BlockFormTest.php
index 09f450b..07b3780 100644
--- a/core/modules/block/tests/src/Unit/BlockFormTest.php
+++ b/core/modules/block/tests/src/Unit/BlockFormTest.php
@@ -3,6 +3,7 @@
 namespace Drupal\Tests\block\Unit;
 
 use Drupal\block\BlockForm;
+use Drupal\Core\Plugin\PluginFormManagerInterface;
 use Drupal\Tests\UnitTestCase;
 
 /**
@@ -55,6 +56,13 @@ class BlockFormTest extends UnitTestCase {
   protected $contextRepository;
 
   /**
+   * The plugin form manager.
+   *
+   * @var \Drupal\Core\Plugin\PluginFormManagerInterface|\Prophecy\Prophecy\ProphecyInterface
+   */
+  protected $pluginFormManager;
+
+  /**
    * {@inheritdoc}
    */
   protected function setUp() {
@@ -71,6 +79,7 @@ protected function setUp() {
       ->method('getStorage')
       ->will($this->returnValue($this->storage));
 
+    $this->pluginFormManager = $this->prophesize(PluginFormManagerInterface::class);
   }
 
   /**
@@ -99,7 +108,7 @@ public function testGetUniqueMachineName() {
       ->method('getQuery')
       ->will($this->returnValue($query));
 
-    $block_form_controller = new BlockForm($this->entityManager, $this->conditionManager, $this->contextRepository, $this->language, $this->themeHandler);
+    $block_form_controller = new BlockForm($this->entityManager, $this->conditionManager, $this->contextRepository, $this->language, $this->themeHandler, $this->pluginFormManager->reveal());
 
     // Ensure that the block with just one other instance gets the next available
     // name suggestion.
diff --git a/core/tests/Drupal/KernelTests/Core/Block/MultipleBlockFormTest.php b/core/tests/Drupal/KernelTests/Core/Block/MultipleBlockFormTest.php
new file mode 100644
index 0000000..06438ea
--- /dev/null
+++ b/core/tests/Drupal/KernelTests/Core/Block/MultipleBlockFormTest.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace Drupal\KernelTests\Core\Block;
+
+use Drupal\block_test\Form\SecondaryBlockForm;
+use Drupal\KernelTests\KernelTestBase;
+
+/**
+ * Tests that blocks can have multiple forms.
+ *
+ * @group block
+ */
+class MultipleBlockFormTest extends KernelTestBase {
+
+  /**
+   * @var array
+   */
+  public static $modules = ['system', 'block', 'block_test'];
+
+  /**
+   * Tests that blocks can have multiple forms.
+   */
+  public function testMultipleForms() {
+    $block = \Drupal::service('plugin.manager.block')->createInstance('test_multiple_forms_block');
+
+    $form_object1 = \Drupal::service('plugin_form.manager')->getFormObject($block, 'default');
+    $form_object2 = \Drupal::service('plugin_form.manager')->getFormObject($block, 'secondary');
+
+    // Assert that the block itself is used for the default form.
+    $this->assertSame($block, $form_object1);
+
+    $expected_secondary = new SecondaryBlockForm();
+    $expected_secondary->setOperation('secondary');
+    $this->assertEquals($expected_secondary, $form_object2);
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/Plugin/PluginFormManagerTest.php b/core/tests/Drupal/Tests/Core/Plugin/PluginFormManagerTest.php
new file mode 100644
index 0000000..7e70b5c
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Plugin/PluginFormManagerTest.php
@@ -0,0 +1,155 @@
+<?php
+
+namespace Drupal\Tests\Core\Plugin;
+
+use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
+use Drupal\Component\Plugin\PluginInspectionInterface;
+use Drupal\Core\DependencyInjection\ClassResolverInterface;
+use Drupal\Core\Plugin\PluginFormInterface;
+use Drupal\Core\Form\OperationAwareFormInterface;
+use Drupal\Core\Plugin\PluginFormManager;
+use Drupal\Tests\UnitTestCase;
+use Prophecy\Argument;
+
+/**
+ * @coversDefaultClass \Drupal\Core\Plugin\PluginFormManager
+ * @group Plugin
+ */
+class PluginFormManagerTest extends UnitTestCase {
+
+  /**
+   * The class resolver.
+   *
+   * @var \Drupal\Core\DependencyInjection\ClassResolverInterface|\Prophecy\Prophecy\ProphecyInterface
+   */
+  protected $classResolver;
+
+  /**
+   * The manager being tested.
+   *
+   * @var \Drupal\Core\Plugin\PluginFormManager
+   */
+  protected $manager;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->classResolver = $this->prophesize(ClassResolverInterface::class);
+    $this->manager = new PluginFormManager($this->classResolver->reveal());
+  }
+
+  /**
+   * @covers ::getFormObject
+   */
+  public function testGetFormObject() {
+    $plugin_form = $this->prophesize(PluginFormInterface::class);
+    $expected = $plugin_form->reveal();
+
+    $this->classResolver->getInstanceFromDefinition(get_class($expected))->willReturn($expected);
+
+    $plugin = $this->prophesize(PluginInspectionInterface::class);
+    $plugin->getPluginDefinition()->willReturn([
+      'form' => [
+        'standard_class' => get_class($expected),
+      ],
+    ]);
+
+    $form_object = $this->manager->getFormObject($plugin->reveal(), 'standard_class');
+    $this->assertSame($expected, $form_object);
+  }
+
+  /**
+   * @covers ::getFormObject
+   */
+  public function testGetFormObjectUsingPlugin() {
+    $this->classResolver->getInstanceFromDefinition(Argument::cetera())->shouldNotBeCalled();
+
+    $plugin = $this->prophesize(PluginInspectionInterface::class)->willImplement(PluginFormInterface::class);
+    $plugin->getPluginDefinition()->willReturn([
+      'form' => [
+        'default' => get_class($plugin->reveal()),
+      ],
+    ]);
+
+    $form_object = $this->manager->getFormObject($plugin->reveal(), 'default');
+    $this->assertSame($plugin->reveal(), $form_object);
+  }
+
+  /**
+   * @covers ::getFormObject
+   */
+  public function testGetFormObjectDefaultFallback() {
+    $this->classResolver->getInstanceFromDefinition(Argument::cetera())->shouldNotBeCalled();
+
+    $plugin = $this->prophesize(PluginInspectionInterface::class)->willImplement(PluginFormInterface::class);
+    $plugin->getPluginDefinition()->willReturn([
+      'form' => [
+        'default' => get_class($plugin->reveal()),
+      ],
+    ]);
+
+    $form_object = $this->manager->getFormObject($plugin->reveal(), 'missing');
+    $this->assertSame($plugin->reveal(), $form_object);
+  }
+
+  /**
+   * @covers ::getFormObject
+   */
+  public function testGetFormObjectOperationAware() {
+    $plugin_form = $this->prophesize(PluginFormInterface::class)->willImplement(OperationAwareFormInterface::class);
+    $plugin_form->setOperation('operation_aware')->shouldBeCalled();
+
+    $expected = $plugin_form->reveal();
+
+    $this->classResolver->getInstanceFromDefinition(get_class($expected))->willReturn($expected);
+
+    $plugin = $this->prophesize(PluginInspectionInterface::class);
+    $plugin->getPluginDefinition()->willReturn([
+      'form' => [
+        'operation_aware' => get_class($expected),
+      ],
+    ]);
+
+    $form_object = $this->manager->getFormObject($plugin->reveal(), 'operation_aware');
+    $this->assertSame($expected, $form_object);
+  }
+
+  /**
+   * @covers ::getFormObject
+   */
+  public function testGetFormObjectDefinitionException() {
+    $this->setExpectedException(InvalidPluginDefinitionException::class, 'The "the_plugin_id" plugin did not specify a "anything" form class');
+
+    $plugin = $this->prophesize(PluginInspectionInterface::class);
+    $plugin->getPluginId()->willReturn('the_plugin_id');
+    $plugin->getPluginDefinition()->willReturn([]);
+
+    $form_object = $this->manager->getFormObject($plugin->reveal(), 'anything');
+    $this->assertSame(NULL, $form_object);
+  }
+
+  /**
+   * @covers ::getFormObject
+   */
+  public function testGetFormObjectInvalidException() {
+    $this->setExpectedException(InvalidPluginDefinitionException::class, 'The "the_plugin_id" plugin did not specify a valid "invalid" form class, must implement \Drupal\Core\Plugin\PluginFormInterface');
+
+    $expected = new \stdClass();
+    $this->classResolver->getInstanceFromDefinition(get_class($expected))->willReturn($expected);
+
+    $plugin = $this->prophesize(PluginInspectionInterface::class);
+    $plugin->getPluginId()->willReturn('the_plugin_id');
+    $plugin->getPluginDefinition()->willReturn([
+      'form' => [
+        'invalid' => get_class($expected),
+      ],
+    ]);
+
+    $form_object = $this->manager->getFormObject($plugin->reveal(), 'invalid');
+    $this->assertSame(NULL, $form_object);
+  }
+
+}
