diff --git a/redirect.api.php b/redirect.api.php
index 9ec1bdf..376b32b 100644
--- a/redirect.api.php
+++ b/redirect.api.php
@@ -54,6 +54,31 @@
  */
 
 /**
+ * Act on a redirect response when it is triggered.
+ *
+ * This hook is invoked before the response is sent to the user. The redirect
+ * entity itself is sent as well for inspection.
+ *
+ * @param \Symfony\Component\HttpFoundation\RedirectResponse $response
+ *   The generated redirect response object before it is delivered.
+ * @param \Drupal\redirect\Entity\Redirect $redirect
+ *   The redirect entity used to generate the response object.
+ *
+ * @ingroup redirect_api_hooks
+ */
+function hook_redirect_response_alter(\Symfony\Component\HttpFoundation\RedirectResponse $response, \Drupal\redirect\Entity\Redirect $redirect) {
+  // Set a drupal message.
+  if (!$redirect->getRedirectUrl()->isExternal()) {
+    drupal_set_message(t('You are not being directed off-site.'), 'status');
+  }
+
+  // If `some condition`, send to Drupal.org.
+  if (FALSE) {
+    $response->setTrustedTargetUrl('http://drupal.org');
+  }
+}
+
+/**
  * Act on redirects being loaded from the database.
  *
  * This hook is invoked during redirect loading, which is handled by
@@ -122,21 +147,5 @@ function hook_redirect_prepare($redirect) {
 }
 
 /**
- * Act on a redirect being redirected.
- *
- * This hook is invoked from redirect_redirect() before the redirect callback
- * is invoked.
- *
- * @param $redirect
- *   The redirect that is being used for the redirect.
- *
- * @see redirect_redirect()
- * @see drupal_page_is_cacheable()
- * @ingroup redirect_api_hooks
- */
-function hook_redirect_alter($redirect) {
-}
-
-/**
  * @} End of "addtogroup hooks".
  */
diff --git a/redirect.module b/redirect.module
index 79131a5..d9208ed 100644
--- a/redirect.module
+++ b/redirect.module
@@ -27,7 +27,7 @@ use Drupal\redirect\Entity\Redirect;
  * Implements hook_hook_info().
  */
 function redirect_hook_info() {
-  $hooks = array(
+  $hooks = [
     'redirect_load',
     'redirect_load_by_source_alter',
     'redirect_access',
@@ -38,7 +38,8 @@ function redirect_hook_info() {
     'redirect_update',
     'redirect_delete',
     'redirect_alter',
-  );
+    'redirect_response',
+  ];
 
   return array_fill_keys($hooks, array('group' => 'redirect'));
 }
diff --git a/redirect.services.yml b/redirect.services.yml
index 743bd93..43cb8e3 100644
--- a/redirect.services.yml
+++ b/redirect.services.yml
@@ -11,7 +11,7 @@ services:
     arguments: ['@config.factory', '@state', '@access_manager', '@current_user', '@router.route_provider']
   redirect.request_subscriber:
     class: Drupal\redirect\EventSubscriber\RedirectRequestSubscriber
-    arguments: ['@redirect.repository', '@language_manager', '@config.factory', '@path.alias_manager', '@module_handler', '@entity.manager', '@redirect.checker', '@router.request_context', '@path_processor_manager']
+    arguments: ['@redirect.repository', '@language_manager', '@config.factory', '@module_handler', '@redirect.checker', '@router.request_context', '@path_processor_manager']
     tags:
       - { name: event_subscriber }
   redirect.settings_cache_tag:
diff --git a/src/EventSubscriber/RedirectRequestSubscriber.php b/src/EventSubscriber/RedirectRequestSubscriber.php
index a31fa22..26cce95 100644
--- a/src/EventSubscriber/RedirectRequestSubscriber.php
+++ b/src/EventSubscriber/RedirectRequestSubscriber.php
@@ -2,21 +2,15 @@
 
 namespace Drupal\redirect\EventSubscriber;
 
-use Drupal\Core\Cache\CacheableMetadata;
 use Drupal\Core\Config\ConfigFactoryInterface;
-use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Language\LanguageManagerInterface;
-use Drupal\Core\Logger\RfcLogLevel;
-use Drupal\Core\Path\AliasManager;
 use Drupal\Core\PathProcessor\InboundPathProcessorInterface;
 use Drupal\Core\Routing\TrustedRedirectResponse;
-use Drupal\Core\Url;
 use Drupal\redirect\Exception\RedirectLoopException;
 use Drupal\redirect\RedirectChecker;
 use Drupal\redirect\RedirectRepository;
 use Symfony\Component\HttpFoundation\Response;
-use Symfony\Component\HttpKernel\HttpKernelInterface;
 use Symfony\Component\HttpKernel\KernelEvents;
 use Symfony\Component\HttpKernel\Event\GetResponseEvent;
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
@@ -41,21 +35,11 @@ class RedirectRequestSubscriber implements EventSubscriberInterface {
   protected $config;
 
   /**
-   * @var \Drupal\Core\Path\AliasManager
-   */
-  protected $aliasManager;
-
-  /**
    * @var \Drupal\Core\Extension\ModuleHandlerInterface
    */
   protected $moduleHandler;
 
   /**
-   * @var \Drupal\Core\Entity\EntityManagerInterface
-   */
-  protected $entityManager;
-
-  /**
    * @var \Drupal\redirect\RedirectChecker
    */
   protected $checker;
@@ -85,20 +69,16 @@ class RedirectRequestSubscriber implements EventSubscriberInterface {
    *   The alias manager service.
    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
    *   The module handler service.
-   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
-   *   The entity manager service.
    * @param \Drupal\redirect\RedirectChecker $checker
    *   The redirect checker service.
    * @param \Symfony\Component\Routing\RequestContext
    *   Request context.
    */
-  public function __construct(RedirectRepository $redirect_repository, LanguageManagerInterface $language_manager, ConfigFactoryInterface $config, AliasManager $alias_manager, ModuleHandlerInterface $module_handler, EntityManagerInterface $entity_manager, RedirectChecker $checker, RequestContext $context, InboundPathProcessorInterface $path_processor) {
+  public function __construct(RedirectRepository $redirect_repository, LanguageManagerInterface $language_manager, ConfigFactoryInterface $config, ModuleHandlerInterface $module_handler, RedirectChecker $checker, RequestContext $context, InboundPathProcessorInterface $path_processor) {
     $this->redirectRepository = $redirect_repository;
     $this->languageManager = $language_manager;
     $this->config = $config->get('redirect.settings');
-    $this->aliasManager = $alias_manager;
     $this->moduleHandler = $module_handler;
-    $this->entityManager = $entity_manager;
     $this->checker = $checker;
     $this->context = $context;
     $this->pathProcessor = $path_processor;
@@ -157,32 +137,10 @@ class RedirectRequestSubscriber implements EventSubscriberInterface {
       ];
       $response = new TrustedRedirectResponse($url->setAbsolute()->toString(), $redirect->getStatusCode(), $headers);
       $response->addCacheableDependency($redirect);
-      $event->setResponse($response);
-    }
-  }
-
-  /**
-   * Prior to set the response it check if we can redirect.
-   *
-   * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
-   *   The event object.
-   * @param \Drupal\Core\Url $url
-   *   The Url where we want to redirect.
-   */
-  protected function setResponse(GetResponseEvent $event, Url $url) {
-    $request = $event->getRequest();
-    $this->context->fromRequest($request);
 
-    parse_str($request->getQueryString(), $query);
-    $url->setOption('query', $query);
-    $url->setAbsolute(TRUE);
+      // Invoke hook_redirect_response_alter().
+      $this->moduleHandler->alter('redirect_response', $response, $redirect);
 
-    // We can only check access for routed URLs.
-    if (!$url->isRouted() || $this->checker->canRedirect($request, $url->getRouteName())) {
-      // Add the 'rendered' cache tag, so that we can invalidate all responses
-      // when settings are changed.
-      $response = new TrustedRedirectResponse($url->toString(), 301);
-      $response->addCacheableDependency(CacheableMetadata::createFromRenderArray([])->addCacheTags(['rendered']));
       $event->setResponse($response);
     }
   }
diff --git a/src/Tests/GlobalRedirectTest.php b/src/Tests/GlobalRedirectTest.php
index c457f82..9696e2a 100644
--- a/src/Tests/GlobalRedirectTest.php
+++ b/src/Tests/GlobalRedirectTest.php
@@ -2,9 +2,7 @@
 
 namespace Drupal\redirect\Tests;
 
-use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Language\Language;
-use Drupal\simpletest\WebTestBase;
 use Drupal\language\Entity\ConfigurableLanguage;
 
 /**
@@ -12,7 +10,7 @@ use Drupal\language\Entity\ConfigurableLanguage;
  *
  * @group redirect
  */
-class GlobalRedirectTest extends WebTestBase {
+class GlobalRedirectTest extends RedirectTestBase {
 
   /**
    * Modules to enable.
@@ -235,42 +233,4 @@ class GlobalRedirectTest extends WebTestBase {
     // Test multilingual redirect.
     $this->assertRedirect('es/node/' . $spanish_node->id(), 'es/spanish-test-node');
   }
-
-  /**
-   * Asserts the redirect from $path to the $expected_ending_url.
-   *
-   * @param string $path
-   *   The request path.
-   * @param $expected_ending_url
-   *   The path where we expect it to redirect. If NULL value provided, no
-   *   redirect is expected.
-   * @param string $expected_ending_status
-   *   The status we expect to get with the first request.
-   */
-  public function assertRedirect($path, $expected_ending_url, $expected_ending_status = 'HTTP/1.1 301 Moved Permanently') {
-    $this->drupalHead($GLOBALS['base_url'] . '/' . $path);
-    $headers = $this->drupalGetHeaders(TRUE);
-
-    $ending_url = isset($headers[0]['location']) ? $headers[0]['location'] : NULL;
-    $message = SafeMarkup::format('Testing redirect from %from to %to. Ending url: %url', array(
-      '%from' => $path,
-      '%to' => $expected_ending_url,
-      '%url' => $ending_url,
-    ));
-
-
-    if ($expected_ending_url == '<front>') {
-      $expected_ending_url = $GLOBALS['base_url'] . '/';
-    }
-    elseif (!empty($expected_ending_url)) {
-      $expected_ending_url = $GLOBALS['base_url'] . '/' . $expected_ending_url;
-    }
-    else {
-      $expected_ending_url = NULL;
-    }
-
-    $this->assertEqual($expected_ending_url, $ending_url);
-
-    $this->assertEqual($headers[0][':status'], $expected_ending_status);
-  }
 }
diff --git a/tests/modules/redirect_test/redirect_test.module b/tests/modules/redirect_test/redirect_test.module
index 0bfe4b1..37cfd7f 100644
--- a/tests/modules/redirect_test/redirect_test.module
+++ b/tests/modules/redirect_test/redirect_test.module
@@ -9,9 +9,12 @@ use Drupal\redirect\Entity\Redirect;
 use Symfony\Component\HttpFoundation\RedirectResponse;
 
 /**
- * Implements hook_coffee_commands().
+ * Implements hook_redirect_response_alter().
  */
 function redirect_test_redirect_response_alter(RedirectResponse $response, Redirect $redirect) {
-  // @TODO: Need a condition maybe?
-  $response->setTrustedTargetUrl("http://drupal.org");
+  $path = 'test/redirect/2/successful';
+  $replace = 'test/redirect/other';
+  if ($redirect->getRedirect()['uri'] == "internal:/" . $path) {
+    $response->setTargetUrl(str_replace($path, $replace, $redirect->getRedirectUrl()->setAbsolute()->toString()));
+  }
 }
diff --git a/tests/src/Functional/RedirectHooksTest.php b/tests/src/Functional/RedirectHooksTest.php
index e8c0d00..578dd90 100644
--- a/tests/src/Functional/RedirectHooksTest.php
+++ b/tests/src/Functional/RedirectHooksTest.php
@@ -1,8 +1,8 @@
 <?php
 
-namespace Drupal\redirect\Tests;
+namespace Drupal\Tests\redirect\Functional;
 
-use Drupal\Tests\BrowserTestBase;
+use Drupal\redirect\Tests\RedirectTestBase;
 use Drupal\redirect\Entity\Redirect;
 
 /**
@@ -12,7 +12,7 @@ use Drupal\redirect\Entity\Redirect;
  *
  * @group redirect
  */
-class RedirectHooksTest extends BrowserTestBase {
+class RedirectHooksTest extends RedirectTestBase {
 
   /**
    * {@inheritdoc}
@@ -31,11 +31,16 @@ class RedirectHooksTest extends BrowserTestBase {
     parent::setUp();
 
     // Create two redirects.
-    $redirect = Redirect::create([
-      'redirect_source' => '/test/redirect/1',
-      'redirect_redirect' => '/test/redirect/1/successful',
-      'status_code' => '301',
-    ]);
+    $redirect = Redirect::create();
+    $redirect->setSource('/test/redirect/1');
+    $redirect->setRedirect('/test/redirect/1/successful');
+    $redirect->setStatusCode(301);
+    $redirect->save();
+
+    $redirect = Redirect::create();
+    $redirect->setSource('/test/redirect/2');
+    $redirect->setRedirect('/test/redirect/2/successful');
+    $redirect->setStatusCode(301);
     $redirect->save();
   }
 
@@ -43,47 +48,8 @@ class RedirectHooksTest extends BrowserTestBase {
    * Test the redirects.
    */
   public function testRedirectResponseHook() {
-    /*
-    // Test the description page at examples/hook-example returns a 200.
-    $this->drupalGet('examples/hooks-example');
-    $this->assertSession()->statusCodeEquals(200);
-
-    // Test that our implementation of hook_help() works.
-    $this->drupalGet('admin/help/hooks_example');
-    $this->assertSession()->statusCodeEquals(200);
-    $this->assertSession()->pageTextContains('This text is provided by the function hooks_example_help()');
-
-    // Test that our implementation of hook_node_view() works.
-    // Create a new node.
-    $settings = [
-      'type' => 'page',
-      'title' => t('Hooks Example Testing Node'),
-      'status' => 1,
-    ];
-    $node = $this->drupalCreateNode($settings);
-
-    $this->drupalGet($node->toUrl());
-
-    // Test that the output added to the page by hooks_example_node_view() is
-    // present. Which also tests that our page view counting was initialized.
-    $this->assertSession()->pageTextContains('You have viewed this node 1 times this session.');
-    // Tests that the message set by
-    // hooks_example_hooks_example_count_incremented() is displayed on the page.
-    // Which also has the effect of testing to see wehther or not our custom
-    // hook is being invoked.
-    $this->assertSession()->pageTextContains('This is the first time you have viewed the node ' . $node->label() . '.');
-
-    // Navigate to a new page, and then back and verify the counter was updated.
-    $this->drupalGet('<front>');
-    $this->drupalGet($node->toUrl());
-    $this->assertSession()->pageTextContains('You have viewed this node 2 times this session.');
-    $this->assertSession()->pageTextNotContains('This is the first time you have viewed the node ' . $node->label() . '.');
-
-    // Test our implementation of hook_form_alter().
-    $this->drupalLogout();
-    $this->drupalGet('user/login');
-    $this->assertSession()->pageTextContains('This text has been altered by hooks_example_form_alter().');
-    */
+    $this->assertRedirect('test/redirect/1', 'test/redirect/1/successful');
+    $this->assertRedirect('test/redirect/2', 'test/redirect/other');
   }
 
 }
