diff --git a/core/lib/Drupal/Core/Plugin/Context/ContextDefinition.php b/core/lib/Drupal/Core/Plugin/Context/ContextDefinition.php
index 63e4038abdfd309c8eae687017e772f969b3ccd5..55336d55c98cb30db0ec2fb0a9b08c802bc6a8f4 100644
--- a/core/lib/Drupal/Core/Plugin/Context/ContextDefinition.php
+++ b/core/lib/Drupal/Core/Plugin/Context/ContextDefinition.php
@@ -3,6 +3,11 @@
 namespace Drupal\Core\Plugin\Context;
 
 use Drupal\Core\DependencyInjection\DependencySerializationTrait;
+use Drupal\Core\Entity\ContentEntityStorageInterface;
+use Drupal\Core\Entity\Plugin\DataType\EntityAdapter;
+use Drupal\Core\Entity\Plugin\Validation\Constraint\BundleConstraint;
+use Drupal\Core\Entity\Plugin\Validation\Constraint\EntityTypeConstraint;
+use Drupal\Core\Entity\TypedData\EntityDataDefinition;
 use Drupal\Core\TypedData\TypedDataTrait;
 
 /**
@@ -252,4 +257,105 @@ public function getDataDefinition() {
     return $definition;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function isSatisfiedBy(ContextInterface $context) {
+    $definition = $context->getContextDefinition();
+    // If the data types do not match, this context is invalid unless the
+    // expected data type is any, which means all data types are supported.
+    if ($this->getDataType() != 'any' && $definition->getDataType() != $this->getDataType()) {
+      return FALSE;
+    }
+
+    // Get the value for this context, either directly if possible or by
+    // introspecting the definition.
+    if ($context->hasContextValue()) {
+      $values = [$context->getContextData()];
+    }
+    elseif ($definition instanceof static) {
+      $values = $definition->getSampleValues();
+    }
+    else {
+      $values = [];
+    }
+
+    $validator = $this->getTypedDataManager()->getValidator();
+    foreach ($values as $value) {
+      $violations = $validator->validate($value, array_values($this->getConstraintObjects()));
+      // If a value has no violations then the requirement is satisfied.
+      if (!$violations->count()) {
+        return TRUE;
+      }
+    }
+
+    return FALSE;
+  }
+
+  /**
+   * Returns typed data objects representing this context definition.
+   *
+   * This should return as many objects as needed to reflect the variations of
+   * the constraints it supports.
+   *
+   * @yield \Drupal\Core\TypedData\TypedDataInterface
+   *   The set of typed data object.
+   */
+  protected function getSampleValues() {
+    // @todo Move the entity specific logic out of this class in
+    //   https://www.drupal.org/node/2932462.
+    // Get the constraints from the context's definition.
+    $constraints = $this->getConstraintObjects();
+    // If constraints include EntityType, we generate an entity or adapter.
+    if (!empty($constraints['EntityType']) && $constraints['EntityType'] instanceof EntityTypeConstraint) {
+      $entity_type_manager = \Drupal::entityTypeManager();
+      $entity_type_id = $constraints['EntityType']->type;
+      $storage = $entity_type_manager->getStorage($entity_type_id);
+      // If the storage can generate a sample entity we might delegate to that.
+      if ($storage instanceof ContentEntityStorageInterface) {
+        if (!empty($constraints['Bundle']) && $constraints['Bundle'] instanceof BundleConstraint) {
+          foreach ($constraints['Bundle']->bundle as $bundle) {
+            // We have a bundle, we are bundleable and we can generate a sample.
+            yield EntityAdapter::createFromEntity($storage->createWithSampleValues($bundle));
+          }
+          return;
+        }
+      }
+
+      // Either no bundle, or not bundleable, so generate an entity adapter.
+      $definition = EntityDataDefinition::create($entity_type_id);
+      yield new EntityAdapter($definition);
+      return;
+    }
+
+    // No entity related constraints, so generate a basic typed data object.
+    yield $this->getTypedDataManager()->create($this->getDataDefinition());
+  }
+
+  /**
+   * Extracts an array of constraints for a context definition object.
+   *
+   * @return \Symfony\Component\Validator\Constraint[]
+   *   A list of applied constraints for the context definition.
+   */
+  protected function getConstraintObjects() {
+    $constraint_definitions = $this->getConstraints();
+
+    // @todo Move the entity specific logic out of this class in
+    //   https://www.drupal.org/node/2932462.
+    // If the data type is an entity, manually add one to the constraints array.
+    if (strpos($this->getDataType(), 'entity:') === 0) {
+      $entity_type_id = substr($this->getDataType(), 7);
+      $constraint_definitions['EntityType'] = ['type' => $entity_type_id];
+    }
+
+    $validation_constraint_manager = $this->getTypedDataManager()->getValidationConstraintManager();
+    $constraints = [];
+    foreach ($constraint_definitions as $constraint_name => $constraint_definition) {
+      $constraints[$constraint_name] = $validation_constraint_manager->create($constraint_name, $constraint_definition);
+    }
+
+    return $constraints;
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Plugin/Context/ContextDefinitionInterface.php b/core/lib/Drupal/Core/Plugin/Context/ContextDefinitionInterface.php
index c60c6c7fcb6533e6475d4c5e685de00128739caf..2f66fe9ef40c39e3fa1b49804ce48c391df4581d 100644
--- a/core/lib/Drupal/Core/Plugin/Context/ContextDefinitionInterface.php
+++ b/core/lib/Drupal/Core/Plugin/Context/ContextDefinitionInterface.php
@@ -20,4 +20,16 @@ interface ContextDefinitionInterface extends ComponentContextDefinitionInterface
    */
   public function getDataDefinition();
 
+  /**
+   * Determines if this definition is satisfied by a context object.
+   *
+   * @param \Drupal\Core\Plugin\Context\ContextInterface $context
+   *   The context object.
+   *
+   * @return bool
+   *   TRUE if this definition is satisfiable by the context object, FALSE
+   *   otherwise.
+   */
+  public function isSatisfiedBy(ContextInterface $context);
+
 }
diff --git a/core/lib/Drupal/Core/Plugin/Context/ContextHandler.php b/core/lib/Drupal/Core/Plugin/Context/ContextHandler.php
index 2a13d364d7e4883019c934c2139841c5d07aff57..56dcdb2a1c1a31acf983936c5f2b943cf4481d2c 100644
--- a/core/lib/Drupal/Core/Plugin/Context/ContextHandler.php
+++ b/core/lib/Drupal/Core/Plugin/Context/ContextHandler.php
@@ -43,23 +43,7 @@ public function checkRequirements(array $contexts, array $requirements) {
    */
   public function getMatchingContexts(array $contexts, ContextDefinitionInterface $definition) {
     return array_filter($contexts, function (ContextInterface $context) use ($definition) {
-      $context_definition = $context->getContextDefinition();
-
-      // If the data types do not match, this context is invalid unless the
-      // expected data type is any, which means all data types are supported.
-      if ($definition->getDataType() != 'any' && $definition->getDataType() != $context_definition->getDataType()) {
-        return FALSE;
-      }
-
-      // If any constraint does not match, this context is invalid.
-      foreach ($definition->getConstraints() as $constraint_name => $constraint) {
-        if ($context_definition->getConstraint($constraint_name) != $constraint) {
-          return FALSE;
-        }
-      }
-
-      // All contexts with matching data type and contexts are valid.
-      return TRUE;
+      return $definition->isSatisfiedBy($context);
     });
   }
 
diff --git a/core/modules/user/src/ContextProvider/CurrentUserContext.php b/core/modules/user/src/ContextProvider/CurrentUserContext.php
index e9eccd8190b18ac3de2a94cd446ad08b3bf1a987..73be2caa09528d3480be113b5dde5688d5572fed 100644
--- a/core/modules/user/src/ContextProvider/CurrentUserContext.php
+++ b/core/modules/user/src/ContextProvider/CurrentUserContext.php
@@ -50,6 +50,10 @@ public function __construct(AccountInterface $account, EntityManagerInterface $e
   public function getRuntimeContexts(array $unqualified_context_ids) {
     $current_user = $this->userStorage->load($this->account->id());
 
+    // @todo Do not validate protected fields to avoid bug in TypedData, remove
+    //   this in https://www.drupal.org/project/drupal/issues/2934192.
+    $current_user->_skipProtectedUserFieldConstraint = TRUE;
+
     $context = new Context(new ContextDefinition('entity:user', $this->t('Current user')), $current_user);
     $cacheability = new CacheableMetadata();
     $cacheability->setCacheContexts(['user']);
diff --git a/core/tests/Drupal/Tests/Core/Plugin/Context/ContextDefinitionIsSatisfiedTest.php b/core/tests/Drupal/Tests/Core/Plugin/Context/ContextDefinitionIsSatisfiedTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..edde3f98220ae5b8b6d3e2b40786ef711694b7be
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Plugin/Context/ContextDefinitionIsSatisfiedTest.php
@@ -0,0 +1,344 @@
+<?php
+
+namespace Drupal\Tests\Core\Plugin\Context;
+
+use Drupal\Core\Cache\NullBackend;
+use Drupal\Core\DependencyInjection\ClassResolverInterface;
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Core\Entity\ContentEntityInterface;
+use Drupal\Core\Entity\ContentEntityStorageInterface;
+use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Entity\EntityStorageInterface;
+use Drupal\Core\Entity\EntityType;
+use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Plugin\Context\Context;
+use Drupal\Core\Plugin\Context\ContextDefinition;
+use Drupal\Core\TypedData\TypedDataManager;
+use Drupal\Core\Validation\ConstraintManager;
+use Drupal\Tests\UnitTestCase;
+use Prophecy\Argument;
+
+/**
+ * @coversDefaultClass \Drupal\Core\Plugin\Context\ContextDefinition
+ * @group Plugin
+ */
+class ContextDefinitionIsSatisfiedTest extends UnitTestCase {
+
+  /**
+   * The entity type manager.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected $entityTypeManager;
+
+  /**
+   * The entity manager.
+   *
+   * @var \Drupal\Core\Entity\EntityManagerInterface
+   */
+  protected $entityManager;
+
+  /**
+   * The entity type bundle info.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface
+   */
+  protected $entityTypeBundleInfo;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $namespaces = new \ArrayObject([
+      'Drupal\\Core\\TypedData' => $this->root . '/core/lib/Drupal/Core/TypedData',
+      'Drupal\\Core\\Validation' => $this->root . '/core/lib/Drupal/Core/Validation',
+      'Drupal\\Core\\Entity' => $this->root . '/core/lib/Drupal/Core/Entity',
+    ]);
+    $cache_backend = new NullBackend('cache');
+    $module_handler = $this->prophesize(ModuleHandlerInterface::class);
+
+    $class_resolver = $this->prophesize(ClassResolverInterface::class);
+    $class_resolver->getInstanceFromDefinition(Argument::type('string'))->will(function ($arguments) {
+      $class_name = $arguments[0];
+      return new $class_name();
+    });
+
+    $type_data_manager = new TypedDataManager($namespaces, $cache_backend, $module_handler->reveal(), $class_resolver->reveal());
+    $type_data_manager->setValidationConstraintManager(new ConstraintManager($namespaces, $cache_backend, $module_handler->reveal()));
+
+    $this->entityTypeManager = $this->prophesize(EntityTypeManagerInterface::class);
+    $this->entityManager = $this->prophesize(EntityManagerInterface::class);
+
+    $this->entityTypeBundleInfo = $this->prophesize(EntityTypeBundleInfoInterface::class);
+
+    $container = new ContainerBuilder();
+    $container->set('typed_data_manager', $type_data_manager);
+    $container->set('entity_type.manager', $this->entityTypeManager->reveal());
+    $container->set('entity.manager', $this->entityManager->reveal());
+    $container->set('entity_type.bundle.info', $this->entityTypeBundleInfo->reveal());
+    \Drupal::setContainer($container);
+  }
+
+  /**
+   * Asserts that the requirement is satisfied as expected.
+   *
+   * @param bool $expected
+   *   The expected outcome.
+   * @param \Drupal\Core\Plugin\Context\ContextDefinition $requirement
+   *   The requirement to check against.
+   * @param \Drupal\Core\Plugin\Context\ContextDefinition $definition
+   *   The context definition to check.
+   * @param mixed $value
+   *   (optional) The value to set on the context, defaults to NULL.
+   */
+  protected function assertRequirementIsSatisfied($expected, ContextDefinition $requirement, ContextDefinition $definition, $value = NULL) {
+    $context = new Context($definition, $value);
+    $this->assertSame($expected, $requirement->isSatisfiedBy($context));
+  }
+
+  /**
+   * @covers ::isSatisfiedBy
+   * @covers ::getSampleValues
+   * @covers ::getConstraintObjects
+   *
+   * @dataProvider providerTestIsSatisfiedBy
+   */
+  public function testIsSatisfiedBy($expected, ContextDefinition $requirement, ContextDefinition $definition, $value = NULL) {
+    $entity_storage = $this->prophesize(EntityStorageInterface::class);
+    $content_entity_storage = $this->prophesize(ContentEntityStorageInterface::class);
+    $this->entityTypeManager->getStorage('test_config')->willReturn($entity_storage->reveal());
+    $this->entityTypeManager->getStorage('test_content')->willReturn($content_entity_storage->reveal());
+    $this->entityManager->getDefinitions()->willReturn([
+      'test_config' => new EntityType(['id' => 'test_config']),
+      'test_content' => new EntityType(['id' => 'test_content']),
+    ]);
+    $this->entityTypeBundleInfo->getBundleInfo('test_config')->willReturn([
+      'test_config' => ['label' => 'test_config'],
+    ]);
+    $this->entityTypeBundleInfo->getBundleInfo('test_content')->willReturn([
+      'test_content' => ['label' => 'test_content'],
+    ]);
+
+    $this->assertRequirementIsSatisfied($expected, $requirement, $definition, $value);
+  }
+
+  /**
+   * Provides test data for ::testIsSatisfiedBy().
+   */
+  public function providerTestIsSatisfiedBy() {
+    $data = [];
+
+    // Simple data types.
+    $data['both any'] = [
+      TRUE,
+      new ContextDefinition('any'),
+      new ContextDefinition('any'),
+    ];
+    $data['requirement any'] = [
+      TRUE,
+      new ContextDefinition('any'),
+      new ContextDefinition('integer'),
+    ];
+    $data['integer, out of range'] = [
+      FALSE,
+      (new ContextDefinition('integer'))->addConstraint('Range', ['min' => 0, 'max' => 10]),
+      new ContextDefinition('integer'),
+      20,
+    ];
+    $data['integer, within range'] = [
+      TRUE,
+      (new ContextDefinition('integer'))->addConstraint('Range', ['min' => 0, 'max' => 10]),
+      new ContextDefinition('integer'),
+      5,
+    ];
+    $data['integer, no value'] = [
+      TRUE,
+      (new ContextDefinition('integer'))->addConstraint('Range', ['min' => 0, 'max' => 10]),
+      new ContextDefinition('integer'),
+    ];
+    $data['non-integer, within range'] = [
+      FALSE,
+      (new ContextDefinition('integer'))->addConstraint('Range', ['min' => 0, 'max' => 10]),
+      new ContextDefinition('any'),
+      5,
+    ];
+
+    // Entities without bundles.
+    $data['content entity, matching type, no value'] = [
+      TRUE,
+      new ContextDefinition('entity:test_content'),
+      new ContextDefinition('entity:test_content'),
+    ];
+    $entity = $this->prophesize(ContentEntityInterface::class)->willImplement(\IteratorAggregate::class);
+    $entity->getIterator()->willReturn(new \ArrayIterator([]));
+    $entity->getCacheContexts()->willReturn([]);
+    $entity->getCacheTags()->willReturn([]);
+    $entity->getCacheMaxAge()->willReturn(0);
+    $entity->getEntityTypeId()->willReturn('test_content');
+    $data['content entity, matching type, correct value'] = [
+      TRUE,
+      new ContextDefinition('entity:test_content'),
+      new ContextDefinition('entity:test_content'),
+      $entity->reveal(),
+    ];
+    $data['content entity, incorrect manual constraint'] = [
+      TRUE,
+      new ContextDefinition('entity:test_content'),
+      (new ContextDefinition('entity:test_content'))->addConstraint('EntityType', 'test_config'),
+    ];
+    $data['config entity, matching type, no value'] = [
+      TRUE,
+      new ContextDefinition('entity:test_config'),
+      new ContextDefinition('entity:test_config'),
+    ];
+
+    return $data;
+  }
+
+  /**
+   * @covers ::isSatisfiedBy
+   * @covers ::getSampleValues
+   * @covers ::getConstraintObjects
+   *
+   * @dataProvider providerTestIsSatisfiedByGenerateBundledEntity
+   */
+  public function testIsSatisfiedByGenerateBundledEntity($expected, array $requirement_bundles, array $candidate_bundles, array $bundles_to_instantiate = NULL) {
+    // If no bundles are explicitly specified, instantiate all bundles.
+    if (!$bundles_to_instantiate) {
+      $bundles_to_instantiate = $candidate_bundles;
+    }
+
+    $content_entity_storage = $this->prophesize(ContentEntityStorageInterface::class);
+    foreach ($bundles_to_instantiate as $bundle) {
+      $entity = $this->prophesize(ContentEntityInterface::class)->willImplement(\IteratorAggregate::class);
+      $entity->getEntityTypeId()->willReturn('test_content');
+      $entity->getIterator()->willReturn(new \ArrayIterator([]));
+      $entity->bundle()->willReturn($bundle);
+      $content_entity_storage->createWithSampleValues($bundle)
+        ->willReturn($entity->reveal())
+        ->shouldBeCalled();
+    }
+
+    $this->entityTypeManager->getStorage('test_content')->willReturn($content_entity_storage->reveal());
+    $this->entityManager->getDefinitions()->willReturn([
+      'test_content' => new EntityType(['id' => 'test_content']),
+    ]);
+
+    $this->entityTypeBundleInfo->getBundleInfo('test_content')->willReturn([
+      'first_bundle' => ['label' => 'First bundle'],
+      'second_bundle' => ['label' => 'Second bundle'],
+      'third_bundle' => ['label' => 'Third bundle'],
+    ]);
+
+    $requirement = new ContextDefinition('entity:test_content');
+    if ($requirement_bundles) {
+      $requirement->addConstraint('Bundle', $requirement_bundles);
+    }
+    $definition = (new ContextDefinition('entity:test_content'))->addConstraint('Bundle', $candidate_bundles);
+    $this->assertRequirementIsSatisfied($expected, $requirement, $definition);
+  }
+
+  /**
+   * Provides test data for ::testIsSatisfiedByGenerateBundledEntity().
+   */
+  public function providerTestIsSatisfiedByGenerateBundledEntity() {
+    $data = [];
+    $data['no requirement'] = [
+      TRUE,
+      [],
+      ['first_bundle'],
+    ];
+    $data['single requirement'] = [
+      TRUE,
+      ['first_bundle'],
+      ['first_bundle'],
+    ];
+    $data['single requirement, multiple candidates, satisfies last candidate'] = [
+      TRUE,
+      ['third_bundle'],
+      ['first_bundle', 'second_bundle', 'third_bundle'],
+    ];
+    $data['single requirement, multiple candidates, satisfies first candidate'] = [
+      TRUE,
+      ['first_bundle'],
+      ['first_bundle', 'second_bundle', 'third_bundle'],
+      // Once the first match is found, subsequent candidates are not checked.
+      ['first_bundle'],
+    ];
+    $data['unsatisfied requirement'] = [
+      FALSE,
+      ['second_bundle'],
+      ['first_bundle', 'third_bundle'],
+    ];
+    $data['multiple requirements'] = [
+      TRUE,
+      ['first_bundle', 'second_bundle'],
+      ['first_bundle'],
+    ];
+    return $data;
+  }
+
+  /**
+   * @covers ::isSatisfiedBy
+   * @covers ::getSampleValues
+   * @covers ::getConstraintObjects
+   *
+   * @dataProvider providerTestIsSatisfiedByPassBundledEntity
+   */
+  public function testIsSatisfiedByPassBundledEntity($expected, $requirement_constraint) {
+    $this->entityManager->getDefinitions()->willReturn([
+      'test_content' => new EntityType(['id' => 'test_content']),
+    ]);
+    $this->entityTypeManager->getStorage('test_content')->shouldNotBeCalled();
+
+    $this->entityTypeBundleInfo->getBundleInfo('test_content')->willReturn([
+      'first_bundle' => ['label' => 'First bundle'],
+      'second_bundle' => ['label' => 'Second bundle'],
+      'third_bundle' => ['label' => 'Third bundle'],
+    ]);
+
+    $entity = $this->prophesize(ContentEntityInterface::class)->willImplement(\IteratorAggregate::class);
+    $entity->getEntityTypeId()->willReturn('test_content');
+    $entity->getIterator()->willReturn(new \ArrayIterator([]));
+    $entity->getCacheContexts()->willReturn([]);
+    $entity->getCacheTags()->willReturn([]);
+    $entity->getCacheMaxAge()->willReturn(0);
+    $entity->bundle()->willReturn('third_bundle');
+
+    $requirement = new ContextDefinition('entity:test_content');
+    if ($requirement_constraint) {
+      $requirement->addConstraint('Bundle', $requirement_constraint);
+    }
+    $definition = new ContextDefinition('entity:test_content');
+    $this->assertRequirementIsSatisfied($expected, $requirement, $definition, $entity->reveal());
+  }
+
+  /**
+   * Provides test data for ::testIsSatisfiedByPassBundledEntity().
+   */
+  public function providerTestIsSatisfiedByPassBundledEntity() {
+    $data = [];
+    $data[] = [TRUE, []];
+    $data[] = [FALSE, ['first_bundle']];
+    $data[] = [FALSE, ['second_bundle']];
+    $data[] = [TRUE, ['third_bundle']];
+    $data[] = [TRUE, ['first_bundle', 'second_bundle', 'third_bundle']];
+    $data[] = [FALSE, ['first_bundle', 'second_bundle']];
+    $data[] = [TRUE, ['first_bundle', 'third_bundle']];
+    $data[] = [TRUE, ['second_bundle', 'third_bundle']];
+    return $data;
+  }
+
+}
+
+namespace Drupal\Core\Validation;
+
+if (!function_exists('t')) {
+  function t($string, array $args = []) {
+    return strtr($string, $args);
+  }
+}
diff --git a/core/tests/Drupal/Tests/Core/Plugin/ContextHandlerTest.php b/core/tests/Drupal/Tests/Core/Plugin/ContextHandlerTest.php
index 4ed5e6eb602fe88c90a954b11c2ba137fae612e1..5cf8d9cc8bf24b9a3b04fb9fa868f32566a4e9df 100644
--- a/core/tests/Drupal/Tests/Core/Plugin/ContextHandlerTest.php
+++ b/core/tests/Drupal/Tests/Core/Plugin/ContextHandlerTest.php
@@ -9,12 +9,19 @@
 
 use Drupal\Component\Plugin\ConfigurablePluginInterface;
 use Drupal\Component\Plugin\Exception\ContextException;
+use Drupal\Core\Cache\NullBackend;
+use Drupal\Core\DependencyInjection\ClassResolverInterface;
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Plugin\Context\ContextDefinition;
 use Drupal\Core\Plugin\Context\ContextHandler;
 use Drupal\Core\Plugin\ContextAwarePluginInterface;
 use Drupal\Core\TypedData\DataDefinition;
 use Drupal\Core\TypedData\Plugin\DataType\StringData;
+use Drupal\Core\TypedData\TypedDataManager;
+use Drupal\Core\Validation\ConstraintManager;
 use Drupal\Tests\UnitTestCase;
+use Prophecy\Argument;
 
 /**
  * @coversDefaultClass \Drupal\Core\Plugin\Context\ContextHandler
@@ -36,6 +43,26 @@ protected function setUp() {
     parent::setUp();
 
     $this->contextHandler = new ContextHandler();
+
+    $namespaces = new \ArrayObject([
+      'Drupal\\Core\\TypedData' => $this->root . '/core/lib/Drupal/Core/TypedData',
+      'Drupal\\Core\\Validation' => $this->root . '/core/lib/Drupal/Core/Validation',
+    ]);
+    $cache_backend = new NullBackend('cache');
+    $module_handler = $this->prophesize(ModuleHandlerInterface::class);
+    $class_resolver = $this->prophesize(ClassResolverInterface::class);
+    $class_resolver->getInstanceFromDefinition(Argument::type('string'))->will(function ($arguments) {
+      $class_name = $arguments[0];
+      return new $class_name();
+    });
+    $type_data_manager = new TypedDataManager($namespaces, $cache_backend, $module_handler->reveal(), $class_resolver->reveal());
+    $type_data_manager->setValidationConstraintManager(
+      new ConstraintManager($namespaces, $cache_backend, $module_handler->reveal())
+    );
+
+    $container = new ContainerBuilder();
+    $container->set('typed_data_manager', $type_data_manager);
+    \Drupal::setContainer($container);
   }
 
   /**
@@ -60,10 +87,10 @@ public function providerTestCheckRequirements() {
     $context_any = $this->getMock('Drupal\Core\Plugin\Context\ContextInterface');
     $context_any->expects($this->atLeastOnce())
       ->method('getContextDefinition')
-      ->will($this->returnValue(new ContextDefinition('empty')));
+      ->will($this->returnValue(new ContextDefinition('any')));
 
-    $requirement_specific = new ContextDefinition('specific');
-    $requirement_specific->setConstraints(['bar' => 'baz']);
+    $requirement_specific = new ContextDefinition('string');
+    $requirement_specific->setConstraints(['Blank' => []]);
 
     $context_constraint_mismatch = $this->getMock('Drupal\Core\Plugin\Context\ContextInterface');
     $context_constraint_mismatch->expects($this->atLeastOnce())
@@ -74,8 +101,8 @@ public function providerTestCheckRequirements() {
       ->method('getContextDefinition')
       ->will($this->returnValue(new ContextDefinition('fuzzy')));
 
-    $context_definition_specific = new ContextDefinition('specific');
-    $context_definition_specific->setConstraints(['bar' => 'baz']);
+    $context_definition_specific = new ContextDefinition('string');
+    $context_definition_specific->setConstraints(['Blank' => []]);
     $context_specific = $this->getMock('Drupal\Core\Plugin\Context\ContextInterface');
     $context_specific->expects($this->atLeastOnce())
       ->method('getContextDefinition')
@@ -112,13 +139,13 @@ public function testGetMatchingContexts($contexts, $requirement, $expected = NUL
   public function providerTestGetMatchingContexts() {
     $requirement_any = new ContextDefinition();
 
-    $requirement_specific = new ContextDefinition('specific');
-    $requirement_specific->setConstraints(['bar' => 'baz']);
+    $requirement_specific = new ContextDefinition('string');
+    $requirement_specific->setConstraints(['Blank' => []]);
 
     $context_any = $this->getMock('Drupal\Core\Plugin\Context\ContextInterface');
     $context_any->expects($this->atLeastOnce())
       ->method('getContextDefinition')
-      ->will($this->returnValue(new ContextDefinition('empty')));
+      ->will($this->returnValue(new ContextDefinition('any')));
     $context_constraint_mismatch = $this->getMock('Drupal\Core\Plugin\Context\ContextInterface');
     $context_constraint_mismatch->expects($this->atLeastOnce())
       ->method('getContextDefinition')
@@ -127,8 +154,8 @@ public function providerTestGetMatchingContexts() {
     $context_datatype_mismatch->expects($this->atLeastOnce())
       ->method('getContextDefinition')
       ->will($this->returnValue(new ContextDefinition('fuzzy')));
-    $context_definition_specific = new ContextDefinition('specific');
-    $context_definition_specific->setConstraints(['bar' => 'baz']);
+    $context_definition_specific = new ContextDefinition('string');
+    $context_definition_specific->setConstraints(['Blank' => []]);
     $context_specific = $this->getMock('Drupal\Core\Plugin\Context\ContextInterface');
     $context_specific->expects($this->atLeastOnce())
       ->method('getContextDefinition')
@@ -158,7 +185,7 @@ public function providerTestGetMatchingContexts() {
   public function testFilterPluginDefinitionsByContexts($has_context, $definitions, $expected) {
     if ($has_context) {
       $context = $this->getMock('Drupal\Core\Plugin\Context\ContextInterface');
-      $expected_context_definition = (new ContextDefinition('expected_data_type'))->setConstraints(['expected_constraint_name' => 'expected_constraint_value']);
+      $expected_context_definition = (new ContextDefinition('string'))->setConstraints(['Blank' => []]);
       $context->expects($this->atLeastOnce())
         ->method('getContextDefinition')
         ->will($this->returnValue($expected_context_definition));
@@ -189,7 +216,7 @@ public function providerTestFilterPluginDefinitionsByContexts() {
     // No context, all plugins available.
     $data[] = [FALSE, $plugins, $plugins];
 
-    $plugins = ['expected_plugin' => ['context' => ['context1' => new ContextDefinition('expected_data_type')]]];
+    $plugins = ['expected_plugin' => ['context' => ['context1' => new ContextDefinition('string')]]];
     // Missing context, no plugins available.
     $data[] = [FALSE, $plugins, []];
     // Satisfied context, all plugins available.
@@ -206,7 +233,7 @@ public function providerTestFilterPluginDefinitionsByContexts() {
     // Optional mismatched constraint, all plugins available.
     $data[] = [FALSE, $plugins, $plugins];
 
-    $expected_context_definition = (new ContextDefinition('expected_data_type'))->setConstraints(['expected_constraint_name' => 'expected_constraint_value']);
+    $expected_context_definition = (new ContextDefinition('string'))->setConstraints(['Blank' => []]);
     $plugins = ['expected_plugin' => ['context' => ['context1' => $expected_context_definition]]];
     // Satisfied context with constraint, all plugins available.
     $data[] = [TRUE, $plugins, $plugins];
@@ -220,7 +247,7 @@ public function providerTestFilterPluginDefinitionsByContexts() {
     $unexpected_context_definition = (new ContextDefinition('unexpected_data_type'))->setConstraints(['mismatched_constraint_name' => 'mismatched_constraint_value']);
     $plugins = [
       'unexpected_plugin' => ['context' => ['context1' => $unexpected_context_definition]],
-      'expected_plugin' => ['context' => ['context2' => new ContextDefinition('expected_data_type')]],
+      'expected_plugin' => ['context' => ['context2' => new ContextDefinition('string')]],
     ];
     // Context only satisfies one plugin.
     $data[] = [TRUE, $plugins, ['expected_plugin' => $plugins['expected_plugin']]];