diff --git a/context.module b/context.module
index 482b60b..652d288 100644
--- a/context.module
+++ b/context.module
@@ -4,7 +4,8 @@
  * @file
  * Defines Drupal hooks for context module.
  */
-
+use Drupal\Core\Hook\Attribute\LegacyHook;
+use Drupal\context\Hook\ContextHooks;
 use Drupal\Core\Render\Markup;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\Component\Utility\NestedArray;
@@ -16,24 +17,9 @@ use Drupal\Core\Form\FormStateInterface;
 /**
  * Implements hook_help().
  */
+#[LegacyHook]
 function context_help($route_name, RouteMatchInterface $route_match) {
-  switch ($route_name) {
-    case 'help.page.context':
-      $output = '';
-      $output .= '<h3>' . t('About') . '</h3>';
-      $output .= '<p>' . t('The Context module lets users define conditions for when certain reactions should take place.') . '</p>';
-      $output .= '<p>' . t('An example of a condition could be when viewing a certain node type and blocks should be placed as a reaction when viewing a page with this node type.') . '</p>';
-      $output .= '<h3>' . t('Uses') . '</h3>';
-      $output .= '<dl>';
-      $output .= '<dt>' . t('Managing context') . '</dt>';
-      $output .= '<dd>' . t('Users with <em>Administer contexts</em> permission can add contextual conditions and reactions for different portions of their site. For each context, they can choose the conditions that trigger this context to be active and choose different aspects of their site that should react to this active context.') . '</dd>';
-      $output .= '<dt>' . t('Adding new custom reactions') . '</dt>';
-      $output .= '<dd>' . t('Reactions for the context module are defined trough the new <a href=":link">Drupal 8 Plugin API</a>.', [':link' => 'https://www.drupal.org/developing/api/8/plugins']) . '</dd>';
-      $output .= '<dd>' . t('The Context module defines a plugin type named ContextReaction that users can extend when creating their own plugins.') . '</dd>';
-      $output .= '<dd>' . t('A context reaction requires a configuration form and execute method. The execution of the plugin is also something that will have to be handled by the author of the reaction.') . '</dd>';
-      $output .= '</dl>';
-      return $output;
-  }
+  return \Drupal::service(ContextHooks::class)->help($route_name, $route_match);
 }
 
 /**
@@ -42,114 +28,43 @@ function context_help($route_name, RouteMatchInterface $route_match) {
  * Run the body class context reactions if there are any and let them add
  * classes to the page body.
  */
-function context_preprocess_html(&$variables) {
-  /** @var \Drupal\context\ContextManager $context_manager */
-  $context_manager = \Drupal::service('context.manager');
-  // Active theme for route.
-  $current_theme = \Drupal::service('theme.negotiator')->determineActiveTheme(Drupal::routeMatch());
-
-  foreach ($context_manager->getActiveReactions('body_class') as $reaction) {
-    $variables['attributes'] = NestedArray::mergeDeep($variables['attributes'], $reaction->execute());
-  }
-
-  foreach ($context_manager->getActiveReactions('page_title') as $reaction) {
-    $variables['head_title']['title'] = Markup::create(trim(strip_tags($reaction->execute())));
-  }
-
-  // Disable regions based on regions reaction.
-  foreach ($context_manager->getActiveReactions('regions') as $region_reaction) {
-    $configuration = $region_reaction->getConfiguration();
-    if (isset($configuration['regions'][$current_theme])) {
-      foreach ($configuration['regions'][$current_theme] as $region) {
-        unset($variables['page'][$region]);
-      }
-    }
-  }
-
+#[LegacyHook]
+function context_preprocess_html(&$variables)
+{
+    \Drupal::service(ContextHooks::class)->preprocessHtml($variables);
 }
 
 /**
  * Implements hook_preprocess_HOOK().
  */
-function context_preprocess_page_title(&$variables) {
-  /** @var \Drupal\context\ContextManager $context_manager */
-  $context_manager = \Drupal::service('context.manager');
-
-  foreach ($context_manager->getActiveReactions('page_title') as $reaction) {
-    $variables['title'] = $reaction->execute();
-  }
+#[LegacyHook]
+function context_preprocess_page_title(&$variables)
+{
+    \Drupal::service(ContextHooks::class)->preprocessPageTitle($variables);
 }
 
 /**
  * Implements hook_theme_suggestions_page_alter().
  */
-function context_theme_suggestions_page_alter(array &$suggestions, array $variables) {
-  $context_manager = \Drupal::service('context.manager');
-  foreach ($context_manager->getActiveReactions('page_template_suggestions') as $reaction) {
-    $template_suggestions = explode(PHP_EOL, $reaction->execute());
-    $suggestions = array_merge($suggestions, $template_suggestions);
-  }
+#[LegacyHook]
+function context_theme_suggestions_page_alter(array &$suggestions, array $variables)
+{
+    \Drupal::service(ContextHooks::class)->themeSuggestionsPageAlter($suggestions, $variables);
 }
 
 /**
  * Implements hook_form_alter().
  */
+#[LegacyHook]
 function context_form_alter(&$form, FormStateInterface $form_state, $form_id) {
-  // If this is Context form.
-  if ($form_id === 'context_edit_form') {
-    $reactions = $form["reactions"]["#process"];
-    foreach ($reactions as $reaction) {
-      foreach ($reaction as $react) {
-        if (
-          is_object($react) &&
-          property_exists($react, 'entity') &&
-          $react->getEntity()->getEntityTypeId() === 'context'
-        ) {
-
-          // If menu reaction is selected.
-          $entity = $react->getEntity();
-          if (
-            !empty($entity->get('reactions')) &&
-            array_key_exists('menu', $entity->get('reactions'))
-          ) {
-
-            // Verify is the correct context class service is correct.
-            $definition = \Drupal::service('menu.active_trail');
-            if (!$definition instanceof ContextMenuActiveTrail) {
-              // Warn users about this skip.
-              $messenger = \Drupal::messenger();
-              $messenger->addMessage(t(
-                '@module will not work because @service has a different menu service provider.',
-                [
-                  '@module' => 'Context module: "Menu Reactions"',
-                  '@service' => 'menu.active_trail',
-                ]
-              ), $messenger::TYPE_WARNING);
-              $form_state->disableRedirect();
-            }
-          }
-        }
-      }
-    }
-  }
+  \Drupal::service(ContextHooks::class)->formAlter($form, $form_state, $form_id);
 }
 
 /**
  * Implements hook_ENTITY_TYPE_presave().
  */
-function context_context_presave(ContextInterface $context) {
-  $context_id = $context->id();
-  // Update the 'context_id' from block reactions.
-  foreach ($context->getReactions() as $reaction) {
-    if ($reaction instanceof Blocks) {
-      foreach ($reaction->getBlocks() as $block) {
-        $config = $block->getConfiguration();
-        if (isset($config['context_id']) && $config['context_id'] != $context_id) {
-          $config['context_id'] = $context_id;
-          $block->setConfiguration($config);
-          $context->save();
-        }
-      }
-    }
-  }
+#[LegacyHook]
+function context_context_presave(ContextInterface $context)
+{
+    \Drupal::service(ContextHooks::class)->contextPresave($context);
 }
diff --git a/context.services.yml b/context.services.yml
index 3575cc1..353333d 100644
--- a/context.services.yml
+++ b/context.services.yml
@@ -15,3 +15,7 @@ services:
     arguments: ['@context.manager']
     tags:
       - { name: theme_negotiator, priority: 1000 }
+
+  Drupal\context\Hook\ContextHooks:
+    class: Drupal\context\Hook\ContextHooks
+    autowire: true
diff --git a/modules/context_ui/src/Form/ConditionDeleteForm.php b/modules/context_ui/src/Form/ConditionDeleteForm.php
index 74ad3b4..c4a8afb 100644
--- a/modules/context_ui/src/Form/ConditionDeleteForm.php
+++ b/modules/context_ui/src/Form/ConditionDeleteForm.php
@@ -89,7 +89,7 @@ class ConditionDeleteForm extends ConfirmFormBase {
   /**
    * {@inheritdoc}
    */
-  public function buildForm(array $form, FormStateInterface $form_state, ContextInterface $context = NULL, $condition_id = NULL) {
+  public function buildForm(array $form, FormStateInterface $form_state, ?ContextInterface $context = NULL, $condition_id = NULL) {
     $this->context = $context;
     $this->condition = $context->getCondition($condition_id);
 
diff --git a/modules/context_ui/src/Form/ReactionDeleteForm.php b/modules/context_ui/src/Form/ReactionDeleteForm.php
index 884210f..2c0afe4 100644
--- a/modules/context_ui/src/Form/ReactionDeleteForm.php
+++ b/modules/context_ui/src/Form/ReactionDeleteForm.php
@@ -92,7 +92,7 @@ class ReactionDeleteForm extends ConfirmFormBase implements ContainerInjectionIn
   /**
    * {@inheritdoc}
    */
-  public function buildForm(array $form, FormStateInterface $form_state, ContextInterface $context = NULL, $reaction_id = NULL) {
+  public function buildForm(array $form, FormStateInterface $form_state, ?ContextInterface $context = NULL, $reaction_id = NULL) {
     $this->context = $context;
     $this->reaction = $this->context->getReaction($reaction_id);
 
diff --git a/src/Hook/ContextHooks.php b/src/Hook/ContextHooks.php
new file mode 100644
index 0000000..20c2db8
--- /dev/null
+++ b/src/Hook/ContextHooks.php
@@ -0,0 +1,152 @@
+<?php
+
+namespace Drupal\context\Hook;
+
+use Drupal\Core\Render\Markup;
+use Drupal\Core\Routing\RouteMatchInterface;
+use Drupal\Component\Utility\NestedArray;
+use Drupal\context\ContextInterface;
+use Drupal\context\ContextMenuActiveTrail;
+use Drupal\context\Plugin\ContextReaction\Blocks;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Hook\Attribute\Hook;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+/**
+ * Hook implementations for context.
+ */
+class ContextHooks
+{
+    use StringTranslationTrait;
+    /**
+     * Implements hook_help().
+     */
+    #[Hook('help')]
+    public function help($route_name, \Drupal\Core\Routing\RouteMatchInterface $route_match)
+    {
+        switch ($route_name) {
+            case 'help.page.context':
+                $output = '';
+                $output .= '<h3>' . $this->t('About') . '</h3>';
+                $output .= '<p>' . $this->t('The Context module lets users define conditions for when certain reactions should take place.') . '</p>';
+                $output .= '<p>' . $this->t('An example of a condition could be when viewing a certain node type and blocks should be placed as a reaction when viewing a page with this node type.') . '</p>';
+                $output .= '<h3>' . $this->t('Uses') . '</h3>';
+                $output .= '<dl>';
+                $output .= '<dt>' . $this->t('Managing context') . '</dt>';
+                $output .= '<dd>' . $this->t('Users with <em>Administer contexts</em> permission can add contextual conditions and reactions for different portions of their site. For each context, they can choose the conditions that trigger this context to be active and choose different aspects of their site that should react to this active context.') . '</dd>';
+                $output .= '<dt>' . $this->t('Adding new custom reactions') . '</dt>';
+                $output .= '<dd>' . $this->t('Reactions for the context module are defined trough the new <a href=":link">Drupal 8 Plugin API</a>.', [
+                    ':link' => 'https://www.drupal.org/developing/api/8/plugins',
+                ]) . '</dd>';
+                $output .= '<dd>' . $this->t('The Context module defines a plugin type named ContextReaction that users can extend when creating their own plugins.') . '</dd>';
+                $output .= '<dd>' . $this->t('A context reaction requires a configuration form and execute method. The execution of the plugin is also something that will have to be handled by the author of the reaction.') . '</dd>';
+                $output .= '</dl>';
+                return $output;
+        }
+    }
+    /**
+     * Implements hook_preprocess_HOOK().
+     *
+     * Run the body class context reactions if there are any and let them add
+     * classes to the page body.
+     */
+    #[Hook('preprocess_html')]
+    public static function preprocessHtml(&$variables)
+    {
+        /** @var \Drupal\context\ContextManager $context_manager */
+        $context_manager = \Drupal::service('context.manager');
+        // Active theme for route.
+        $current_theme = \Drupal::service('theme.negotiator')->determineActiveTheme(\Drupal::routeMatch());
+        foreach ($context_manager->getActiveReactions('body_class') as $reaction) {
+            $variables['attributes'] = \Drupal\Component\Utility\NestedArray::mergeDeep($variables['attributes'], $reaction->execute());
+        }
+        foreach ($context_manager->getActiveReactions('page_title') as $reaction) {
+            $variables['head_title']['title'] = \Drupal\Core\Render\Markup::create(trim(strip_tags($reaction->execute())));
+        }
+        // Disable regions based on regions reaction.
+        foreach ($context_manager->getActiveReactions('regions') as $region_reaction) {
+            $configuration = $region_reaction->getConfiguration();
+            if (isset($configuration['regions'][$current_theme])) {
+                foreach ($configuration['regions'][$current_theme] as $region) {
+                    unset($variables['page'][$region]);
+                }
+            }
+        }
+    }
+    /**
+     * Implements hook_preprocess_HOOK().
+     */
+    #[Hook('preprocess_page_title')]
+    public static function preprocessPageTitle(&$variables)
+    {
+        /** @var \Drupal\context\ContextManager $context_manager */
+        $context_manager = \Drupal::service('context.manager');
+        foreach ($context_manager->getActiveReactions('page_title') as $reaction) {
+            $variables['title'] = $reaction->execute();
+        }
+    }
+    /**
+     * Implements hook_theme_suggestions_page_alter().
+     */
+    #[Hook('theme_suggestions_page_alter')]
+    public static function themeSuggestionsPageAlter(array &$suggestions, array $variables)
+    {
+        $context_manager = \Drupal::service('context.manager');
+        foreach ($context_manager->getActiveReactions('page_template_suggestions') as $reaction) {
+            $template_suggestions = explode(PHP_EOL, $reaction->execute());
+            $suggestions = array_merge($suggestions, $template_suggestions);
+        }
+    }
+    /**
+     * Implements hook_form_alter().
+     */
+    #[Hook('form_alter')]
+    public function formAlter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id)
+    {
+        // If this is Context form.
+        if ($form_id === 'context_edit_form') {
+            $reactions = $form["reactions"]["#process"];
+            foreach ($reactions as $reaction) {
+                foreach ($reaction as $react) {
+                    if (is_object($react) && property_exists($react, 'entity') && $react->getEntity()->getEntityTypeId() === 'context') {
+                        // If menu reaction is selected.
+                        $entity = $react->getEntity();
+                        if (!empty($entity->get('reactions')) && array_key_exists('menu', $entity->get('reactions'))) {
+                            // Verify is the correct context class service is correct.
+                            $definition = \Drupal::service('menu.active_trail');
+                            if (!$definition instanceof \Drupal\context\ContextMenuActiveTrail) {
+                                // Warn users about this skip.
+                                $messenger = \Drupal::messenger();
+                                $messenger->addMessage($this->t('@module will not work because @service has a different menu service provider.', [
+                                    '@module' => 'Context module: "Menu Reactions"',
+                                    '@service' => 'menu.active_trail',
+                                ]), $messenger::TYPE_WARNING);
+                                $form_state->disableRedirect();
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    /**
+     * Implements hook_ENTITY_TYPE_presave().
+     */
+    #[Hook('context_presave')]
+    public static function contextPresave(\Drupal\context\ContextInterface $context)
+    {
+        $context_id = $context->id();
+        // Update the 'context_id' from block reactions.
+        foreach ($context->getReactions() as $reaction) {
+            if ($reaction instanceof \Drupal\context\Plugin\ContextReaction\Blocks) {
+                foreach ($reaction->getBlocks() as $block) {
+                    $config = $block->getConfiguration();
+                    if (isset($config['context_id']) && $config['context_id'] != $context_id) {
+                        $config['context_id'] = $context_id;
+                        $block->setConfiguration($config);
+                        $context->save();
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/src/Plugin/ContextReaction/Blocks.php b/src/Plugin/ContextReaction/Blocks.php
index a67c52e..fb86276 100644
--- a/src/Plugin/ContextReaction/Blocks.php
+++ b/src/Plugin/ContextReaction/Blocks.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\context\Plugin\ContextReaction;
 
+use Drupal\Component\Utility\DeprecationHelper;
 use Drupal\block\BlockRepositoryInterface;
 use Drupal\block\Entity\Block;
 use Drupal\Core\Access\AccessResult;
@@ -790,7 +791,7 @@ class Blocks extends ContextReactionPluginBase implements ContainerFactoryPlugin
    * @todo This could be moved to a service since we use it in a couple of places.
    */
   protected function getSystemRegionList($theme, $show = BlockRepositoryInterface::REGIONS_ALL) {
-    return system_region_list($theme, $show);
+    return DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '11.4.0', fn() => \Drupal::service('theme_handler')->getTheme($theme)->listAllRegions(), fn() => system_region_list($theme, $show));
   }
 
   /**
diff --git a/src/Plugin/ContextReaction/Regions.php b/src/Plugin/ContextReaction/Regions.php
index 81513e9..749e3c2 100644
--- a/src/Plugin/ContextReaction/Regions.php
+++ b/src/Plugin/ContextReaction/Regions.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\context\Plugin\ContextReaction;
 
+use Drupal\Component\Utility\DeprecationHelper;
 use Drupal\block\BlockRepositoryInterface;
 use Drupal\context\ContextReactionPluginBase;
 use Drupal\Core\Extension\ThemeHandlerInterface;
@@ -162,7 +163,7 @@ class Regions extends ContextReactionPluginBase implements ContainerFactoryPlugi
    * @todo This could be moved to a service since we use it in a couple of places.
    */
   protected function getSystemRegionList($theme, $show = BlockRepositoryInterface::REGIONS_ALL) {
-    return system_region_list($theme, $show);
+    return DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '11.4.0', fn() => \Drupal::service('theme_handler')->getTheme($theme)->listAllRegions(), fn() => system_region_list($theme, $show));
   }
 
   /**
diff --git a/src/Reaction/Blocks/Form/BlockFormBase.php b/src/Reaction/Blocks/Form/BlockFormBase.php
index 7c6eff2..562efb7 100644
--- a/src/Reaction/Blocks/Form/BlockFormBase.php
+++ b/src/Reaction/Blocks/Form/BlockFormBase.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\context\Reaction\Blocks\Form;
 
+use Drupal\Component\Utility\DeprecationHelper;
 use Drupal\block\BlockRepositoryInterface;
 use Drupal\block\Entity\Block;
 use Drupal\Component\Plugin\PluginManagerInterface;
@@ -405,7 +406,7 @@ abstract class BlockFormBase extends FormBase {
    *   The regions of the theme.
    */
   protected function getThemeRegionOptions($theme, $show = BlockRepositoryInterface::REGIONS_ALL) {
-    $regions = system_region_list($theme, $show);
+    $regions = DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '11.4.0', fn() => \Drupal::service('theme_handler')->getTheme($theme)->listAllRegions(), fn() => system_region_list($theme, $show));
 
     foreach ($regions as $region => $title) {
       $regions[$region] = $title;
diff --git a/tests/src/Kernel/RequestPathExclusionTest.php b/tests/src/Kernel/RequestPathExclusionTest.php
index 10fe0df..3f6b534 100644
--- a/tests/src/Kernel/RequestPathExclusionTest.php
+++ b/tests/src/Kernel/RequestPathExclusionTest.php
@@ -56,8 +56,6 @@ class RequestPathExclusionTest extends KernelTestBase {
   protected function setUp(): void {
     parent::setUp();
 
-    $this->installSchema('system', ['sequences']);
-
     $this->pluginManager = $this->container->get('plugin.manager.condition');
 
     // Set a mock alias manager in the container.
