diff --git a/core/includes/batch.inc b/core/includes/batch.inc
index 1136220..c25f119 100644
--- a/core/includes/batch.inc
+++ b/core/includes/batch.inc
@@ -16,9 +16,11 @@
 
 use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Component\Utility\Timer;
+use Drupal\Component\Utility\UrlHelper;
 use Drupal\Core\Batch\Percentage;
 use Drupal\Core\Form\FormState;
 use Drupal\Core\Page\DefaultHtmlPageRenderer;
+use Drupal\Core\Url;
 use Symfony\Component\HttpFoundation\JsonResponse;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\RedirectResponse;
@@ -446,13 +448,12 @@ function _batch_finished() {
     if (!isset($_batch['form_state'])) {
       $_batch['form_state'] = new FormState();
     }
-    if (!isset($_batch['form_state']['redirect'])) {
-      if (isset($_batch['redirect'])) {
-        $_batch['form_state']['redirect'] = $_batch['redirect'];
-      }
-      else {
-        $_batch['form_state']['redirect'] = $_batch['source_url'];
-      }
+    if ($_batch['form_state']->getRedirect() === NULL) {
+      $redirect = $_batch['batch_redirect'] ?: $_batch['source_url'];
+      $options = UrlHelper::parse($redirect);
+      $redirect = Url::createFromPath($GLOBALS['base_url'] . '/' . $options['path']);
+      $redirect->setOptions($options);
+      $_batch['form_state']->setRedirectUrl($redirect);
     }
 
     // Use \Drupal\Core\Form\FormSubmitterInterface::redirectForm() to handle
diff --git a/core/includes/form.inc b/core/includes/form.inc
index 5a24e98..1b4a086 100644
--- a/core/includes/form.inc
+++ b/core/includes/form.inc
@@ -3066,7 +3066,7 @@ function batch_process($redirect = NULL, $url = 'batch', $redirect_callback = NU
       'url' => $url,
       'url_options' => array(),
       'source_url' => current_path(),
-      'redirect' => $redirect,
+      'batch_redirect' => $redirect,
       'theme' => $GLOBALS['theme_key'],
       'redirect_callback' => $redirect_callback,
     );
diff --git a/core/lib/Drupal/Core/Annotation/Action.php b/core/lib/Drupal/Core/Annotation/Action.php
index 0e4fd73..5d0937d 100644
--- a/core/lib/Drupal/Core/Annotation/Action.php
+++ b/core/lib/Drupal/Core/Annotation/Action.php
@@ -42,14 +42,13 @@ class Action extends Plugin {
   public $label;
 
   /**
-   * The path for a confirmation form for this action.
+   * The route name for a confirmation form for this action.
    *
-   * @todo Change this to accept a route.
    * @todo Provide a more generic way to allow an action to be confirmed first.
    *
    * @var string (optional)
    */
-  public $confirm_form_path = '';
+  public $confirm_form_route_name = '';
 
   /**
    * The entity type the action can apply to.
diff --git a/core/lib/Drupal/Core/Form/FormState.php b/core/lib/Drupal/Core/Form/FormState.php
index beef3b3..5e2be94 100644
--- a/core/lib/Drupal/Core/Form/FormState.php
+++ b/core/lib/Drupal/Core/Form/FormState.php
@@ -111,35 +111,27 @@ class FormState implements FormStateInterface, \ArrayAccess {
    * Used when a form needs to return some kind of a
    * \Symfony\Component\HttpFoundation\Response object, e.g., a
    * \Symfony\Component\HttpFoundation\BinaryFileResponse when triggering a
-   * file download. If you use the $form_state['redirect'] key, it will be used
-   * to build a \Symfony\Component\HttpFoundation\RedirectResponse and will
-   * populate this key.
+   * file download. If you use self::setRedirect() or self::setRedirectUrl(),
+   * it will be used to build a
+   * \Symfony\Component\HttpFoundation\RedirectResponse and will populate this
+   * key.
    *
    * @var \Symfony\Component\HttpFoundation\Response|null
    */
   protected $response;
 
   /**
-   * Used to redirect the form on submission. It may either be a  string
-   * containing the destination URL, or an array of arguments compatible with
-   * url(). See url() for complete information.
+   * Used to redirect the form on submission.
+   *
+   * @see self::getRedirect()
    *
    * This property is uncacheable.
    *
-   * @var string|array|null
+   * @var \Drupal\Core\Url|\Symfony\Component\HttpFoundation\RedirectResponse|null
    */
   protected $redirect;
 
   /**
-   * Used for route-based redirects.
-   *
-   * This property is uncacheable.
-   *
-   * @var \Drupal\Core\Url|array
-   */
-  protected $redirect_route;
-
-  /**
    * If set to TRUE the form will NOT perform a redirect, even if
    * self::$redirect is set.
    *
@@ -602,8 +594,16 @@ public function setResponse(Response $response) {
   /**
    * {@inheritdoc}
    */
-  public function setRedirect(Url $url) {
-    $this->set('redirect_route', $url);
+  public function setRedirect($route_name, array $route_parameters = array(), array $options = array()) {
+    $url = new Url($route_name, $route_parameters, $options);
+    return $this->setRedirectUrl($url);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setRedirectUrl(Url $url) {
+    $this->set('redirect', $url);
     return $this;
   }
 
@@ -625,22 +625,6 @@ public function getRedirect() {
       return FALSE;
     }
 
-    // Check for a route-based redirection.
-    if ($redirect_route = $this->get('redirect_route')) {
-      // @todo Remove once all redirects are converted to \Drupal\Core\Url. See
-      //   https://www.drupal.org/node/2189661.
-      if (!($redirect_route instanceof Url)) {
-        $redirect_route += array(
-          'route_parameters' => array(),
-          'options' => array(),
-        );
-        $redirect_route = new Url($redirect_route['route_name'], $redirect_route['route_parameters'], $redirect_route['options']);
-      }
-
-      $redirect_route->setAbsolute();
-      return $redirect_route;
-    }
-
     return $this->get('redirect');
   }
 
diff --git a/core/lib/Drupal/Core/Form/FormStateInterface.php b/core/lib/Drupal/Core/Form/FormStateInterface.php
index b635ce5..a24d28d 100644
--- a/core/lib/Drupal/Core/Form/FormStateInterface.php
+++ b/core/lib/Drupal/Core/Form/FormStateInterface.php
@@ -90,6 +90,23 @@ public function setIfNotExists($property, $value);
   public function setResponse(Response $response);
 
   /**
+   * Sets the redirect for the form.
+   *
+   * @param string $route_name
+   *   The name of the route
+   * @param array $route_parameters
+   *   (optional) An associative array of parameter names and values.
+   * @param array $options
+   *   (optional) An associative array of additional options. See
+   *   \Drupal\Core\Url for the available keys.
+   *
+   * @return $this
+   *
+   * @see \Drupal\Core\Form\FormSubmitterInterface::redirectForm()
+   */
+  public function setRedirect($route_name, array $route_parameters = array(), array $options = array());
+
+  /**
    * Sets the redirect URL for the form.
    *
    * @param \Drupal\Core\Url $url
@@ -99,7 +116,7 @@ public function setResponse(Response $response);
    *
    * @see \Drupal\Core\Form\FormSubmitterInterface::redirectForm()
    */
-  public function setRedirect(Url $url);
+  public function setRedirectUrl(Url $url);
 
   /**
    * Gets the value to use for redirecting after the form has been executed.
@@ -110,10 +127,6 @@ public function setRedirect(Url $url);
    *   The value will be one of the following:
    *   - A fully prepared \Symfony\Component\HttpFoundation\RedirectResponse.
    *   - An instance of \Drupal\Core\Url to use for the redirect.
-   *   - A numerically-indexed array where the first value is the path to use
-   *     for the redirect, and the optional second value is an array of options
-   *     for generating the URL from the path.
-   *   - The path to use for the redirect.
    *   - NULL, to signify that no redirect was specified and that the current
    *     path should be used for the redirect.
    *   - FALSE, to signify that no redirect should take place.
diff --git a/core/lib/Drupal/Core/Form/FormSubmitter.php b/core/lib/Drupal/Core/Form/FormSubmitter.php
index fb447a2..e99727e 100644
--- a/core/lib/Drupal/Core/Form/FormSubmitter.php
+++ b/core/lib/Drupal/Core/Form/FormSubmitter.php
@@ -127,10 +127,6 @@ public function executeSubmitHandlers(&$form, FormStateInterface &$form_state) {
    * {@inheritdoc}
    */
   public function redirectForm(FormStateInterface $form_state) {
-    // According to RFC 7231, 303 See Other status code must be used to redirect
-    // user agent (and not default 302 Found).
-    // @see http://tools.ietf.org/html/rfc7231#section-6.4.4
-    $status_code = Response::HTTP_SEE_OTHER;
     $redirect = $form_state->getRedirect();
 
     // Allow using redirect responses directly if needed.
@@ -141,35 +137,7 @@ public function redirectForm(FormStateInterface $form_state) {
     $url = NULL;
     // Check for a route-based redirection.
     if ($redirect instanceof Url) {
-      $url = $redirect->toString();
-    }
-    // An array contains the path to use for the redirect, as well as options to
-    // use for generating the URL.
-    elseif (is_array($redirect)) {
-      if (isset($redirect[1])) {
-        $options = $redirect[1];
-      }
-      else {
-        $options = array();
-      }
-      // Redirections should always use absolute URLs.
-      $options['absolute'] = TRUE;
-      if (isset($redirect[2])) {
-        $status_code = $redirect[2];
-      }
-      $url = $this->urlGenerator->generateFromPath($redirect[0], $options);
-    }
-    // A string represents the path to use for the redirect.
-    elseif (is_string($redirect)) {
-      // This function can be called from the installer, which guarantees
-      // that $redirect will always be a string, so catch that case here
-      // and use the appropriate redirect function.
-      if ($this->drupalInstallationAttempted()) {
-        install_goto($redirect);
-      }
-      else {
-        $url = $this->urlGenerator->generateFromPath($redirect, array('absolute' => TRUE));
-      }
+      $url = $redirect->setAbsolute()->toString();
     }
     // If no redirect was specified, redirect to the current path.
     elseif ($redirect === NULL) {
@@ -183,7 +151,10 @@ public function redirectForm(FormStateInterface $form_state) {
     }
 
     if ($url) {
-      return new RedirectResponse($url, $status_code);
+      // According to RFC 7231, 303 See Other status code must be used to redirect
+      // user agent (and not default 302 Found).
+      // @see http://tools.ietf.org/html/rfc7231#section-6.4.4
+      return new RedirectResponse($url, Response::HTTP_SEE_OTHER);
     }
   }
 
diff --git a/core/lib/Drupal/Core/Form/FormSubmitterInterface.php b/core/lib/Drupal/Core/Form/FormSubmitterInterface.php
index 8a79fe0..15ce4d2 100644
--- a/core/lib/Drupal/Core/Form/FormSubmitterInterface.php
+++ b/core/lib/Drupal/Core/Form/FormSubmitterInterface.php
@@ -49,21 +49,18 @@ public function executeSubmitHandlers(&$form, FormStateInterface &$form_state);
    * destination should be, based on the $form_state and the 'destination'
    * query string in the request URL, and redirects the user there.
    *
-   * Usually (for exceptions, see below) $form_state['redirect'] determines
-   * where to redirect the user. This can be set either to a string (the path to
-   * redirect to), or an array of arguments for url(). If
-   * $form_state['redirect'] is missing, the user is usually (again, see below
-   * for exceptions) redirected back to the page they came from, where they
-   * should see a fresh, unpopulated copy of the form.
+   * The result of \Drupal\Core\Form|FormStateInterface::getRedirect()
+   * determines where to redirect the user. See the possible return values
+   * listed there. If the result is FALSE, then the user will not be redirected.
    *
-   * Here is an example of how to set up a form to redirect to the path 'node':
+   * Here is an example of how to set up a form to redirect to the path 'user':
    * @code
-   * $form_state->set('redirect', 'node');
+   * $form_state->setRedirect('user.page');
    * @endcode
    * And here is an example of how to redirect to 'node/123?foo=bar#baz':
    * @code
-   * $form_state->set('redirect', array(
-   *   'node/123',
+   * $form_state->setRedirect('node.view',
+   *   array('node' => 123),
    *   array(
    *     'query' => array(
    *       'foo' => 'bar',
@@ -73,27 +70,7 @@ public function executeSubmitHandlers(&$form, FormStateInterface &$form_state);
    * ));
    * @endcode
    *
-   * There are several exceptions to the "usual" behavior described above:
-   * - If $form_state['programmed'] is TRUE, the form submission was usually
-   *   invoked via self::submitForm(), so any redirection would break the script
-   *   that invoked self::submitForm() and no redirection is done.
-   * - If $form_state['rebuild'] is TRUE, the form is being rebuilt, and no
-   *   redirection is done.
-   * - If $form_state['no_redirect'] is TRUE, redirection is disabled. This is
-   *   set, for instance, by \Drupal\system\FormAjaxController::getForm() to
-   *   prevent redirection in Ajax callbacks. $form_state['no_redirect'] should
-   *   never be set or altered by form builder functions or form validation
-   *   or submit handlers.
-   * - If $form_state['redirect'] is set to FALSE, redirection is disabled.
-   * - If none of the above conditions has prevented redirection, then the
-   *   redirect is accomplished by returning a RedirectResponse, passing in the
-   *   value of $form_state['redirect'] if it is set, or the current path if it
-   *   is not. RedirectResponse preferentially uses the value of
-   *   \Drupal::request->query->get('destination') (the 'destination' URL query
-   *   string) if it is present, so this will override any values set by
-   *   $form_state['redirect'].
-   *
-   * @param $form_state
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
    *   The current state of the form.
    *
    * @return \Symfony\Component\HttpFoundation\RedirectResponse|null
diff --git a/core/modules/action/src/ActionFormBase.php b/core/modules/action/src/ActionFormBase.php
index 23b7f07..88e78ad 100644
--- a/core/modules/action/src/ActionFormBase.php
+++ b/core/modules/action/src/ActionFormBase.php
@@ -150,9 +150,7 @@ public function save(array $form, FormStateInterface $form_state) {
     $this->entity->save();
     drupal_set_message($this->t('The action has been successfully saved.'));
 
-    $form_state['redirect_route'] = array(
-      'route_name' => 'action.admin',
-    );
+    $form_state->setRedirect('action.admin');
   }
 
 }
diff --git a/core/modules/action/src/Form/ActionAdminManageForm.php b/core/modules/action/src/Form/ActionAdminManageForm.php
index 81c08f4..192a81e 100644
--- a/core/modules/action/src/Form/ActionAdminManageForm.php
+++ b/core/modules/action/src/Form/ActionAdminManageForm.php
@@ -90,9 +90,9 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
     if ($form_state['values']['action']) {
-      $form_state['redirect_route'] = array(
-        'route_name' => 'action.admin_add',
-        'route_parameters' => array('action_id' => $form_state['values']['action']),
+      $form_state->setRedirect(
+        'action.admin_add',
+        array('action_id' => $form_state['values']['action'])
       );
     }
   }
diff --git a/core/modules/action/src/Form/ActionDeleteForm.php b/core/modules/action/src/Form/ActionDeleteForm.php
index 95b8ebb..0f89e3d 100644
--- a/core/modules/action/src/Form/ActionDeleteForm.php
+++ b/core/modules/action/src/Form/ActionDeleteForm.php
@@ -46,7 +46,7 @@ public function submit(array $form, FormStateInterface $form_state) {
     $this->logger('user')->notice('Deleted action %aid (%action)', array('%aid' => $this->entity->id(), '%action' => $this->entity->label()));
     drupal_set_message($this->t('Action %action was deleted', array('%action' => $this->entity->label())));
 
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/aggregator/src/FeedForm.php b/core/modules/aggregator/src/FeedForm.php
index 449564c..1832cb5 100644
--- a/core/modules/aggregator/src/FeedForm.php
+++ b/core/modules/aggregator/src/FeedForm.php
@@ -67,7 +67,7 @@ public function save(array $form, FormStateInterface $form_state) {
     $feed->save();
     if ($insert) {
       drupal_set_message($this->t('The feed %feed has been updated.', array('%feed' => $feed->label())));
-      $form_state['redirect_route'] = $feed->urlInfo('canonical');
+      $form_state->setRedirectUrl($feed->urlInfo('canonical'));
     }
     else {
       $this->logger('aggregator')->notice('Feed %feed added.', array('%feed' => $feed->label(), 'link' => l($this->t('View'), 'admin/config/services/aggregator')));
diff --git a/core/modules/aggregator/src/Form/FeedDeleteForm.php b/core/modules/aggregator/src/Form/FeedDeleteForm.php
index 6786544..eba206b 100644
--- a/core/modules/aggregator/src/Form/FeedDeleteForm.php
+++ b/core/modules/aggregator/src/Form/FeedDeleteForm.php
@@ -44,7 +44,7 @@ public function submit(array $form, FormStateInterface $form_state) {
     $this->entity->delete();
     $this->logger('aggregator')->notice('Feed %feed deleted.', array('%feed' => $this->entity->label()));
     drupal_set_message($this->t('The feed %feed has been deleted.', array('%feed' => $this->entity->label())));
-    $form_state['redirect_route'] = new Url('aggregator.sources');
+    $form_state->setRedirect('aggregator.sources');
   }
 
 }
diff --git a/core/modules/aggregator/src/Form/FeedItemsDeleteForm.php b/core/modules/aggregator/src/Form/FeedItemsDeleteForm.php
index 2d79aa2..8c02f85 100644
--- a/core/modules/aggregator/src/Form/FeedItemsDeleteForm.php
+++ b/core/modules/aggregator/src/Form/FeedItemsDeleteForm.php
@@ -43,7 +43,7 @@ public function getConfirmText() {
   public function submit(array $form, FormStateInterface $form_state) {
     $this->entity->deleteItems();
 
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/aggregator/src/Form/OpmlFeedAdd.php b/core/modules/aggregator/src/Form/OpmlFeedAdd.php
index 104dd3a..546b443 100644
--- a/core/modules/aggregator/src/Form/OpmlFeedAdd.php
+++ b/core/modules/aggregator/src/Form/OpmlFeedAdd.php
@@ -173,7 +173,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       $new_feed->save();
     }
 
-    $form_state['redirect_route']['route_name'] = 'aggregator.admin_overview';
+    $form_state->setRedirect('aggregator.admin_overview');
   }
 
   /**
diff --git a/core/modules/ban/src/Form/BanAdmin.php b/core/modules/ban/src/Form/BanAdmin.php
index 57216ee..19ea5d7 100644
--- a/core/modules/ban/src/Form/BanAdmin.php
+++ b/core/modules/ban/src/Form/BanAdmin.php
@@ -124,7 +124,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $ip = trim($form_state['values']['ip']);
     $this->ipManager->banIp($ip);
     drupal_set_message($this->t('The IP address %ip has been banned.', array('%ip' => $ip)));
-    $form_state['redirect_route']['route_name'] = 'ban.admin_page';
+    $form_state->setRedirect('ban.admin_page');
   }
 
 }
diff --git a/core/modules/ban/src/Form/BanDelete.php b/core/modules/ban/src/Form/BanDelete.php
index 2734540..08ca9a3 100644
--- a/core/modules/ban/src/Form/BanDelete.php
+++ b/core/modules/ban/src/Form/BanDelete.php
@@ -93,7 +93,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $this->ipManager->unbanIp($this->banIp);
     $this->logger('user')->notice('Deleted %ip', array('%ip' => $this->banIp));
     drupal_set_message($this->t('The IP address %ip was deleted.', array('%ip' => $this->banIp)));
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/block/src/BlockForm.php b/core/modules/block/src/BlockForm.php
index 704f3d1..ad19363 100644
--- a/core/modules/block/src/BlockForm.php
+++ b/core/modules/block/src/BlockForm.php
@@ -181,14 +181,12 @@ public function submit(array $form, FormStateInterface $form_state) {
     $entity->save();
 
     drupal_set_message($this->t('The block configuration has been saved.'));
-    $form_state['redirect_route'] = array(
-      'route_name' => 'block.admin_display_theme',
-      'route_parameters' => array(
+    $form_state->setRedirect(
+      'block.admin_display_theme',
+      array(
         'theme' => $form_state['values']['theme'],
       ),
-      'options' => array(
-        'query' => array('block-placement' => drupal_html_class($this->entity->id()))
-      ),
+      array('query' => array('block-placement' => drupal_html_class($this->entity->id())))
     );
   }
 
diff --git a/core/modules/block/src/Form/BlockDeleteForm.php b/core/modules/block/src/Form/BlockDeleteForm.php
index d811247..1567875 100644
--- a/core/modules/block/src/Form/BlockDeleteForm.php
+++ b/core/modules/block/src/Form/BlockDeleteForm.php
@@ -43,7 +43,7 @@ public function getConfirmText() {
   public function submit(array $form, FormStateInterface $form_state) {
     $this->entity->delete();
     drupal_set_message($this->t('The block %name has been removed.', array('%name' => $this->entity->label())));
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/block_content/src/BlockContentForm.php b/core/modules/block_content/src/BlockContentForm.php
index 71728d5..101f01b 100644
--- a/core/modules/block_content/src/BlockContentForm.php
+++ b/core/modules/block_content/src/BlockContentForm.php
@@ -215,16 +215,16 @@ public function save(array $form, FormStateInterface $form_state) {
         if (!$theme = $block->getTheme()) {
           $theme = $this->config('system.theme')->get('default');
         }
-        $form_state['redirect_route'] = array(
-          'route_name' => 'block.admin_add',
-          'route_parameters' => array(
+        $form_state->setRedirect(
+          'block.admin_add',
+          array(
             'plugin_id' => 'block_content:' . $block->uuid(),
             'theme' => $theme,
-          ),
+          )
         );
       }
       else {
-        $form_state['redirect_route']['route_name'] = 'block_content.list';
+        $form_state->setRedirect('block_content.list');
       }
     }
     else {
diff --git a/core/modules/block_content/src/BlockContentTypeForm.php b/core/modules/block_content/src/BlockContentTypeForm.php
index 93c86a3..0675657 100644
--- a/core/modules/block_content/src/BlockContentTypeForm.php
+++ b/core/modules/block_content/src/BlockContentTypeForm.php
@@ -103,7 +103,7 @@ public function save(array $form, FormStateInterface $form_state) {
       $logger->notice('Custom block type %label has been added.', array('%label' => $block_type->label(), 'link' => $edit_link));
     }
 
-    $form_state['redirect_route']['route_name'] = 'block_content.type_list';
+    $form_state->setRedirect('block_content.type_list');
   }
 
 }
diff --git a/core/modules/block_content/src/Form/BlockContentDeleteForm.php b/core/modules/block_content/src/Form/BlockContentDeleteForm.php
index 1fbb99a..d376ec1 100644
--- a/core/modules/block_content/src/Form/BlockContentDeleteForm.php
+++ b/core/modules/block_content/src/Form/BlockContentDeleteForm.php
@@ -58,7 +58,7 @@ public function submit(array $form, FormStateInterface $form_state) {
     $this->entity->delete();
     drupal_set_message($this->t('Custom block %label has been deleted.', array('%label' => $this->entity->label())));
     $this->logger('block_content')->notice('Custom block %label has been deleted.', array('%label' => $this->entity->label()));
-    $form_state['redirect_route'] = new Url('block_content.list');
+    $form_state->setRedirect('block_content.list');
   }
 
 }
diff --git a/core/modules/block_content/src/Form/BlockContentTypeDeleteForm.php b/core/modules/block_content/src/Form/BlockContentTypeDeleteForm.php
index b7c99a6..a1b9e9b 100644
--- a/core/modules/block_content/src/Form/BlockContentTypeDeleteForm.php
+++ b/core/modules/block_content/src/Form/BlockContentTypeDeleteForm.php
@@ -87,7 +87,7 @@ public function submit(array $form, FormStateInterface $form_state) {
     $this->entity->delete();
     drupal_set_message(t('Custom block type %label has been deleted.', array('%label' => $this->entity->label())));
     $this->logger('block_content')->notice('Custom block type %label has been deleted.', array('%label' => $this->entity->label()));
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/book/src/Form/BookOutlineForm.php b/core/modules/book/src/Form/BookOutlineForm.php
index 82a07aa..c4b435d 100644
--- a/core/modules/book/src/Form/BookOutlineForm.php
+++ b/core/modules/book/src/Form/BookOutlineForm.php
@@ -102,11 +102,9 @@ protected function actions(array $form, FormStateInterface $form_state) {
    * @see book_remove_button_submit()
    */
   public function submit(array $form, FormStateInterface $form_state) {
-    $form_state['redirect_route'] = array(
-      'route_name' => 'node.view',
-      'route_parameters' => array(
-        'node' => $this->entity->id(),
-      ),
+    $form_state->setRedirect(
+      'node.view',
+      array('node' => $this->entity->id())
     );
     $book_link = $form_state['values']['book'];
     if (!$book_link['bid']) {
@@ -119,7 +117,7 @@ public function submit(array $form, FormStateInterface $form_state) {
       if (isset($this->entity->book['parent_mismatch']) && $this->entity->book['parent_mismatch']) {
         // This will usually only happen when JS is disabled.
         drupal_set_message($this->t('The post has been added to the selected book. You may now position it relative to other pages.'));
-        $form_state['redirect_route'] = $this->entity->urlInfo('book-outline-form');
+        $form_state->setRedirectUrl($this->entity->urlInfo('book-outline-form'));
       }
       else {
         drupal_set_message($this->t('The book outline has been updated.'));
@@ -134,7 +132,7 @@ public function submit(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function delete(array $form, FormStateInterface $form_state) {
-    $form_state['redirect_route'] = $this->entity->urlInfo('book-remove-form');
+    $form_state->setRedirectUrl($this->entity->urlInfo('book-remove-form'));
   }
 
 }
diff --git a/core/modules/book/src/Form/BookRemoveForm.php b/core/modules/book/src/Form/BookRemoveForm.php
index 8ea7342..7623f5f 100644
--- a/core/modules/book/src/Form/BookRemoveForm.php
+++ b/core/modules/book/src/Form/BookRemoveForm.php
@@ -109,7 +109,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       $this->bookManager->deleteFromBook($this->node->id());
       drupal_set_message($this->t('The post has been removed from the book.'));
     }
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/comment/src/CommentForm.php b/core/modules/comment/src/CommentForm.php
index fc778d5..7b2eee8 100644
--- a/core/modules/comment/src/CommentForm.php
+++ b/core/modules/comment/src/CommentForm.php
@@ -403,6 +403,6 @@ public function save(array $form, FormStateInterface $form_state) {
       drupal_set_message($this->t('Comment: unauthorized comment submitted or comment submitted to a closed post %subject.', array('%subject' => $comment->getSubject())), 'error');
       // Redirect the user to the entity they are commenting on.
     }
-    $form_state['redirect_route'] = $uri;
+    $form_state->setRedirectUrl($uri);
   }
 }
diff --git a/core/modules/comment/src/CommentTypeForm.php b/core/modules/comment/src/CommentTypeForm.php
index 332e911..418aea1 100644
--- a/core/modules/comment/src/CommentTypeForm.php
+++ b/core/modules/comment/src/CommentTypeForm.php
@@ -147,7 +147,7 @@ public function save(array $form, FormStateInterface $form_state) {
       $this->logger->notice('Comment type %label has been added.', array('%label' => $comment_type->label(), 'link' =>  $edit_link));
     }
 
-    $form_state['redirect_route']['route_name'] = 'comment.type_list';
+    $form_state->setRedirect('comment.type_list');
   }
 
 }
diff --git a/core/modules/comment/src/Form/CommentAdminOverview.php b/core/modules/comment/src/Form/CommentAdminOverview.php
index 3876e7c..e65ac1a 100644
--- a/core/modules/comment/src/Form/CommentAdminOverview.php
+++ b/core/modules/comment/src/Form/CommentAdminOverview.php
@@ -281,9 +281,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       }
     }
     drupal_set_message($this->t('The update has been performed.'));
-    $form_state['redirect_route'] = array(
-      'route_name' => 'comment.admin',
-    );
+    $form_state->setRedirect('comment.admin');
   }
 
 }
diff --git a/core/modules/comment/src/Form/CommentTypeDeleteForm.php b/core/modules/comment/src/Form/CommentTypeDeleteForm.php
index 64da7c4..043aac4 100644
--- a/core/modules/comment/src/Form/CommentTypeDeleteForm.php
+++ b/core/modules/comment/src/Form/CommentTypeDeleteForm.php
@@ -143,7 +143,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    */
   public function submit(array $form, FormStateInterface $form_state) {
     $this->entity->delete();
-    $form_state['redirect_route']['route_name'] = 'comment.type_list';
+    $form_state->setRedirect('comment.type_list');
     drupal_set_message($this->t('Comment type %label has been deleted.', array('%label' => $this->entity->label())));
     $this->logger->notice('comment type %label has been deleted.', array('%label' => $this->entity->label()));
   }
diff --git a/core/modules/comment/src/Form/ConfirmDeleteMultiple.php b/core/modules/comment/src/Form/ConfirmDeleteMultiple.php
index fa3494c..c3a9b84 100644
--- a/core/modules/comment/src/Form/ConfirmDeleteMultiple.php
+++ b/core/modules/comment/src/Form/ConfirmDeleteMultiple.php
@@ -108,7 +108,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
 
     if (!$comment_counter) {
       drupal_set_message($this->t('There do not appear to be any comments to delete, or your selected comment was deleted by another administrator.'));
-      $form_state['redirect_route']['route_name'] = 'comment.admin';
+      $form_state->setRedirect('comment.admin');
     }
 
     return parent::buildForm($form, $form_state);
@@ -124,7 +124,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       $this->logger('content')->notice('Deleted @count comments.', array('@count' => $count));
       drupal_set_message(format_plural($count, 'Deleted 1 comment.', 'Deleted @count comments.'));
     }
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/comment/src/Form/DeleteForm.php b/core/modules/comment/src/Form/DeleteForm.php
index a6d01e8..1340f28 100644
--- a/core/modules/comment/src/Form/DeleteForm.php
+++ b/core/modules/comment/src/Form/DeleteForm.php
@@ -53,7 +53,7 @@ public function submit(array $form, FormStateInterface $form_state) {
     drupal_set_message($this->t('The comment and all its replies have been deleted.'));
     $this->logger('content')->notice('Deleted comment @cid and its replies.', array('@cid' => $this->entity->id()));
 
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/config/src/Form/ConfigExportForm.php b/core/modules/config/src/Form/ConfigExportForm.php
index e76a56c..6ecbba1 100644
--- a/core/modules/config/src/Form/ConfigExportForm.php
+++ b/core/modules/config/src/Form/ConfigExportForm.php
@@ -40,7 +40,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $form_state['redirect_route']['route_name'] = 'config.export_download';
+    $form_state->setRedirect('config.export_download');
   }
 
 }
diff --git a/core/modules/config/src/Form/ConfigImportForm.php b/core/modules/config/src/Form/ConfigImportForm.php
index 07db53f..4353684 100644
--- a/core/modules/config/src/Form/ConfigImportForm.php
+++ b/core/modules/config/src/Form/ConfigImportForm.php
@@ -98,7 +98,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
         }
         $archiver->extractList($files, config_get_config_directory(CONFIG_STAGING_DIRECTORY));
         drupal_set_message($this->t('Your configuration files were successfully uploaded, ready for import.'));
-        $form_state['redirect_route']['route_name'] = 'config.sync';
+        $form_state->setRedirect('config.sync');
       }
       catch (\Exception $e) {
         drupal_set_message($this->t('Could not extract the contents of the tar file. The error message is <em>@message</em>', array('@message' => $e->getMessage())), 'error');
diff --git a/core/modules/config/tests/config_test/src/ConfigTestForm.php b/core/modules/config/tests/config_test/src/ConfigTestForm.php
index cbe4c6f..cb847ee 100644
--- a/core/modules/config/tests/config_test/src/ConfigTestForm.php
+++ b/core/modules/config/tests/config_test/src/ConfigTestForm.php
@@ -81,7 +81,7 @@ public function save(array $form, FormStateInterface $form_state) {
       drupal_set_message(format_string('%label configuration has been created.', array('%label' => $entity->label())));
     }
 
-    $form_state['redirect_route']['route_name'] = 'config_test.list_page';
+    $form_state->setRedirect('config_test.list_page');
   }
 
 }
diff --git a/core/modules/config/tests/config_test/src/Form/ConfigTestDeleteForm.php b/core/modules/config/tests/config_test/src/Form/ConfigTestDeleteForm.php
index d344a4e..b203008 100644
--- a/core/modules/config/tests/config_test/src/Form/ConfigTestDeleteForm.php
+++ b/core/modules/config/tests/config_test/src/Form/ConfigTestDeleteForm.php
@@ -43,7 +43,7 @@ public function getCancelUrl() {
   public function submit(array $form, FormStateInterface $form_state) {
     $this->entity->delete();
     drupal_set_message(String::format('%label configuration has been deleted.', array('%label' => $this->entity->label())));
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/config_translation/src/Form/ConfigTranslationDeleteForm.php b/core/modules/config_translation/src/Form/ConfigTranslationDeleteForm.php
index fc9c730..d4c18a4 100644
--- a/core/modules/config_translation/src/Form/ConfigTranslationDeleteForm.php
+++ b/core/modules/config_translation/src/Form/ConfigTranslationDeleteForm.php
@@ -147,7 +147,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
 
     drupal_set_message($this->t('@language translation of %label was deleted', array('%label' => $this->mapper->getTitle(), '@language' => $this->language->name)));
 
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/config_translation/src/Form/ConfigTranslationFormBase.php b/core/modules/config_translation/src/Form/ConfigTranslationFormBase.php
index 29ed2c9..528158e 100644
--- a/core/modules/config_translation/src/Form/ConfigTranslationFormBase.php
+++ b/core/modules/config_translation/src/Form/ConfigTranslationFormBase.php
@@ -242,9 +242,9 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     }
     $config_factory->setOverrideState($old_state);
 
-    $form_state['redirect_route'] = array(
-      'route_name' => $this->mapper->getOverviewRoute(),
-      'route_parameters' => $this->mapper->getOverviewRouteParameters(),
+    $form_state->setRedirect(
+      $this->mapper->getOverviewRoute(),
+      $this->mapper->getOverviewRouteParameters()
     );
   }
 
diff --git a/core/modules/contact/src/CategoryForm.php b/core/modules/contact/src/CategoryForm.php
index 5403c65..e722cda 100644
--- a/core/modules/contact/src/CategoryForm.php
+++ b/core/modules/contact/src/CategoryForm.php
@@ -120,7 +120,7 @@ public function save(array $form, FormStateInterface $form_state) {
         ->save();
     }
 
-    $form_state['redirect_route']['route_name'] = 'contact.category_list';
+    $form_state->setRedirect('contact.category_list');
   }
 
 }
diff --git a/core/modules/contact/src/Form/CategoryDeleteForm.php b/core/modules/contact/src/Form/CategoryDeleteForm.php
index aca9161..cd534d4 100644
--- a/core/modules/contact/src/Form/CategoryDeleteForm.php
+++ b/core/modules/contact/src/Form/CategoryDeleteForm.php
@@ -44,7 +44,7 @@ public function submit(array $form, FormStateInterface $form_state) {
     $this->entity->delete();
     drupal_set_message($this->t('Category %label has been deleted.', array('%label' => $this->entity->label())));
     $this->logger('contact')->notice('Category %label has been deleted.', array('%label' => $this->entity->label()));
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/contact/src/MessageForm.php b/core/modules/contact/src/MessageForm.php
index 69c804a..2e7bd71 100644
--- a/core/modules/contact/src/MessageForm.php
+++ b/core/modules/contact/src/MessageForm.php
@@ -258,10 +258,10 @@ public function save(array $form, FormStateInterface $form_state) {
     // To avoid false error messages caused by flood control, redirect away from
     // the contact form; either to the contacted user account or the front page.
     if ($message->isPersonal() && $user->hasPermission('access user profiles')) {
-      $form_state['redirect_route'] = $message->getPersonalRecipient()->urlInfo();
+      $form_state->setRedirectUrl($message->getPersonalRecipient()->urlInfo());
     }
     else {
-      $form_state['redirect_route']['route_name'] = '<front>';
+      $form_state->setRedirect('<front>');
     }
     // Save the message. In core this is a no-op but should contrib wish to
     // implement message storage, this will make the task of swapping in a real
diff --git a/core/modules/content_translation/src/ContentTranslationHandler.php b/core/modules/content_translation/src/ContentTranslationHandler.php
index d7601e7..b1b7cc0 100644
--- a/core/modules/content_translation/src/ContentTranslationHandler.php
+++ b/core/modules/content_translation/src/ContentTranslationHandler.php
@@ -435,8 +435,12 @@ public function entityFormSourceChange($form, FormStateInterface $form_state) {
     $entity = $form_controller->getEntity();
     $source = $form_state['values']['source_langcode']['source'];
 
-    $path = $entity->getSystemPath('drupal:content-translation-overview');
-    $form_state['redirect'] = $path . '/add/' . $source . '/' . $form_controller->getFormLangcode($form_state);
+    $entity_type_id = $entity->getEntityTypeId();
+    $form_state->setRedirect('content_translation.translation_add_' . $entity_type_id, array(
+      $entity_type_id => $entity->id(),
+      'source' => $source,
+      'target' => $form_controller->getFormLangcode($form_state),
+    ));
     $languages = language_list();
     drupal_set_message(t('Source language set to: %language', array('%language' => $languages[$source]->name)));
   }
@@ -462,9 +466,11 @@ function entityFormDelete($form, FormStateInterface $form_state) {
   function entityFormDeleteTranslation($form, FormStateInterface $form_state) {
     $form_controller = content_translation_form_controller($form_state);
     $entity = $form_controller->getEntity();
-    $path = $entity->getSystemPath('drupal:content-translation-overview');
-    $form_langcode = $form_controller->getFormLangcode($form_state);
-    $form_state['redirect'] = $path . '/delete/' . $form_langcode;
+    $entity_type_id = $entity->getEntityTypeId();
+    $form_state->setRedirect('content_translation.delete_' . $entity_type_id, array(
+      $entity_type_id => $entity->id(),
+      'language' => $form_controller->getFormLangcode($form_state),
+    ));
   }
 
   /**
diff --git a/core/modules/content_translation/src/Form/ContentTranslationDeleteForm.php b/core/modules/content_translation/src/Form/ContentTranslationDeleteForm.php
index a265124..c27b5e8 100644
--- a/core/modules/content_translation/src/Form/ContentTranslationDeleteForm.php
+++ b/core/modules/content_translation/src/Form/ContentTranslationDeleteForm.php
@@ -83,7 +83,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       \Drupal::service('path.alias_storage')->delete($conditions);
     }
 
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/dblog/src/Form/DblogClearLogConfirmForm.php b/core/modules/dblog/src/Form/DblogClearLogConfirmForm.php
index d2b6a89..1f43ef1 100644
--- a/core/modules/dblog/src/Form/DblogClearLogConfirmForm.php
+++ b/core/modules/dblog/src/Form/DblogClearLogConfirmForm.php
@@ -72,7 +72,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $_SESSION['dblog_overview_filter'] = array();
     $this->connection->delete('watchdog')->execute();
     drupal_set_message($this->t('Database log cleared.'));
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/dblog/src/Form/DblogClearLogForm.php b/core/modules/dblog/src/Form/DblogClearLogForm.php
index f3781d4..e647ca4 100644
--- a/core/modules/dblog/src/Form/DblogClearLogForm.php
+++ b/core/modules/dblog/src/Form/DblogClearLogForm.php
@@ -10,7 +10,6 @@
 use Drupal\Core\Database\Connection;
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Url;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -71,7 +70,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $form_state['redirect_route'] = new Url('dblog.confirm');
+    $form_state->setRedirect('dblog.confirm');
   }
 
 }
diff --git a/core/modules/entity/src/Form/EntityDisplayModeDeleteForm.php b/core/modules/entity/src/Form/EntityDisplayModeDeleteForm.php
index b76d56b..95e535f 100644
--- a/core/modules/entity/src/Form/EntityDisplayModeDeleteForm.php
+++ b/core/modules/entity/src/Form/EntityDisplayModeDeleteForm.php
@@ -56,7 +56,7 @@ public function submit(array $form, FormStateInterface $form_state) {
     drupal_set_message(t('Deleted the %label @entity-type.', array('%label' => $this->entity->label(), '@entity-type' => $entity_type->getLowercaseLabel())));
     $this->entity->delete();
     \Drupal::entityManager()->clearCachedFieldDefinitions();
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/entity/src/Form/EntityDisplayModeFormBase.php b/core/modules/entity/src/Form/EntityDisplayModeFormBase.php
index 52e3388..11b39e5 100644
--- a/core/modules/entity/src/Form/EntityDisplayModeFormBase.php
+++ b/core/modules/entity/src/Form/EntityDisplayModeFormBase.php
@@ -125,7 +125,7 @@ public function save(array $form, FormStateInterface $form_state) {
     drupal_set_message(t('Saved the %label @entity-type.', array('%label' => $this->entity->label(), '@entity-type' => $this->entityType->getLowercaseLabel())));
     $this->entity->save();
     \Drupal::entityManager()->clearCachedFieldDefinitions();
-    $form_state['redirect_route']['route_name'] = 'entity.' . $this->entity->getEntityTypeId() . '_list';
+    $form_state->setRedirect('entity.' . $this->entity->getEntityTypeId() . '_list');
   }
 
 }
diff --git a/core/modules/field_ui/field_ui.module b/core/modules/field_ui/field_ui.module
index 7179a3a..400fb21 100644
--- a/core/modules/field_ui/field_ui.module
+++ b/core/modules/field_ui/field_ui.module
@@ -201,7 +201,7 @@ function field_ui_entity_operation(EntityInterface $entity) {
  */
 function field_ui_form_node_type_form_submit($form, FormStateInterface $form_state) {
   if ($form_state['triggering_element']['#parents'][0] === 'save_continue' && $route_info = FieldUI::getOverviewRouteInfo('node', $form_state['values']['type'])) {
-    $form_state['redirect_route'] = $route_info;
+    $form_state->setRedirectUrl($route_info);
   }
 }
 
diff --git a/core/modules/field_ui/src/FieldOverview.php b/core/modules/field_ui/src/FieldOverview.php
index 2000a9d..04c9805 100644
--- a/core/modules/field_ui/src/FieldOverview.php
+++ b/core/modules/field_ui/src/FieldOverview.php
@@ -478,7 +478,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     if ($destinations) {
       $destination = drupal_get_destination();
       $destinations[] = $destination['destination'];
-      $form_state['redirect_route'] = FieldUI::getNextDestination($destinations, $form_state);
+      $form_state->setRedirectUrl(FieldUI::getNextDestination($destinations, $form_state));
     }
     elseif (!$error) {
       drupal_set_message($this->t('Your settings have been saved.'));
diff --git a/core/modules/field_ui/src/FieldUI.php b/core/modules/field_ui/src/FieldUI.php
index 39ad937..bd18010 100644
--- a/core/modules/field_ui/src/FieldUI.php
+++ b/core/modules/field_ui/src/FieldUI.php
@@ -41,20 +41,25 @@ public static function getOverviewRouteInfo($entity_type_id, $bundle) {
    * @param array $destinations
    *   An array of destinations to redirect to.
    *
-   * @return array
+   * @return \Drupal\Core\Url
    *   The next destination to redirect to.
    */
   public static function getNextDestination(array $destinations) {
     $next_destination = array_shift($destinations);
     if (is_array($next_destination)) {
       $next_destination['options']['query']['destinations'] = $destinations;
+      $next_destination += array(
+        'route_parameters' => array(),
+      );
+      $next_destination = new Url($next_destination['route_name'], $next_destination['route_parameters'], $next_destination['options']);
     }
     else {
       $options = UrlHelper::parse($next_destination);
       if ($destinations) {
         $options['query']['destinations'] = $destinations;
       }
-      $next_destination = array($options['path'], $options);
+      $next_destination = Url::createFromPath($options['path']);
+      $next_destination->setOptions($options);
     }
     return $next_destination;
   }
diff --git a/core/modules/field_ui/src/Form/FieldInstanceConfigDeleteForm.php b/core/modules/field_ui/src/Form/FieldInstanceConfigDeleteForm.php
index 940d991..97470db 100644
--- a/core/modules/field_ui/src/Form/FieldInstanceConfigDeleteForm.php
+++ b/core/modules/field_ui/src/Form/FieldInstanceConfigDeleteForm.php
@@ -81,7 +81,7 @@ public function submit(array $form, FormStateInterface $form_state) {
       drupal_set_message($this->t('There was a problem removing the %field from the %type content type.', array('%field' => $this->entity->label(), '%type' => $bundle_label)), 'error');
     }
 
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
 
     // Fields are purged on cron. However field module prevents disabling modules
     // when field types they provided are used in a field until it is fully
diff --git a/core/modules/field_ui/src/Form/FieldInstanceEditForm.php b/core/modules/field_ui/src/Form/FieldInstanceEditForm.php
index b03fd16..08bb37b 100644
--- a/core/modules/field_ui/src/Form/FieldInstanceEditForm.php
+++ b/core/modules/field_ui/src/Form/FieldInstanceEditForm.php
@@ -195,15 +195,10 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $request = $this->getRequest();
     if (($destinations = $request->query->get('destinations')) && $next_destination = FieldUI::getNextDestination($destinations)) {
       $request->query->remove('destinations');
-      if (isset($next_destination['route_name'])) {
-        $form_state['redirect_route'] = $next_destination;
-      }
-      else {
-        $form_state['redirect'] = $next_destination;
-      }
+      $form_state->setRedirectUrl($next_destination);
     }
     else {
-      $form_state['redirect_route'] = FieldUI::getOverviewRouteInfo($this->instance->entity_type, $this->instance->bundle);
+      $form_state->setRedirectUrl(FieldUI::getOverviewRouteInfo($this->instance->entity_type, $this->instance->bundle));
     }
   }
 
@@ -218,15 +213,13 @@ public function delete(array &$form, FormStateInterface $form_state) {
       $request->query->remove('destination');
     }
     $entity_type = $this->entityManager->getDefinition($this->instance->entity_type);
-    $form_state['redirect_route'] = array(
-      'route_name' => 'field_ui.delete_' . $this->instance->entity_type,
-      'route_parameters' => array(
+    $form_state->setRedirect(
+      'field_ui.delete_' . $this->instance->entity_type,
+      array(
         $entity_type->getBundleEntityType() => $this->instance->bundle,
         'field_instance_config' => $this->instance->id(),
       ),
-      'options' => array(
-        'query' => $destination,
-      ),
+      array('query' => $destination)
     );
   }
 
diff --git a/core/modules/field_ui/src/Form/FieldStorageEditForm.php b/core/modules/field_ui/src/Form/FieldStorageEditForm.php
index c2b4883..8130670 100644
--- a/core/modules/field_ui/src/Form/FieldStorageEditForm.php
+++ b/core/modules/field_ui/src/Form/FieldStorageEditForm.php
@@ -198,15 +198,10 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       $request = $this->getRequest();
       if (($destinations = $request->query->get('destinations')) && $next_destination = FieldUI::getNextDestination($destinations)) {
         $request->query->remove('destinations');
-        if (isset($next_destination['route_name'])) {
-          $form_state['redirect_route'] = $next_destination;
-        }
-        else {
-          $form_state['redirect'] = $next_destination;
-        }
+        $form_state->setRedirectUrl($next_destination);
       }
       else {
-        $form_state['redirect_route'] = FieldUI::getOverviewRouteInfo($this->instance->entity_type, $this->instance->bundle);
+        $form_state->setRedirectUrl(FieldUI::getOverviewRouteInfo($this->instance->entity_type, $this->instance->bundle));
       }
     }
     catch (\Exception $e) {
diff --git a/core/modules/file/file.module b/core/modules/file/file.module
index a48a7a7..a71340d 100644
--- a/core/modules/file/file.module
+++ b/core/modules/file/file.module
@@ -1418,7 +1418,7 @@ function file_managed_file_submit($form, FormStateInterface $form_state) {
   // Set the form to rebuild so that $form is correctly updated in response to
   // processing the file removal. Since this function did not change $form_state
   // if the upload button was clicked, a rebuild isn't necessary in that
-  // situation and setting $form_state['redirect'] to FALSE would suffice.
+  // situation and setting $form_state['no_redirect'] to TRUE would suffice.
   // However, we choose to always rebuild, to keep the form processing workflow
   // consistent between the two buttons.
   $form_state['rebuild'] = TRUE;
diff --git a/core/modules/filter/src/FilterFormatFormBase.php b/core/modules/filter/src/FilterFormatFormBase.php
index ba19896..28ec4da 100644
--- a/core/modules/filter/src/FilterFormatFormBase.php
+++ b/core/modules/filter/src/FilterFormatFormBase.php
@@ -258,7 +258,7 @@ public function submit(array $form, FormStateInterface $form_state) {
       }
     }
 
-    $form_state['redirect_route']['route_name'] = 'filter.admin_overview';
+    $form_state->setRedirect('filter.admin_overview');
 
     return $this->entity;
   }
diff --git a/core/modules/filter/src/Form/FilterDisableForm.php b/core/modules/filter/src/Form/FilterDisableForm.php
index a6b7b88..25b64c0 100644
--- a/core/modules/filter/src/Form/FilterDisableForm.php
+++ b/core/modules/filter/src/Form/FilterDisableForm.php
@@ -51,7 +51,7 @@ public function submit(array $form, FormStateInterface $form_state) {
     $this->entity->disable()->save();
     drupal_set_message($this->t('Disabled text format %format.', array('%format' => $this->entity->label())));
 
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/forum/src/Form/DeleteForm.php b/core/modules/forum/src/Form/DeleteForm.php
index ddde478..1c73319 100644
--- a/core/modules/forum/src/Form/DeleteForm.php
+++ b/core/modules/forum/src/Form/DeleteForm.php
@@ -68,7 +68,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $this->taxonomyTerm->delete();
     drupal_set_message($this->t('The forum %label and all sub-forums have been deleted.', array('%label' => $this->taxonomyTerm->label())));
     $this->logger('forum')->notice('forum: deleted %label and all its sub-forums.', array('%label' => $this->taxonomyTerm->label()));
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/forum/src/Form/ForumForm.php b/core/modules/forum/src/Form/ForumForm.php
index 4290452..67e2398 100644
--- a/core/modules/forum/src/Form/ForumForm.php
+++ b/core/modules/forum/src/Form/ForumForm.php
@@ -92,7 +92,7 @@ public function save(array $form, FormStateInterface $form_state) {
         break;
     }
 
-    $form_state['redirect_route']['route_name'] = 'forum.overview';
+    $form_state->setRedirect('forum.overview');
     return $term;
   }
 
diff --git a/core/modules/image/src/Form/ImageEffectDeleteForm.php b/core/modules/image/src/Form/ImageEffectDeleteForm.php
index 761fd21..18e9cd3 100644
--- a/core/modules/image/src/Form/ImageEffectDeleteForm.php
+++ b/core/modules/image/src/Form/ImageEffectDeleteForm.php
@@ -74,7 +74,7 @@ public function buildForm(array $form, FormStateInterface $form_state, ImageStyl
   public function submitForm(array &$form, FormStateInterface $form_state) {
     $this->imageStyle->deleteImageEffect($this->imageEffect);
     drupal_set_message($this->t('The image effect %name has been deleted.', array('%name' => $this->imageEffect->label())));
-    $form_state['redirect_route'] = $this->imageStyle->urlInfo('edit-form');
+    $form_state->setRedirectUrl($this->imageStyle->urlInfo('edit-form'));
   }
 
 }
diff --git a/core/modules/image/src/Form/ImageEffectFormBase.php b/core/modules/image/src/Form/ImageEffectFormBase.php
index 6f3268e..ef3e677 100644
--- a/core/modules/image/src/Form/ImageEffectFormBase.php
+++ b/core/modules/image/src/Form/ImageEffectFormBase.php
@@ -136,7 +136,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $this->imageStyle->save();
 
     drupal_set_message($this->t('The image effect was successfully applied.'));
-    $form_state['redirect_route'] = $this->imageStyle->urlInfo('edit-form');
+    $form_state->setRedirectUrl($this->imageStyle->urlInfo('edit-form'));
   }
 
   /**
diff --git a/core/modules/image/src/Form/ImageStyleDeleteForm.php b/core/modules/image/src/Form/ImageStyleDeleteForm.php
index 41ca653..2723599 100644
--- a/core/modules/image/src/Form/ImageStyleDeleteForm.php
+++ b/core/modules/image/src/Form/ImageStyleDeleteForm.php
@@ -66,7 +66,7 @@ public function submit(array $form, FormStateInterface $form_state) {
     $this->entity->set('replacementID', $form_state['values']['replacement']);
     $this->entity->delete();
     drupal_set_message($this->t('Style %name was deleted.', array('%name' => $this->entity->label())));
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/image/src/Form/ImageStyleEditForm.php b/core/modules/image/src/Form/ImageStyleEditForm.php
index ef4f7de..99f766c 100644
--- a/core/modules/image/src/Form/ImageStyleEditForm.php
+++ b/core/modules/image/src/Form/ImageStyleEditForm.php
@@ -186,15 +186,13 @@ public function effectSave($form, FormStateInterface $form_state) {
 
     // Load the configuration form for this option.
     if (is_subclass_of($effect['class'], '\Drupal\image\ConfigurableImageEffectInterface')) {
-      $form_state['redirect_route'] = array(
-        'route_name' => 'image.effect_add_form',
-        'route_parameters' => array(
+      $form_state->setRedirect(
+        'image.effect_add_form',
+        array(
           'image_style' => $this->entity->id(),
           'image_effect' => $form_state['values']['new'],
         ),
-        'options' => array(
-          'query' => array('weight' => $form_state['values']['weight']),
-        ),
+        array('query' => array('weight' => $form_state['values']['weight']))
       );
     }
     // If there's no form, immediately add the image effect.
diff --git a/core/modules/image/src/Form/ImageStyleFlushForm.php b/core/modules/image/src/Form/ImageStyleFlushForm.php
index 5212ba0..6fcaf2d 100644
--- a/core/modules/image/src/Form/ImageStyleFlushForm.php
+++ b/core/modules/image/src/Form/ImageStyleFlushForm.php
@@ -50,7 +50,7 @@ public function getCancelUrl() {
   public function submit(array $form, FormStateInterface $form_state) {
     $this->entity->flush();
     drupal_set_message($this->t('The image style %name has been flushed.', array('%name' => $this->entity->label())));
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/image/src/Form/ImageStyleFormBase.php b/core/modules/image/src/Form/ImageStyleFormBase.php
index ad4ce5c..af35482 100644
--- a/core/modules/image/src/Form/ImageStyleFormBase.php
+++ b/core/modules/image/src/Form/ImageStyleFormBase.php
@@ -78,7 +78,7 @@ public function form(array $form, FormStateInterface $form_state) {
    */
   public function save(array $form, FormStateInterface $form_state) {
     $this->entity->save();
-    $form_state['redirect_route'] = $this->entity->urlInfo('edit-form');
+    $form_state->setRedirectUrl($this->entity->urlInfo('edit-form'));
   }
 
 }
diff --git a/core/modules/language/src/Form/LanguageAddForm.php b/core/modules/language/src/Form/LanguageAddForm.php
index facbd5d..1e9cca9 100644
--- a/core/modules/language/src/Form/LanguageAddForm.php
+++ b/core/modules/language/src/Form/LanguageAddForm.php
@@ -104,7 +104,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     // Tell the user they have the option to add a language switcher block
     // to their theme so they can switch between the languages.
     drupal_set_message($this->t('Use one of the language switcher blocks to allow site visitors to switch between languages. You can enable these blocks on the <a href="@block-admin">block administration page</a>.', array('@block-admin' => url('admin/structure/block'))));
-    $form_state['redirect_route']['route_name'] = 'language.admin_overview';
+    $form_state->setRedirect('language.admin_overview');
   }
 
   /**
diff --git a/core/modules/language/src/Form/LanguageDeleteForm.php b/core/modules/language/src/Form/LanguageDeleteForm.php
index db158e0..26c83a2 100644
--- a/core/modules/language/src/Form/LanguageDeleteForm.php
+++ b/core/modules/language/src/Form/LanguageDeleteForm.php
@@ -115,7 +115,7 @@ public function submit(array $form, FormStateInterface $form_state) {
       drupal_set_message($this->t('The %language (%langcode) language has been removed.', array('%language' => $this->entity->label(), '%langcode' => $this->entity->id())));
     }
 
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/language/src/Form/LanguageEditForm.php b/core/modules/language/src/Form/LanguageEditForm.php
index f5d7498..c1f1cf8 100644
--- a/core/modules/language/src/Form/LanguageEditForm.php
+++ b/core/modules/language/src/Form/LanguageEditForm.php
@@ -56,7 +56,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $language->direction = $form_state['values']['direction'];
     language_save($language);
 
-    $form_state['redirect_route']['route_name'] = 'language.admin_overview';
+    $form_state->setRedirect('language.admin_overview');
   }
 
 }
diff --git a/core/modules/language/src/Form/NegotiationBrowserDeleteForm.php b/core/modules/language/src/Form/NegotiationBrowserDeleteForm.php
index 43fd8b4..0c0a447 100644
--- a/core/modules/language/src/Form/NegotiationBrowserDeleteForm.php
+++ b/core/modules/language/src/Form/NegotiationBrowserDeleteForm.php
@@ -67,7 +67,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       language_set_browser_drupal_langcode_mappings($mappings);
     }
 
-    $form_state['redirect_route']['route_name'] = 'language.negotiation_browser';
+    $form_state->setRedirect('language.negotiation_browser');
   }
 
 }
diff --git a/core/modules/language/src/Form/NegotiationBrowserForm.php b/core/modules/language/src/Form/NegotiationBrowserForm.php
index 4c65e45..73509e0 100644
--- a/core/modules/language/src/Form/NegotiationBrowserForm.php
+++ b/core/modules/language/src/Form/NegotiationBrowserForm.php
@@ -175,7 +175,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       $config->setData($mappings);
       $config->save();
     }
-    $form_state['redirect_route']['route_name'] = 'language.negotiation';
+    $form_state->setRedirect('language.negotiation');
 
     parent::submitForm($form, $form_state);
   }
diff --git a/core/modules/language/src/Form/NegotiationConfigureForm.php b/core/modules/language/src/Form/NegotiationConfigureForm.php
index afc39aa..191e08d 100644
--- a/core/modules/language/src/Form/NegotiationConfigureForm.php
+++ b/core/modules/language/src/Form/NegotiationConfigureForm.php
@@ -174,7 +174,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       $this->blockManager->clearCachedDefinitions();
     }
 
-    $form_state['redirect_route']['route_name'] = 'language.negotiation';
+    $form_state->setRedirect('language.negotiation');
     drupal_set_message($this->t('Language negotiation configuration saved.'));
   }
 
diff --git a/core/modules/language/src/Form/NegotiationSessionForm.php b/core/modules/language/src/Form/NegotiationSessionForm.php
index ef4cb3d..92c6dd4 100644
--- a/core/modules/language/src/Form/NegotiationSessionForm.php
+++ b/core/modules/language/src/Form/NegotiationSessionForm.php
@@ -34,7 +34,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#description' => t('Name of the request/session parameter used to determine the desired language.'),
     );
 
-    $form_state['redirect_route']['route_name'] = 'language.negotiation';
+    $form_state->setRedirect('language.negotiation');
 
     return parent::buildForm($form, $form_state);
   }
diff --git a/core/modules/language/src/Form/NegotiationUrlForm.php b/core/modules/language/src/Form/NegotiationUrlForm.php
index 403c4a1..91a5c0a 100644
--- a/core/modules/language/src/Form/NegotiationUrlForm.php
+++ b/core/modules/language/src/Form/NegotiationUrlForm.php
@@ -89,7 +89,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       );
     }
 
-    $form_state['redirect_route']['route_name'] = 'language.negotiation';
+    $form_state->setRedirect('language.negotiation');
 
     return parent::buildForm($form, $form_state);
   }
diff --git a/core/modules/locale/src/Form/ImportForm.php b/core/modules/locale/src/Form/ImportForm.php
index e8d5ac6..0a41461 100644
--- a/core/modules/locale/src/Form/ImportForm.php
+++ b/core/modules/locale/src/Form/ImportForm.php
@@ -190,6 +190,6 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $batch = locale_translate_batch_build(array($file->uri => $file), $options);
     batch_set($batch);
 
-    $form_state['redirect_route']['route_name'] = 'locale.translate_page';
+    $form_state->setRedirect('locale.translate_page');
   }
 }
diff --git a/core/modules/locale/src/Form/TranslateEditForm.php b/core/modules/locale/src/Form/TranslateEditForm.php
index c29f2bc..ef49ce7 100644
--- a/core/modules/locale/src/Form/TranslateEditForm.php
+++ b/core/modules/locale/src/Form/TranslateEditForm.php
@@ -230,11 +230,10 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     // Keep the user on the current pager page.
     $page = $this->getRequest()->query->get('page');
     if (isset($page)) {
-      $form_state['redirect_route'] = array(
-        'route_name' => 'locale.translate_page',
-        'options' => array(
-          'page' => $page,
-        ),
+      $form_state->setRedirect(
+        'locale.translate_page',
+        array(),
+        array('page' => $page)
       );
     }
 
diff --git a/core/modules/locale/src/Form/TranslateFilterForm.php b/core/modules/locale/src/Form/TranslateFilterForm.php
index a9be9f5..176afff 100644
--- a/core/modules/locale/src/Form/TranslateFilterForm.php
+++ b/core/modules/locale/src/Form/TranslateFilterForm.php
@@ -91,7 +91,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
         $_SESSION['locale_translate_filter'][$name] = $form_state['values'][$name];
       }
     }
-    $form_state['redirect_route']['route_name'] = 'locale.translate_page';
+    $form_state->setRedirect('locale.translate_page');
   }
 
   /**
@@ -99,7 +99,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
    */
   public function resetForm(array &$form, FormStateInterface $form_state) {
     $_SESSION['locale_translate_filter'] = array();
-    $form_state['redirect_route']['route_name'] = 'locale.translate_page';
+    $form_state->setRedirect('locale.translate_page');
   }
 
 }
diff --git a/core/modules/menu_link_content/src/Form/MenuLinkContentDeleteForm.php b/core/modules/menu_link_content/src/Form/MenuLinkContentDeleteForm.php
index 7d79bd5..c5a7232 100644
--- a/core/modules/menu_link_content/src/Form/MenuLinkContentDeleteForm.php
+++ b/core/modules/menu_link_content/src/Form/MenuLinkContentDeleteForm.php
@@ -71,9 +71,7 @@ public function submit(array $form, FormStateInterface $form_state) {
     $this->entity->delete();
     drupal_set_message($this->t('The menu link %title has been deleted.', $t_args));
     $this->logger->notice('Deleted menu link %title.', $t_args);
-    $form_state['redirect_route'] = array(
-      'route_name' => '<front>',
-    );
+    $form_state->setRedirect('<front>');
   }
 
 }
diff --git a/core/modules/menu_link_content/src/Form/MenuLinkContentForm.php b/core/modules/menu_link_content/src/Form/MenuLinkContentForm.php
index 74d5c67..9da5356 100644
--- a/core/modules/menu_link_content/src/Form/MenuLinkContentForm.php
+++ b/core/modules/menu_link_content/src/Form/MenuLinkContentForm.php
@@ -363,11 +363,9 @@ public function save(array $form, FormStateInterface $form_state) {
 
     if ($saved) {
       drupal_set_message($this->t('The menu link has been saved.'));
-      $form_state['redirect_route'] = array(
-        'route_name' => 'entity.menu_link_content.canonical',
-        'route_parameters' => array(
-          'menu_link_content' => $menu_link->id(),
-        ),
+      $form_state->setRedirect(
+        'entity.menu_link_content.canonical',
+        array('menu_link_content' => $menu_link->id())
       );
     }
     else {
diff --git a/core/modules/menu_ui/src/Form/MenuDeleteForm.php b/core/modules/menu_ui/src/Form/MenuDeleteForm.php
index 33712e4..299df36 100644
--- a/core/modules/menu_ui/src/Form/MenuDeleteForm.php
+++ b/core/modules/menu_ui/src/Form/MenuDeleteForm.php
@@ -11,7 +11,6 @@
 use Drupal\Core\Entity\EntityConfirmFormBase;
 use Drupal\Core\Menu\MenuLinkManagerInterface;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Url;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -94,7 +93,7 @@ public function getConfirmText() {
    * {@inheritdoc}
    */
   public function submit(array $form, FormStateInterface $form_state) {
-    $form_state['redirect_route'] = new Url('menu_ui.overview_page');
+    $form_state->setRedirect('menu_ui.overview_page');
 
     // Locked menus may not be deleted.
     if ($this->entity->isLocked()) {
diff --git a/core/modules/menu_ui/src/Form/MenuLinkEditForm.php b/core/modules/menu_ui/src/Form/MenuLinkEditForm.php
index ebd691f..784024a 100644
--- a/core/modules/menu_ui/src/Form/MenuLinkEditForm.php
+++ b/core/modules/menu_ui/src/Form/MenuLinkEditForm.php
@@ -95,11 +95,9 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $link = $form['#plugin_form']->submitConfigurationForm($form, $form_state);
 
     drupal_set_message($this->t('The menu link has been saved.'));
-    $form_state['redirect_route'] = array(
-      'route_name' => 'menu_ui.menu_edit',
-      'route_parameters' => array(
-        'menu' => $link->getMenuName(),
-      ),
+    $form_state->setRedirect(
+      'menu_ui.menu_edit',
+      array('menu' => $link->getMenuName())
     );
   }
 
diff --git a/core/modules/menu_ui/src/Form/MenuLinkResetForm.php b/core/modules/menu_ui/src/Form/MenuLinkResetForm.php
index 09cfb87..d0bd61e 100644
--- a/core/modules/menu_ui/src/Form/MenuLinkResetForm.php
+++ b/core/modules/menu_ui/src/Form/MenuLinkResetForm.php
@@ -106,7 +106,7 @@ public function buildForm(array $form, FormStateInterface $form_state, MenuLinkI
   public function submitForm(array &$form, FormStateInterface $form_state) {
     $this->link = $this->menuLinkManager->resetLink($this->link->getPluginId());
     drupal_set_message($this->t('The menu link was reset to its default settings.'));
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
   /**
diff --git a/core/modules/menu_ui/src/MenuForm.php b/core/modules/menu_ui/src/MenuForm.php
index 40123d5..302a9e2 100644
--- a/core/modules/menu_ui/src/MenuForm.php
+++ b/core/modules/menu_ui/src/MenuForm.php
@@ -192,7 +192,7 @@ public function save(array $form, FormStateInterface $form_state) {
       $this->logger('menu')->notice('Menu %label has been added.', array('%label' => $menu->label(), 'link' => $edit_link));
     }
 
-    $form_state['redirect_route'] = $this->entity->urlInfo('edit-form');
+    $form_state->setRedirectUrl($this->entity->urlInfo('edit-form'));
   }
 
   /**
diff --git a/core/modules/node/src/Form/DeleteMultiple.php b/core/modules/node/src/Form/DeleteMultiple.php
index 4f0356e..86b81ec 100644
--- a/core/modules/node/src/Form/DeleteMultiple.php
+++ b/core/modules/node/src/Form/DeleteMultiple.php
@@ -124,7 +124,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       $this->logger('content')->notice('Deleted @count posts.', array('@count' => $count));
       drupal_set_message(format_plural($count, 'Deleted 1 post.', 'Deleted @count posts.'));
     }
-    $form_state['redirect_route']['route_name'] = 'system.admin_content';
+    $form_state->setRedirect('system.admin_content');
   }
 
 }
diff --git a/core/modules/node/src/Form/NodeDeleteForm.php b/core/modules/node/src/Form/NodeDeleteForm.php
index 87df223..c3de373 100644
--- a/core/modules/node/src/Form/NodeDeleteForm.php
+++ b/core/modules/node/src/Form/NodeDeleteForm.php
@@ -78,7 +78,7 @@ public function submit(array $form, FormStateInterface $form_state) {
     $node_type_storage = $this->entityManager->getStorage('node_type');
     $node_type = $node_type_storage->load($this->entity->bundle())->label();
     drupal_set_message(t('@type %title has been deleted.', array('@type' => $node_type, '%title' => $this->entity->label())));
-    $form_state['redirect_route']['route_name'] = '<front>';
+    $form_state->setRedirect('<front>');
   }
 
 }
diff --git a/core/modules/node/src/Form/NodeRevisionDeleteForm.php b/core/modules/node/src/Form/NodeRevisionDeleteForm.php
index 4df7292..dbbe550 100644
--- a/core/modules/node/src/Form/NodeRevisionDeleteForm.php
+++ b/core/modules/node/src/Form/NodeRevisionDeleteForm.php
@@ -123,14 +123,15 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $this->logger('content')->notice('@type: deleted %title revision %revision.', array('@type' => $this->revision->bundle(), '%title' => $this->revision->label(), '%revision' => $this->revision->getRevisionId()));
     $node_type = $this->nodeTypeStorage->load($this->revision->bundle())->label();
     drupal_set_message(t('Revision from %revision-date of @type %title has been deleted.', array('%revision-date' => format_date($this->revision->getRevisionCreationTime()), '@type' => $node_type, '%title' => $this->revision->label())));
-    $form_state['redirect_route'] = array(
-      'route_name' => 'node.view',
-      'route_parameters' => array(
-        'node' => $this->revision->id(),
-      ),
+    $form_state->setRedirect(
+      'node.view',
+      array('node' => $this->revision->id())
     );
     if ($this->connection->query('SELECT COUNT(DISTINCT vid) FROM {node_field_revision} WHERE nid = :nid', array(':nid' => $this->revision->id()))->fetchField() > 1) {
-      $form_state['redirect_route']['route_name'] = 'node.revision_overview';
+      $form_state->setRedirect(
+        'node.revision_overview',
+        array('node' => $this->revision->id())
+      );
     }
   }
 
diff --git a/core/modules/node/src/Form/NodeRevisionRevertForm.php b/core/modules/node/src/Form/NodeRevisionRevertForm.php
index c6dc728..bc5a302 100644
--- a/core/modules/node/src/Form/NodeRevisionRevertForm.php
+++ b/core/modules/node/src/Form/NodeRevisionRevertForm.php
@@ -115,11 +115,9 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
 
     $this->logger('content')->notice('@type: reverted %title revision %revision.', array('@type' => $this->revision->bundle(), '%title' => $this->revision->label(), '%revision' => $this->revision->getRevisionId()));
     drupal_set_message(t('@type %title has been reverted back to the revision from %revision-date.', array('@type' => node_get_type_label($this->revision), '%title' => $this->revision->label(), '%revision-date' => format_date($original_revision_timestamp))));
-    $form_state['redirect_route'] = array(
-      'route_name' => 'node.revision_overview',
-      'route_parameters' => array(
-        'node' => $this->revision->id(),
-      ),
+    $form_state->setRedirect(
+      'node.revision_overview',
+      array('node' => $this->revision->id())
     );
   }
 
diff --git a/core/modules/node/src/Form/NodeTypeDeleteConfirm.php b/core/modules/node/src/Form/NodeTypeDeleteConfirm.php
index 5cf4e2a..3631b33 100644
--- a/core/modules/node/src/Form/NodeTypeDeleteConfirm.php
+++ b/core/modules/node/src/Form/NodeTypeDeleteConfirm.php
@@ -89,7 +89,7 @@ public function submit(array $form, FormStateInterface $form_state) {
     drupal_set_message(t('The content type %name has been deleted.', $t_args));
     $this->logger('node')->notice('Deleted content type %name.', $t_args);
 
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/node/src/Form/RebuildPermissionsForm.php b/core/modules/node/src/Form/RebuildPermissionsForm.php
index 9f8da72..9b8246a 100644
--- a/core/modules/node/src/Form/RebuildPermissionsForm.php
+++ b/core/modules/node/src/Form/RebuildPermissionsForm.php
@@ -53,7 +53,7 @@ public function getDescription() {
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
     node_access_rebuild(TRUE);
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/node/src/NodeForm.php b/core/modules/node/src/NodeForm.php
index b31e6a9..d1dd654 100644
--- a/core/modules/node/src/NodeForm.php
+++ b/core/modules/node/src/NodeForm.php
@@ -449,15 +449,13 @@ public function save(array $form, FormStateInterface $form_state) {
       $form_state['values']['nid'] = $node->id();
       $form_state['nid'] = $node->id();
       if ($node->access('view')) {
-        $form_state['redirect_route'] = array(
-          'route_name' => 'node.view',
-          'route_parameters' => array(
-            'node' => $node->id(),
-          ),
+        $form_state->setRedirect(
+          'node.view',
+          array('node' => $node->id())
         );
       }
       else {
-        $form_state['redirect_route']['route_name'] = '<front>';
+        $form_state->setRedirect('<front>');
       }
     }
     else {
diff --git a/core/modules/node/src/NodeTypeForm.php b/core/modules/node/src/NodeTypeForm.php
index a197746..d6e4a29 100644
--- a/core/modules/node/src/NodeTypeForm.php
+++ b/core/modules/node/src/NodeTypeForm.php
@@ -194,7 +194,7 @@ public function save(array $form, FormStateInterface $form_state) {
       $this->logger('node')->notice('Added content type %name.', $context);
     }
 
-    $form_state['redirect_route']['route_name'] = 'node.overview_types';
+    $form_state->setRedirect('node.overview_types');
   }
 
 }
diff --git a/core/modules/node/src/Plugin/Action/DeleteNode.php b/core/modules/node/src/Plugin/Action/DeleteNode.php
index f279357..e71b581 100644
--- a/core/modules/node/src/Plugin/Action/DeleteNode.php
+++ b/core/modules/node/src/Plugin/Action/DeleteNode.php
@@ -19,7 +19,7 @@
  *   id = "node_delete_action",
  *   label = @Translation("Delete selected content"),
  *   type = "node",
- *   confirm_form_path = "admin/content/node/delete"
+ *   confirm_form_route_name = "node.multiple_delete_confirm"
  * )
  */
 class DeleteNode extends ActionBase implements ContainerFactoryPluginInterface {
diff --git a/core/modules/path/src/Form/DeleteForm.php b/core/modules/path/src/Form/DeleteForm.php
index b253490..80251dc 100644
--- a/core/modules/path/src/Form/DeleteForm.php
+++ b/core/modules/path/src/Form/DeleteForm.php
@@ -89,7 +89,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $pid = NU
   public function submitForm(array &$form, FormStateInterface $form_state) {
     $this->aliasStorage->delete(array('pid' => $this->pathAlias['pid']));
 
-    $form_state['redirect'] = 'admin/config/search/path';
+    $form_state->setRedirect('path.admin_overview');
   }
 
 }
diff --git a/core/modules/path/src/Form/EditForm.php b/core/modules/path/src/Form/EditForm.php
index b5fd90e..2dd99b0 100644
--- a/core/modules/path/src/Form/EditForm.php
+++ b/core/modules/path/src/Form/EditForm.php
@@ -53,14 +53,16 @@ public function buildForm(array $form, FormStateInterface $form_state, $pid = NU
    * Submits the delete form.
    */
   public function deleteSubmit(array &$form, FormStateInterface $form_state) {
-    $form_state['redirect_route'] = new Url('path.delete', array(
+    $url = new Url('path.delete', array(
       'pid' => $form_state['values']['pid'],
     ));
 
     if ($this->getRequest()->query->has('destination')) {
-      $form_state['redirect_route']->setOption('query', drupal_get_destination());
+      $url->setOption('query', drupal_get_destination());
       $this->getRequest()->query->remove('destination');
     }
+
+    $form_state->setRedirectUrl($url);
   }
 
 }
diff --git a/core/modules/path/src/Form/PathFilterForm.php b/core/modules/path/src/Form/PathFilterForm.php
index e8130f0..a9de1ea 100644
--- a/core/modules/path/src/Form/PathFilterForm.php
+++ b/core/modules/path/src/Form/PathFilterForm.php
@@ -9,7 +9,6 @@
 
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Url;
 
 /**
  * Provides the path admin overview filter form.
@@ -61,7 +60,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $keys = N
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $form_state['redirect_route'] = new Url('path.admin_overview_filter', array(
+    $form_state->setRedirect('path.admin_overview_filter', array(
       'keys' => trim($form_state['values']['filter']),
     ));
   }
@@ -70,7 +69,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
    * Resets the filter selections.
    */
   public function resetForm(array &$form, FormStateInterface $form_state) {
-    $form_state['redirect_route'] = new Url('path.admin_overview');
+    $form_state->setRedirect('path.admin_overview');
   }
 
 }
diff --git a/core/modules/path/src/Form/PathFormBase.php b/core/modules/path/src/Form/PathFormBase.php
index c1f7ca5..94eb079 100644
--- a/core/modules/path/src/Form/PathFormBase.php
+++ b/core/modules/path/src/Form/PathFormBase.php
@@ -12,7 +12,6 @@
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Path\AliasManagerInterface;
 use Drupal\Core\Path\AliasStorageInterface;
-use Drupal\Core\Url;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -170,7 +169,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $this->aliasStorage->save($source, $alias, $langcode, $pid);
 
     drupal_set_message($this->t('The alias has been saved.'));
-    $form_state['redirect_route'] = new Url('path.admin_overview');
+    $form_state->setRedirect('path.admin_overview');
   }
 
 }
diff --git a/core/modules/responsive_image/src/Form/ResponsiveImageMappingDeleteForm.php b/core/modules/responsive_image/src/Form/ResponsiveImageMappingDeleteForm.php
index 1d438b6..c15d823 100644
--- a/core/modules/responsive_image/src/Form/ResponsiveImageMappingDeleteForm.php
+++ b/core/modules/responsive_image/src/Form/ResponsiveImageMappingDeleteForm.php
@@ -41,7 +41,7 @@ public function submit(array $form, FormStateInterface $form_state) {
     $this->entity->delete();
     drupal_set_message($this->t('Responsive image mapping %label has been deleted.', array('%label' => $this->entity->label())));
     $this->logger('responsive_image')->notice('Responsive image mapping %label has been deleted.', array('%label' => $this->entity->label()));
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/responsive_image/src/ResponsiveImageMappingForm.php b/core/modules/responsive_image/src/ResponsiveImageMappingForm.php
index f8bb055..cfa3d3f 100644
--- a/core/modules/responsive_image/src/ResponsiveImageMappingForm.php
+++ b/core/modules/responsive_image/src/ResponsiveImageMappingForm.php
@@ -131,15 +131,13 @@ public function save(array $form, FormStateInterface $form_state) {
     // Redirect to edit form after creating a new mapping or after selecting
     // another breakpoint group.
     if (!$responsive_image_mapping->hasMappings()) {
-      $form_state['redirect_route'] = array(
-        'route_name' => 'entity.responsive_image_mapping.edit_form',
-        'route_parameters' => array(
-          'responsive_image_mapping' => $responsive_image_mapping->id(),
-        ),
+      $form_state->setRedirect(
+        'entity.responsive_image_mapping.edit_form',
+        array('responsive_image_mapping' => $responsive_image_mapping->id())
       );
     }
     else {
-      $form_state['redirect_route']['route_name'] = 'responsive_image.mapping_page';
+      $form_state->setRedirect('responsive_image.mapping_page');
     }
   }
 
diff --git a/core/modules/search/src/Form/ReindexConfirm.php b/core/modules/search/src/Form/ReindexConfirm.php
index 06c457b..3136559 100644
--- a/core/modules/search/src/Form/ReindexConfirm.php
+++ b/core/modules/search/src/Form/ReindexConfirm.php
@@ -65,7 +65,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     if ($form['confirm']) {
       search_reindex();
       drupal_set_message($this->t('The index will be rebuilt.'));
-      $form_state['redirect_route'] = $this->getCancelUrl();
+      $form_state->setRedirectUrl($this->getCancelUrl());
     }
   }
 }
diff --git a/core/modules/search/src/Form/SearchPageDeleteForm.php b/core/modules/search/src/Form/SearchPageDeleteForm.php
index a78d1c2..8797961 100644
--- a/core/modules/search/src/Form/SearchPageDeleteForm.php
+++ b/core/modules/search/src/Form/SearchPageDeleteForm.php
@@ -42,7 +42,7 @@ public function getConfirmText() {
    */
   public function submit(array $form, FormStateInterface $form_state) {
     $this->entity->delete();
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
     drupal_set_message($this->t('The %label search page has been deleted.', array('%label' => $this->entity->label())));
   }
 
diff --git a/core/modules/search/src/Form/SearchPageForm.php b/core/modules/search/src/Form/SearchPageForm.php
index 8e585db..795cbc0 100644
--- a/core/modules/search/src/Form/SearchPageForm.php
+++ b/core/modules/search/src/Form/SearchPageForm.php
@@ -91,9 +91,10 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     // parameters so that the search results generation is triggered.
     $query = $this->entity->getPlugin()->buildSearchUrlQuery($form_state);
     $route = 'search.view_' . $form_state['search_page_id'];
-    $form_state['redirect_route'] = array(
-      'route_name' => $route,
-      'options' => array('query' => $query),
+    $form_state->setRedirect(
+      $route,
+      array(),
+      array('query' => $query)
     );
   }
 }
diff --git a/core/modules/search/src/Form/SearchPageFormBase.php b/core/modules/search/src/Form/SearchPageFormBase.php
index 3c051f3..0610a20 100644
--- a/core/modules/search/src/Form/SearchPageFormBase.php
+++ b/core/modules/search/src/Form/SearchPageFormBase.php
@@ -179,7 +179,7 @@ public function submit(array $form, FormStateInterface $form_state) {
   public function save(array $form, FormStateInterface $form_state) {
     $this->entity->save();
 
-    $form_state['redirect_route']['route_name'] = 'search.settings';
+    $form_state->setRedirect('search.settings');
   }
 
 }
diff --git a/core/modules/search/src/SearchPageListBuilder.php b/core/modules/search/src/SearchPageListBuilder.php
index c54bbef..a5c2d18 100644
--- a/core/modules/search/src/SearchPageListBuilder.php
+++ b/core/modules/search/src/SearchPageListBuilder.php
@@ -351,7 +351,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
    */
   public function searchAdminReindexSubmit(array &$form, FormStateInterface $form_state) {
     // Send the user to the confirmation page.
-    $form_state['redirect_route']['route_name'] = 'search.reindex_confirm';
+    $form_state->setRedirect('search.reindex_confirm');
   }
 
   /**
@@ -367,11 +367,9 @@ public function validateAddSearchPage(array &$form, FormStateInterface $form_sta
    * Form submission handler for adding a new search page.
    */
   public function submitAddSearchPage(array &$form, FormStateInterface $form_state) {
-    $form_state['redirect_route'] = array(
-      'route_name' => 'search.add_type',
-      'route_parameters' => array(
-        'search_plugin_id' => $form_state['values']['search_type'],
-      ),
+    $form_state->setRedirect(
+      'search.add_type',
+      array('search_plugin_id' => $form_state['values']['search_type'])
     );
   }
 
diff --git a/core/modules/shortcut/src/Form/ShortcutDeleteForm.php b/core/modules/shortcut/src/Form/ShortcutDeleteForm.php
index b51dca8..8172fb4 100644
--- a/core/modules/shortcut/src/Form/ShortcutDeleteForm.php
+++ b/core/modules/shortcut/src/Form/ShortcutDeleteForm.php
@@ -51,7 +51,7 @@ public function getConfirmText() {
    */
   public function submit(array $form, FormStateInterface $form_state) {
     $this->entity->delete();
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
     drupal_set_message($this->t('The shortcut %title has been deleted.', array('%title' => $this->entity->title->value)));
   }
 
diff --git a/core/modules/shortcut/src/Form/ShortcutSetDeleteForm.php b/core/modules/shortcut/src/Form/ShortcutSetDeleteForm.php
index f7e28ac..4be29ca 100644
--- a/core/modules/shortcut/src/Form/ShortcutSetDeleteForm.php
+++ b/core/modules/shortcut/src/Form/ShortcutSetDeleteForm.php
@@ -9,7 +9,6 @@
 
 use Drupal\Core\Entity\EntityConfirmFormBase;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Url;
 use Drupal\shortcut\ShortcutSetStorageInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Drupal\Core\Database\Connection;
@@ -104,7 +103,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    */
   public function submit(array $form, FormStateInterface $form_state) {
     $this->entity->delete();
-    $form_state['redirect_route'] = new Url('shortcut.set_admin');
+    $form_state->setRedirect('shortcut.set_admin');
     drupal_set_message(t('The shortcut set %title has been deleted.', array('%title' => $this->entity->label())));
   }
 
diff --git a/core/modules/shortcut/src/Form/SwitchShortcutSet.php b/core/modules/shortcut/src/Form/SwitchShortcutSet.php
index 462cf40..2e5c92e 100644
--- a/core/modules/shortcut/src/Form/SwitchShortcutSet.php
+++ b/core/modules/shortcut/src/Form/SwitchShortcutSet.php
@@ -211,11 +211,9 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       else {
         drupal_set_message($this->t('%user is now using a new shortcut set called %set_name. You can edit it from this page.', $replacements));
       }
-      $form_state['redirect_route'] = array(
-        'route_name' => 'entity.shortcut_set.customize_form',
-        'route_parameters' => array(
-          'shortcut_set' => $set->id(),
-        ),
+      $form_state->setRedirect(
+        'entity.shortcut_set.customize_form',
+        array('shortcut_set' => $set->id())
       );
     }
     else {
diff --git a/core/modules/shortcut/src/ShortcutForm.php b/core/modules/shortcut/src/ShortcutForm.php
index d5cb017..2666046 100644
--- a/core/modules/shortcut/src/ShortcutForm.php
+++ b/core/modules/shortcut/src/ShortcutForm.php
@@ -87,9 +87,9 @@ public function save(array $form, FormStateInterface $form_state) {
     }
     drupal_set_message($message);
 
-    $form_state['redirect_route'] = array(
-      'route_name' => 'entity.shortcut_set.customize_form',
-      'route_parameters' => array('shortcut_set' => $entity->bundle()),
+    $form_state->setRedirect(
+      'entity.shortcut_set.customize_form',
+      array('shortcut_set' => $entity->bundle())
     );
   }
 
diff --git a/core/modules/shortcut/src/ShortcutSetForm.php b/core/modules/shortcut/src/ShortcutSetForm.php
index 17c3814..0d3b7ad 100644
--- a/core/modules/shortcut/src/ShortcutSetForm.php
+++ b/core/modules/shortcut/src/ShortcutSetForm.php
@@ -74,7 +74,7 @@ public function save(array $form, FormStateInterface $form_state) {
     else {
       drupal_set_message(t('Updated set name to %set-name.', array('%set-name' => $entity->label())));
     }
-    $form_state['redirect_route'] = $this->entity->urlInfo('customize-form');
+    $form_state->setRedirectUrl($this->entity->urlInfo('customize-form'));
   }
 
 }
diff --git a/core/modules/simpletest/src/Form/SimpletestResultsForm.php b/core/modules/simpletest/src/Form/SimpletestResultsForm.php
index f9e48d3..7e82690 100644
--- a/core/modules/simpletest/src/Form/SimpletestResultsForm.php
+++ b/core/modules/simpletest/src/Form/SimpletestResultsForm.php
@@ -266,7 +266,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     }
 
     if (!$classes) {
-      $form_state['redirect_route']['route_name'] = 'simpletest.test_form';
+      $form_state->setRedirect('simpletest.test_form');
       return;
     }
 
@@ -283,7 +283,9 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $simpletest_test_form = new SimpletestTestForm();
     $simpletest_test_form->buildForm($form_execute, $form_state_execute);
     $simpletest_test_form->submitForm($form_execute, $form_state_execute);
-    $form_state['redirect_route'] = $form_state_execute['redirect_route'];
+    if ($redirect = $form_state_execute->getRedirect()) {
+      $form_state->setRedirectUrl($redirect);
+    }
   }
 
   /**
diff --git a/core/modules/simpletest/src/Form/SimpletestTestForm.php b/core/modules/simpletest/src/Form/SimpletestTestForm.php
index bb56b69..6f19a38 100644
--- a/core/modules/simpletest/src/Form/SimpletestTestForm.php
+++ b/core/modules/simpletest/src/Form/SimpletestTestForm.php
@@ -215,11 +215,9 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     }
     if (!empty($tests_list)) {
       $test_id = simpletest_run_tests($tests_list, 'drupal');
-      $form_state['redirect_route'] = array(
-        'route_name' => 'simpletest.result_form',
-        'route_parameters' => array(
-          'test_id' => $test_id,
-        ),
+      $form_state->setRedirect(
+        'simpletest.result_form',
+        array('test_id' => $test_id)
       );
     }
   }
diff --git a/core/modules/system/src/Form/DateFormatDeleteForm.php b/core/modules/system/src/Form/DateFormatDeleteForm.php
index 952ee47..a97b94a 100644
--- a/core/modules/system/src/Form/DateFormatDeleteForm.php
+++ b/core/modules/system/src/Form/DateFormatDeleteForm.php
@@ -75,7 +75,7 @@ public function submit(array $form, FormStateInterface $form_state) {
     $this->entity->delete();
     drupal_set_message(t('Removed date format %format.', array('%format' => $this->entity->label())));
 
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/system/src/Form/DateFormatFormBase.php b/core/modules/system/src/Form/DateFormatFormBase.php
index e250b9a..abbc745 100644
--- a/core/modules/system/src/Form/DateFormatFormBase.php
+++ b/core/modules/system/src/Form/DateFormatFormBase.php
@@ -174,7 +174,7 @@ public function validate(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submit(array $form, FormStateInterface $form_state) {
-    $form_state['redirect_route']['route_name'] = 'system.date_format_list';
+    $form_state->setRedirect('system.date_format_list');
     $form_state['values']['pattern'] = trim($form_state['values']['date_format_pattern']);
 
     parent::submit($form, $form_state);
diff --git a/core/modules/system/src/Form/ModulesListConfirmForm.php b/core/modules/system/src/Form/ModulesListConfirmForm.php
index 412c4ba..70779c1 100644
--- a/core/modules/system/src/Form/ModulesListConfirmForm.php
+++ b/core/modules/system/src/Form/ModulesListConfirmForm.php
@@ -152,7 +152,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       drupal_set_message($this->t('The configuration options have been saved.'));
     }
 
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/system/src/Form/ModulesListForm.php b/core/modules/system/src/Form/ModulesListForm.php
index c8fe301..6edbcb4 100644
--- a/core/modules/system/src/Form/ModulesListForm.php
+++ b/core/modules/system/src/Form/ModulesListForm.php
@@ -486,7 +486,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       $this->keyValueExpirable->setWithExpire($account, $modules, 60);
 
       // Redirect to the confirmation form.
-      $form_state['redirect_route']['route_name'] = 'system.modules_list_confirm';
+      $form_state->setRedirect('system.modules_list_confirm');
 
       // We can exit here because at least one modules has dependencies
       // which we have to prompt the user for in a confirmation form.
diff --git a/core/modules/system/src/Form/ModulesUninstallConfirmForm.php b/core/modules/system/src/Form/ModulesUninstallConfirmForm.php
index 02c1dbe..4273f89 100644
--- a/core/modules/system/src/Form/ModulesUninstallConfirmForm.php
+++ b/core/modules/system/src/Form/ModulesUninstallConfirmForm.php
@@ -201,7 +201,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $this->moduleHandler->uninstall($this->modules);
 
     drupal_set_message($this->t('The selected modules have been uninstalled.'));
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/system/src/Form/ModulesUninstallForm.php b/core/modules/system/src/Form/ModulesUninstallForm.php
index b1ec48c..a8427b5 100644
--- a/core/modules/system/src/Form/ModulesUninstallForm.php
+++ b/core/modules/system/src/Form/ModulesUninstallForm.php
@@ -153,7 +153,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
     // Form submitted, but no modules selected.
     if (!array_filter($form_state['values']['uninstall'])) {
       drupal_set_message($this->t('No modules selected.'), 'error');
-      $form_state['redirect_route']['route_name'] = 'system.modules_uninstall';
+      $form_state->setRedirect('system.modules_uninstall');
     }
   }
 
@@ -168,6 +168,6 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $this->keyValueExpirable->setWithExpire($account, $uninstall, 60);
 
     // Redirect to the confirm form.
-    $form_state['redirect_route']['route_name'] = 'system.modules_uninstall_confirm';
+    $form_state->setRedirect('system.modules_uninstall_confirm');
   }
 }
diff --git a/core/modules/system/src/Plugin/views/field/BulkForm.php b/core/modules/system/src/Plugin/views/field/BulkForm.php
index 9cf6836..c910ba1 100644
--- a/core/modules/system/src/Plugin/views/field/BulkForm.php
+++ b/core/modules/system/src/Plugin/views/field/BulkForm.php
@@ -263,8 +263,8 @@ public function viewsFormSubmit(&$form, FormStateInterface $form_state) {
       $action->execute($entities);
 
       $operation_definition = $action->getPluginDefinition();
-      if (!empty($operation_definition['confirm_form_path'])) {
-        $form_state['redirect'] = $operation_definition['confirm_form_path'];
+      if (!empty($operation_definition['confirm_form_route_name'])) {
+        $form_state->setRedirect($operation_definition['confirm_form_route_name']);
       }
 
       $count = count(array_filter($form_state['values'][$this->options['id']]));
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 976fcc5..cad83e5 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -14,6 +14,7 @@
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Menu\MenuTreeParameters;
 use Drupal\block\BlockPluginInterface;
+use Drupal\Core\Url;
 use Drupal\user\UserInterface;
 use Symfony\Component\HttpFoundation\RedirectResponse;
 use GuzzleHttp\Exception\RequestException;
@@ -790,7 +791,7 @@ function _system_themes_access($theme) {
  * using the URL from system_authorized_get_url(). Redirecting yourself is
  * necessary when your authorized operation is being triggered by a form
  * submit handler, since calling redirecting in a submit handler is a bad
- * idea, and you should instead set $form_state['redirect'].
+ * idea, and you should instead use $form_state->setRedirect().
  *
  * Once the SESSION is setup for the operation and the user is redirected to
  * authorize.php, they will be prompted for their connection credentials (core
@@ -817,14 +818,14 @@ function _system_themes_access($theme) {
  * not to assume any code exists. Example (system_authorized_run()):
  * @code
  *   system_authorized_init($callback, $file, $arguments, $page_title);
- *   return new RedirectResponse(system_authorized_get_url());
+ *   return new RedirectResponse(system_authorized_get_url()->toString());
  * @endcode
  * Example (update_manager_install_form_submit()):
  * @code
  *  system_authorized_init('update_authorize_run_install',
  *    drupal_get_path('module', 'update') . '/update.authorize.inc',
  *    $arguments, t('Update manager'));
- *  $form_state['redirect'] = system_authorized_get_url();
+ *  $form_state->setRedirectUrl(system_authorized_get_url());
  * @endcode
  *
  * @param $callback
@@ -863,7 +864,7 @@ function system_authorized_init($callback, $file, $arguments = array(), $page_ti
  *
  * @param array $options
  *   Optional array of options to pass to url().
- * @return
+ * @return \Drupal\Core\Url
  *   The full URL to authorize.php, using HTTPS if available.
  *
  * @see system_authorized_init()
@@ -873,7 +874,10 @@ function system_authorized_get_url(array $options = array()) {
   // Force HTTPS if available, regardless of what the caller specifies.
   $options['https'] = TRUE;
   // Prefix with $base_url so url() treats it as an external link.
-  return url($base_url . '/core/authorize.php', $options);
+  $url = Url::createFromPath($base_url . '/core/authorize.php');
+  $url_options = $url->getOptions();
+  $url->setOptions($options + $url_options);
+  return $url;
 }
 
 /**
@@ -881,6 +885,8 @@ function system_authorized_get_url(array $options = array()) {
  *
  * @param array $options
  *   Optional array of options to pass to url().
+ *
+ * @return \Drupal\Core\Url
  */
 function system_authorized_batch_processing_url(array $options = array()) {
   $options['query'] = array('batch' => '1');
@@ -894,7 +900,7 @@ function system_authorized_batch_processing_url(array $options = array()) {
  */
 function system_authorized_run($callback, $file, $arguments = array(), $page_title = NULL) {
   system_authorized_init($callback, $file, $arguments, $page_title);
-  return new RedirectResponse(system_authorized_get_url());
+  return new RedirectResponse(system_authorized_get_url()->toString());
 }
 
 /**
@@ -905,7 +911,7 @@ function system_authorized_run($callback, $file, $arguments = array(), $page_tit
 function system_authorized_batch_process() {
   $finish_url = system_authorized_get_url();
   $process_url = system_authorized_batch_processing_url();
-  return batch_process($finish_url, $process_url);
+  return batch_process($finish_url->toString(), $process_url->toString());
 }
 
 /**
diff --git a/core/modules/system/tests/modules/ajax_test/src/Form/AjaxTestDialogForm.php b/core/modules/system/tests/modules/ajax_test/src/Form/AjaxTestDialogForm.php
index 5f11817..22dc4ee 100644
--- a/core/modules/system/tests/modules/ajax_test/src/Form/AjaxTestDialogForm.php
+++ b/core/modules/system/tests/modules/ajax_test/src/Form/AjaxTestDialogForm.php
@@ -68,7 +68,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $form_state['redirect'] = 'ajax-test/dialog-contents';
+    $form_state->setRedirect('ajax_test.dialog_contents');
   }
 
 
diff --git a/core/modules/system/tests/modules/batch_test/src/Form/BatchTestChainedForm.php b/core/modules/system/tests/modules/batch_test/src/Form/BatchTestChainedForm.php
index ae6430e..b249127 100644
--- a/core/modules/system/tests/modules/batch_test/src/Form/BatchTestChainedForm.php
+++ b/core/modules/system/tests/modules/batch_test/src/Form/BatchTestChainedForm.php
@@ -9,7 +9,6 @@
 
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Url;
 
 /**
  * Generate form of id batch_test_chained_form.
@@ -65,7 +64,7 @@ public static function batchTestChainedFormSubmit1($form, FormStateInterface $fo
     $form_state['values']['value']++;
     batch_set(_batch_test_batch_1());
 
-    $form_state['redirect_route'] = new Url('batch_test.redirect');
+    $form_state->setRedirect('batch_test.redirect');
   }
 
   /**
@@ -78,7 +77,7 @@ public static function batchTestChainedFormSubmit2($form, FormStateInterface $fo
     $form_state['values']['value']++;
     batch_set(_batch_test_batch_2());
 
-    $form_state['redirect_route'] = new Url('batch_test.redirect');
+    $form_state->setRedirect('batch_test.redirect');
   }
 
   /**
@@ -90,7 +89,7 @@ public static function batchTestChainedFormSubmit3($form, FormStateInterface $fo
 
     $form_state['values']['value']++;
 
-    $form_state['redirect_route'] = new Url('batch_test.redirect');
+    $form_state->setRedirect('batch_test.redirect');
   }
 
   /**
@@ -103,7 +102,7 @@ public static function batchTestChainedFormSubmit4($form, FormStateInterface $fo
     $form_state['values']['value']++;
     batch_set(_batch_test_batch_3());
 
-    $form_state['redirect_route'] = new Url('batch_test.redirect');
+    $form_state->setRedirect('batch_test.redirect');
   }
 
 }
diff --git a/core/modules/system/tests/modules/batch_test/src/Form/BatchTestMultiStepForm.php b/core/modules/system/tests/modules/batch_test/src/Form/BatchTestMultiStepForm.php
index 3743cac..e5c72e9 100644
--- a/core/modules/system/tests/modules/batch_test/src/Form/BatchTestMultiStepForm.php
+++ b/core/modules/system/tests/modules/batch_test/src/Form/BatchTestMultiStepForm.php
@@ -9,7 +9,6 @@
 
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Url;
 
 /**
  * Generate form of id batch_test_multistep_form.
@@ -62,7 +61,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       $form_state['rebuild'] = TRUE;
     }
 
-    $form_state['redirect_route'] = new Url('batch_test.redirect');
+    $form_state->setRedirect('batch_test.redirect');
   }
 
 }
diff --git a/core/modules/system/tests/modules/batch_test/src/Form/BatchTestSimpleForm.php b/core/modules/system/tests/modules/batch_test/src/Form/BatchTestSimpleForm.php
index 6bfa1c9..f43c873 100644
--- a/core/modules/system/tests/modules/batch_test/src/Form/BatchTestSimpleForm.php
+++ b/core/modules/system/tests/modules/batch_test/src/Form/BatchTestSimpleForm.php
@@ -9,7 +9,6 @@
 
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Url;
 
 /**
  * Generate form of id batch_test_simple_form.
@@ -55,7 +54,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $function = '_batch_test_' . $form_state['values']['batch'];
     batch_set($function());
 
-    $form_state['redirect_route'] = new Url('batch_test.redirect');
+    $form_state->setRedirect('batch_test.redirect');
   }
 
 }
diff --git a/core/modules/system/tests/modules/entity_test/src/EntityTestDeleteForm.php b/core/modules/system/tests/modules/entity_test/src/EntityTestDeleteForm.php
index 76fea69..d68d4bc 100644
--- a/core/modules/system/tests/modules/entity_test/src/EntityTestDeleteForm.php
+++ b/core/modules/system/tests/modules/entity_test/src/EntityTestDeleteForm.php
@@ -39,7 +39,7 @@ public function submit(array $form, FormStateInterface $form_state) {
     $entity = $this->entity;
     $entity->delete();
     drupal_set_message(t('%entity_type @id has been deleted.', array('@id' => $entity->id(), '%entity_type' => $entity->getEntityTypeId())));
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/system/tests/modules/entity_test/src/EntityTestForm.php b/core/modules/system/tests/modules/entity_test/src/EntityTestForm.php
index ed56b50..0b5db44 100644
--- a/core/modules/system/tests/modules/entity_test/src/EntityTestForm.php
+++ b/core/modules/system/tests/modules/entity_test/src/EntityTestForm.php
@@ -94,11 +94,9 @@ public function save(array $form, FormStateInterface $form_state) {
 
     if ($entity->id()) {
       $entity_type = $entity->getEntityTypeId();
-      $form_state['redirect_route'] = array(
-        'route_name' => "entity_test.edit_$entity_type",
-        'route_parameters' => array(
-          $entity_type => $entity->id(),
-        ),
+      $form_state->setRedirect(
+        "entity_test.edit_$entity_type",
+        array($entity_type => $entity->id())
       );
     }
     else {
diff --git a/core/modules/system/tests/modules/form_test/src/ConfirmFormTestForm.php b/core/modules/system/tests/modules/form_test/src/ConfirmFormTestForm.php
index d650455..a031747 100644
--- a/core/modules/system/tests/modules/form_test/src/ConfirmFormTestForm.php
+++ b/core/modules/system/tests/modules/form_test/src/ConfirmFormTestForm.php
@@ -72,7 +72,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
     drupal_set_message($this->t('The ConfirmFormTestForm::submitForm() method was used for this form.'));
-    $form_state['redirect_route']['route_name'] = '<front>';
+    $form_state->setRedirect('<front>');
   }
 
 }
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxesZeroForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxesZeroForm.php
index 70efd25..557fd64 100644
--- a/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxesZeroForm.php
+++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxesZeroForm.php
@@ -60,7 +60,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       $form_state->setResponse(new JsonResponse($form_state['values']));
     }
     else {
-      $form_state['redirect'] = FALSE;
+      $form_state['no_redirect'] = TRUE;
     }
   }
 
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestRedirectForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestRedirectForm.php
index 0adc985..1c6437d 100644
--- a/core/modules/system/tests/modules/form_test/src/Form/FormTestRedirectForm.php
+++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestRedirectForm.php
@@ -9,6 +9,7 @@
 
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Url;
 
 /**
  * Form builder to detect form redirect.
@@ -52,10 +53,12 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
     if (!empty($form_state['values']['redirection'])) {
-      $form_state['redirect'] = !empty($form_state['values']['destination']) ? $form_state['values']['destination'] : NULL;
+      if (!empty($form_state['values']['destination'])) {
+        $form_state->setRedirectUrl(Url::createFromPath($GLOBALS['base_url'] . '/' . $form_state['values']['destination']));
+      }
     }
     else {
-      $form_state['redirect'] = FALSE;
+      $form_state['no_redirect'] = TRUE;
     }
   }
 
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestStorageForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestStorageForm.php
index 742dac3..b649950 100644
--- a/core/modules/system/tests/modules/form_test/src/Form/FormTestStorageForm.php
+++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestStorageForm.php
@@ -121,7 +121,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     if (isset($form_state['storage']['thing']['changed'])) {
       drupal_set_message("The thing has been changed.");
     }
-    $form_state['redirect_route']['route_name'] = '<front>';
+    $form_state->setRedirect('<front>');
   }
 
 }
diff --git a/core/modules/system/tests/modules/form_test/src/Form/RedirectBlockForm.php b/core/modules/system/tests/modules/form_test/src/Form/RedirectBlockForm.php
index 5f2fb52..6c89af9 100644
--- a/core/modules/system/tests/modules/form_test/src/Form/RedirectBlockForm.php
+++ b/core/modules/system/tests/modules/form_test/src/Form/RedirectBlockForm.php
@@ -9,7 +9,6 @@
 
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Url;
 
 /**
  * Builds a simple form that redirects on submit.
@@ -39,6 +38,6 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $form_state['redirect_route'] = new Url('form_test.route1', array(), array('query' => array('test1' => 'test2')));
+    $form_state->setRedirect('form_test.route1', array(), array('query' => array('test1' => 'test2')));
   }
 }
diff --git a/core/modules/taxonomy/src/Form/OverviewTerms.php b/core/modules/taxonomy/src/Form/OverviewTerms.php
index b04a70f..88addad 100644
--- a/core/modules/taxonomy/src/Form/OverviewTerms.php
+++ b/core/modules/taxonomy/src/Form/OverviewTerms.php
@@ -341,7 +341,6 @@ public function buildForm(array $form, FormStateInterface $form_state, Vocabular
         '#submit' => array(array($this, 'submitReset')),
         '#value' => $this->t('Reset to alphabetical'),
       );
-      $form_state['redirect'] = array(current_path(), ($page ? array('query' => array('page' => $page)) : array()));
     }
 
     return $form;
@@ -453,7 +452,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
   public function submitReset(array &$form, FormStateInterface $form_state) {
     /** @var $vocabulary \Drupal\taxonomy\VocabularyInterface */
     $vocabulary = $form_state['taxonomy']['vocabulary'];
-    $form_state['redirect_route'] = $vocabulary->urlInfo('reset');
+    $form_state->setRedirectUrl($vocabulary->urlInfo('reset'));
   }
 
 }
diff --git a/core/modules/taxonomy/src/Form/TermDeleteForm.php b/core/modules/taxonomy/src/Form/TermDeleteForm.php
index fcd0326..73b7321 100644
--- a/core/modules/taxonomy/src/Form/TermDeleteForm.php
+++ b/core/modules/taxonomy/src/Form/TermDeleteForm.php
@@ -66,7 +66,7 @@ public function submit(array $form, FormStateInterface $form_state) {
 
     drupal_set_message($this->t('Deleted term %name.', array('%name' => $this->entity->getName())));
     $this->logger('taxonomy')->notice('Deleted term %name.', array('%name' => $this->entity->getName()));
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/taxonomy/src/Form/VocabularyDeleteForm.php b/core/modules/taxonomy/src/Form/VocabularyDeleteForm.php
index 1494d0a..e938b6e 100644
--- a/core/modules/taxonomy/src/Form/VocabularyDeleteForm.php
+++ b/core/modules/taxonomy/src/Form/VocabularyDeleteForm.php
@@ -58,7 +58,7 @@ public function submit(array $form, FormStateInterface $form_state) {
     $this->entity->delete();
     drupal_set_message($this->t('Deleted vocabulary %name.', array('%name' => $this->entity->label())));
     $this->logger('taxonomy')->notice('Deleted vocabulary %name.', array('%name' => $this->entity->label()));
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/taxonomy/src/Form/VocabularyResetForm.php b/core/modules/taxonomy/src/Form/VocabularyResetForm.php
index 5382f71..b129262 100644
--- a/core/modules/taxonomy/src/Form/VocabularyResetForm.php
+++ b/core/modules/taxonomy/src/Form/VocabularyResetForm.php
@@ -85,7 +85,7 @@ public function save(array $form, FormStateInterface $form_state) {
     $this->termStorage->resetWeights($this->entity->id());
     drupal_set_message($this->t('Reset vocabulary %name to alphabetical order.', array('%name' => $this->entity->label())));
     $this->logger('taxonomy')->notice('Reset vocabulary %name to alphabetical order.', array('%name' => $this->entity->label()));
-    $form_state['redirect_route'] = $this->entity->urlInfo('edit-form');
+    $form_state->setRedirectUrl($this->entity->urlInfo('edit-form'));
   }
 
 }
diff --git a/core/modules/taxonomy/src/TermForm.php b/core/modules/taxonomy/src/TermForm.php
index fa2443e..1af2453 100644
--- a/core/modules/taxonomy/src/TermForm.php
+++ b/core/modules/taxonomy/src/TermForm.php
@@ -98,10 +98,6 @@ public function form(array $form, FormStateInterface $form_state) {
       '#value' => $term->id(),
     );
 
-    if ($term->isNew()) {
-      $form_state['redirect'] = current_path();
-    }
-
     return parent::form($form, $form_state, $term);
   }
 
diff --git a/core/modules/taxonomy/src/TermTranslationHandler.php b/core/modules/taxonomy/src/TermTranslationHandler.php
index 3b8fbeb..565ace8 100644
--- a/core/modules/taxonomy/src/TermTranslationHandler.php
+++ b/core/modules/taxonomy/src/TermTranslationHandler.php
@@ -37,7 +37,7 @@ function entityFormSave(array $form, FormStateInterface $form_state) {
       // We need a redirect here, otherwise we would get an access denied page,
       // since the current URL would be preserved and we would try to add a
       // translation for a language that already has a translation.
-      $form_state['redirect_route'] = $entity->urlInfo('edit-form');
+      $form_state->setRedirectUrl($entity->urlInfo('edit-form'));
     }
   }
 
diff --git a/core/modules/taxonomy/src/VocabularyForm.php b/core/modules/taxonomy/src/VocabularyForm.php
index d389115..3a8a8b3 100644
--- a/core/modules/taxonomy/src/VocabularyForm.php
+++ b/core/modules/taxonomy/src/VocabularyForm.php
@@ -143,13 +143,13 @@ public function save(array $form, FormStateInterface $form_state) {
       case SAVED_NEW:
         drupal_set_message($this->t('Created new vocabulary %name.', array('%name' => $vocabulary->name)));
         $this->logger('taxonomy')->notice('Created new vocabulary %name.', array('%name' => $vocabulary->name, 'link' => $edit_link));
-        $form_state['redirect_route'] = $vocabulary->urlInfo('overview-form');
+        $form_state->setRedirectUrl($vocabulary->urlInfo('overview-form'));
         break;
 
       case SAVED_UPDATED:
         drupal_set_message($this->t('Updated vocabulary %name.', array('%name' => $vocabulary->name)));
         $this->logger('taxonomy')->notice('Updated vocabulary %name.', array('%name' => $vocabulary->name, 'link' => $edit_link));
-        $form_state['redirect_route']['route_name'] = 'taxonomy.vocabulary_list';
+        $form_state->setRedirect('taxonomy.vocabulary_list');
         break;
     }
 
diff --git a/core/modules/update/src/Form/UpdateManagerInstall.php b/core/modules/update/src/Form/UpdateManagerInstall.php
index 5e56c66..58a49a0 100644
--- a/core/modules/update/src/Form/UpdateManagerInstall.php
+++ b/core/modules/update/src/Form/UpdateManagerInstall.php
@@ -216,7 +216,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     // whatever FileTransfer object authorize.php creates for us.
     else {
       system_authorized_init('update_authorize_run_install', drupal_get_path('module', 'update') . '/update.authorize.inc', $arguments, $this->t('Update manager'));
-      $form_state['redirect'] = system_authorized_get_url();
+      $form_state->setRedirectUrl(system_authorized_get_url());
     }
   }
 
diff --git a/core/modules/update/src/Form/UpdateReady.php b/core/modules/update/src/Form/UpdateReady.php
index 942164a..71bb441 100644
--- a/core/modules/update/src/Form/UpdateReady.php
+++ b/core/modules/update/src/Form/UpdateReady.php
@@ -141,7 +141,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       // whatever FileTransfer object authorize.php creates for us.
       else {
         system_authorized_init('update_authorize_run_update', drupal_get_path('module', 'update') . '/update.authorize.inc', array($updates), $this->t('Update manager'));
-        $form_state['redirect'] = system_authorized_get_url();
+        $form_state->setRedirectUrl(system_authorized_get_url());
       }
     }
   }
diff --git a/core/modules/user/src/Form/UserCancelForm.php b/core/modules/user/src/Form/UserCancelForm.php
index 8e48df9..25a7f1d 100644
--- a/core/modules/user/src/Form/UserCancelForm.php
+++ b/core/modules/user/src/Form/UserCancelForm.php
@@ -125,7 +125,7 @@ public function submit(array $form, FormStateInterface $form_state) {
     if ($this->currentUser()->hasPermission('administer users') && empty($form_state['values']['user_cancel_confirm']) && $this->entity->id() != $this->currentUser()->id()) {
       user_cancel($form_state['values'], $this->entity->id(), $form_state['values']['user_cancel_method']);
 
-      $form_state['redirect_route']['route_name'] = 'user.admin_account';
+      $form_state->setRedirect('user.admin_account');
     }
     else {
       // Store cancelling method and whether to notify the user in
@@ -137,9 +137,9 @@ public function submit(array $form, FormStateInterface $form_state) {
       drupal_set_message($this->t('A confirmation request to cancel your account has been sent to your email address.'));
       $this->logger('user')->notice('Sent account cancellation request to %name %email.', array('%name' => $this->entity->label(), '%email' => '<' . $this->entity->getEmail() . '>'));
 
-      $form_state['redirect_route'] = array(
-        'route_name' => 'user.view',
-        'route_parameters' => array('user' => $this->entity->id()),
+      $form_state->setRedirect(
+        'user.view',
+        array('user' => $this->entity->id())
       );
     }
   }
diff --git a/core/modules/user/src/Form/UserLoginForm.php b/core/modules/user/src/Form/UserLoginForm.php
index ee5cf41..8f5f586 100644
--- a/core/modules/user/src/Form/UserLoginForm.php
+++ b/core/modules/user/src/Form/UserLoginForm.php
@@ -120,9 +120,9 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
 
     // A destination was set, probably on an exception controller,
     if (!$this->getRequest()->request->has('destination')) {
-      $form_state['redirect_route'] = array(
-        'route_name' => 'user.view',
-        'route_parameters' => array('user' => $account->id()),
+      $form_state->setRedirect(
+        'user.view',
+        array('user' => $account->id())
       );
     }
     else {
diff --git a/core/modules/user/src/Form/UserMultipleCancelConfirm.php b/core/modules/user/src/Form/UserMultipleCancelConfirm.php
index 430480a..cb0960c 100644
--- a/core/modules/user/src/Form/UserMultipleCancelConfirm.php
+++ b/core/modules/user/src/Form/UserMultipleCancelConfirm.php
@@ -199,7 +199,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
         }
       }
     }
-    $form_state['redirect_route']['route_name'] = 'user.admin_account';
+    $form_state->setRedirect('user.admin_account');
   }
 
 }
diff --git a/core/modules/user/src/Form/UserPasswordForm.php b/core/modules/user/src/Form/UserPasswordForm.php
index 97b5ada..4ba6f6f 100644
--- a/core/modules/user/src/Form/UserPasswordForm.php
+++ b/core/modules/user/src/Form/UserPasswordForm.php
@@ -138,7 +138,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       drupal_set_message($this->t('Further instructions have been sent to your email address.'));
     }
 
-    $form_state['redirect_route']['route_name'] = 'user.page';
+    $form_state->setRedirect('user.page');
   }
 
 }
diff --git a/core/modules/user/src/Form/UserPasswordResetForm.php b/core/modules/user/src/Form/UserPasswordResetForm.php
index 41c6e1a..5b49d6b 100644
--- a/core/modules/user/src/Form/UserPasswordResetForm.php
+++ b/core/modules/user/src/Form/UserPasswordResetForm.php
@@ -108,11 +108,13 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     // Let the user's password be changed without the current password check.
     $token = Crypt::randomBytesBase64(55);
     $_SESSION['pass_reset_' . $user->id()] = $token;
-    $form_state['redirect_route']['route_name'] = 'user.edit';
-    $form_state['redirect_route']['route_parameters'] = array('user' => $user->id());
-    $form_state['redirect_route']['options'] = array(
-      'query' => array('pass-reset-token' => $token),
-      'absolute' => TRUE,
+    $form_state->setRedirect(
+      'user.edit',
+      array('user' => $user->id()),
+      array(
+        'query' => array('pass-reset-token' => $token),
+        'absolute' => TRUE,
+      )
     );
   }
 
diff --git a/core/modules/user/src/Form/UserRoleDelete.php b/core/modules/user/src/Form/UserRoleDelete.php
index 2e80fc6..bdd4f08 100644
--- a/core/modules/user/src/Form/UserRoleDelete.php
+++ b/core/modules/user/src/Form/UserRoleDelete.php
@@ -44,7 +44,7 @@ public function submit(array $form, FormStateInterface $form_state) {
     $this->entity->delete();
     $this->logger('user')->notice('Role %name has been deleted.', array('%name' => $this->entity->label()));
     drupal_set_message($this->t('Role %name has been deleted.', array('%name' => $this->entity->label())));
-    $form_state['redirect_route'] = $this->getCancelUrl();
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/user/src/Plugin/Action/CancelUser.php b/core/modules/user/src/Plugin/Action/CancelUser.php
index 4246543..6c0e392 100644
--- a/core/modules/user/src/Plugin/Action/CancelUser.php
+++ b/core/modules/user/src/Plugin/Action/CancelUser.php
@@ -19,7 +19,7 @@
  *   id = "user_cancel_user_action",
  *   label = @Translation("Cancel the selected user accounts"),
  *   type = "user",
- *   confirm_form_path = "admin/people/cancel"
+ *   confirm_form_route_name = "user.multiple_cancel_confirm"
  * )
  */
 class CancelUser extends ActionBase implements ContainerFactoryPluginInterface {
diff --git a/core/modules/user/src/ProfileForm.php b/core/modules/user/src/ProfileForm.php
index c7c74c5..f9a0a94 100644
--- a/core/modules/user/src/ProfileForm.php
+++ b/core/modules/user/src/ProfileForm.php
@@ -65,10 +65,10 @@ public function editCancelSubmit($form, FormStateInterface $form_state) {
       $query->remove('destination');
     }
     // We redirect from user/%/edit to user/%/cancel to make the tabs disappear.
-    $form_state['redirect_route'] = array(
-      'route_name' => 'user.cancel',
-      'route_parameters' => array('user' => $this->entity->id()),
-      'options' => array('query' => $destination),
+    $form_state->setRedirect(
+      'user.cancel',
+      array('user' => $this->entity->id()),
+      array('query' => $destination)
     );
   }
 
diff --git a/core/modules/user/src/ProfileTranslationHandler.php b/core/modules/user/src/ProfileTranslationHandler.php
index fd9c90b..6e467b3 100644
--- a/core/modules/user/src/ProfileTranslationHandler.php
+++ b/core/modules/user/src/ProfileTranslationHandler.php
@@ -37,7 +37,7 @@ function entityFormSave(array $form, FormStateInterface $form_state) {
       // We need a redirect here, otherwise we would get an access denied page
       // since the current URL would be preserved and we would try to add a
       // translation for a language that already has a translation.
-      $form_state['redirect_route'] = $entity->urlInfo();
+      $form_state->setRedirectUrl($entity->urlInfo());
     }
   }
 }
diff --git a/core/modules/user/src/RegisterForm.php b/core/modules/user/src/RegisterForm.php
index c20d240..a9b146e 100644
--- a/core/modules/user/src/RegisterForm.php
+++ b/core/modules/user/src/RegisterForm.php
@@ -60,12 +60,6 @@ public function form(array $form, FormStateInterface $form_state) {
     // Start with the default user account fields.
     $form = parent::form($form, $form_state, $account);
 
-    if ($admin) {
-      // Redirect back to page which initiated the create request; usually
-      // admin/people/create.
-      $form_state['redirect'] = current_path();
-    }
-
     return $form;
   }
 
@@ -130,7 +124,7 @@ public function save(array $form, FormStateInterface $form_state) {
       _user_mail_notify('register_no_approval_required', $account);
       user_login_finalize($account);
       drupal_set_message($this->t('Registration successful. You are now logged in.'));
-      $form_state['redirect_route']['route_name'] = '<front>';
+      $form_state->setRedirect('<front>');
     }
     // No administrator approval required.
     elseif ($account->isActive() || $notify) {
@@ -145,7 +139,7 @@ public function save(array $form, FormStateInterface $form_state) {
           }
           else {
             drupal_set_message($this->t('A welcome message with further instructions has been sent to your email address.'));
-            $form_state['redirect_route']['route_name'] = '<front>';
+            $form_state->setRedirect('<front>');
           }
         }
       }
@@ -154,7 +148,7 @@ public function save(array $form, FormStateInterface $form_state) {
     else {
       _user_mail_notify('register_pending_approval', $account);
       drupal_set_message($this->t('Thank you for applying for an account. Your account is currently pending approval by the site administrator.<br />In the meantime, a welcome message with further instructions has been sent to your email address.'));
-      $form_state['redirect_route']['route_name'] = '<front>';
+      $form_state->setRedirect('<front>');
     }
   }
 }
diff --git a/core/modules/user/src/RoleForm.php b/core/modules/user/src/RoleForm.php
index 57c4d46..55e0ccd 100644
--- a/core/modules/user/src/RoleForm.php
+++ b/core/modules/user/src/RoleForm.php
@@ -68,7 +68,7 @@ public function save(array $form, FormStateInterface $form_state) {
       drupal_set_message($this->t('Role %label has been added.', array('%label' => $entity->label())));
       $this->logger('user')->notice('Role %label has been added.', array('%label' => $entity->label(), 'link' => $edit_link));
     }
-    $form_state['redirect_route']['route_name'] = 'user.role_list';
+    $form_state->setRedirect('user.role_list');
   }
 
 }
diff --git a/core/modules/views/src/Plugin/views/exposed_form/ExposedFormPluginBase.php b/core/modules/views/src/Plugin/views/exposed_form/ExposedFormPluginBase.php
index 276a4dd..62e8089 100644
--- a/core/modules/views/src/Plugin/views/exposed_form/ExposedFormPluginBase.php
+++ b/core/modules/views/src/Plugin/views/exposed_form/ExposedFormPluginBase.php
@@ -325,7 +325,6 @@ public function resetForm(&$form, FormStateInterface $form_state) {
       $this->view->exposed_data = array();
     }
 
-    $form_state['redirect'] = current_path();
     $form_state['values'] = array();
   }
 
diff --git a/core/modules/views_ui/src/Form/Ajax/Analyze.php b/core/modules/views_ui/src/Form/Ajax/Analyze.php
index 23840cb..1e0380d 100644
--- a/core/modules/views_ui/src/Form/Ajax/Analyze.php
+++ b/core/modules/views_ui/src/Form/Ajax/Analyze.php
@@ -61,7 +61,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
   public function submitForm(array &$form, FormStateInterface $form_state) {
     /** @var $view \Drupal\views_ui\ViewUI */
     $view = $form_state['view'];
-    $form_state['redirect_route'] = $view->urlInfo('edit-form');
+    $form_state->setRedirectUrl($view->urlInfo('edit-form'));
   }
 
 }
diff --git a/core/modules/views_ui/src/Form/Ajax/ReorderDisplays.php b/core/modules/views_ui/src/Form/Ajax/ReorderDisplays.php
index d9bfd29..843ba96 100644
--- a/core/modules/views_ui/src/Form/Ajax/ReorderDisplays.php
+++ b/core/modules/views_ui/src/Form/Ajax/ReorderDisplays.php
@@ -193,8 +193,9 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
 
     // Store in cache.
     $view->cacheSet();
-    $form_state['redirect_route'] = $view->urlInfo('edit-form');
-    $form_state['redirect_route']->setOption('fragment', 'views-tab-default');
+    $url = $view->urlInfo('edit-form')
+      ->setOption('fragment', 'views-tab-default');
+    $form_state->setRedirectUrl($url);
   }
 
 }
diff --git a/core/modules/views_ui/src/Form/BreakLockForm.php b/core/modules/views_ui/src/Form/BreakLockForm.php
index b95b65e..2bdf7bd 100644
--- a/core/modules/views_ui/src/Form/BreakLockForm.php
+++ b/core/modules/views_ui/src/Form/BreakLockForm.php
@@ -112,7 +112,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    */
   public function submit(array $form, FormStateInterface $form_state) {
     $this->tempStore->delete($this->entity->id());
-    $form_state['redirect_route'] = $this->entity->urlInfo('edit-form');
+    $form_state->setRedirectUrl($this->entity->urlInfo('edit-form'));
     drupal_set_message($this->t('The lock has been broken and you may now edit this view.'));
   }
 
diff --git a/core/modules/views_ui/src/ViewAddForm.php b/core/modules/views_ui/src/ViewAddForm.php
index 12d7173..dd4cd1b 100644
--- a/core/modules/views_ui/src/ViewAddForm.php
+++ b/core/modules/views_ui/src/ViewAddForm.php
@@ -190,12 +190,12 @@ public function submit(array $form, FormStateInterface $form_state) {
     // @todo Figure out whether it really makes sense to throw and catch exceptions on the wizard.
     catch (WizardException $e) {
       drupal_set_message($e->getMessage(), 'error');
-      $form_state['redirect_route']['route_name'] = 'views_ui.list';
+      $form_state->setRedirect('views_ui.list');
       return;
     }
     $view->save();
 
-    $form_state['redirect_route'] = $view->urlInfo('edit-form');
+    $form_state->setRedirectUrl($view->urlInfo('edit-form'));
   }
 
   /**
@@ -207,7 +207,7 @@ public function submit(array $form, FormStateInterface $form_state) {
    *   The current state of the form.
    */
   public function cancel(array $form, FormStateInterface $form_state) {
-    $form_state['redirect_route']['route_name'] = 'views_ui.list';
+    $form_state->setRedirect('views_ui.list');
   }
 
 }
diff --git a/core/modules/views_ui/src/ViewDeleteForm.php b/core/modules/views_ui/src/ViewDeleteForm.php
index 555d1a8..1acc4b8 100644
--- a/core/modules/views_ui/src/ViewDeleteForm.php
+++ b/core/modules/views_ui/src/ViewDeleteForm.php
@@ -46,7 +46,7 @@ public function submit(array $form, FormStateInterface $form_state) {
     $this->entity->delete();
     drupal_set_message($this->t('View %name deleted',array('%name' => $this->entity->label())));
 
-    $form_state->setRedirect($this->getCancelUrl());
+    $form_state->setRedirectUrl($this->getCancelUrl());
   }
 
 }
diff --git a/core/modules/views_ui/src/ViewDuplicateForm.php b/core/modules/views_ui/src/ViewDuplicateForm.php
index b4b5eef..fb2f2df 100644
--- a/core/modules/views_ui/src/ViewDuplicateForm.php
+++ b/core/modules/views_ui/src/ViewDuplicateForm.php
@@ -75,7 +75,7 @@ public function submit(array $form, FormStateInterface $form_state) {
     $this->entity->save();
 
     // Redirect the user to the view admin form.
-    $form_state['redirect_route'] = $this->entity->urlInfo('edit-form');
+    $form_state->setRedirectUrl($this->entity->urlInfo('edit-form'));
     return $this->entity;
   }
 
diff --git a/core/modules/views_ui/src/ViewEditForm.php b/core/modules/views_ui/src/ViewEditForm.php
index be94add..6d42b52 100644
--- a/core/modules/views_ui/src/ViewEditForm.php
+++ b/core/modules/views_ui/src/ViewEditForm.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\views_ui;
 
+use Drupal\Component\Utility\UrlHelper;
 use Drupal\Component\Utility\Xss;
 use Drupal\Core\Ajax\AjaxResponse;
 use Drupal\Core\Ajax\HtmlCommand;
@@ -16,6 +17,7 @@
 use Drupal\Component\Utility\String;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Render\Element;
+use Drupal\Core\Url;
 use Drupal\user\TempStoreFactory;
 use Drupal\views\Views;
 use Symfony\Component\HttpFoundation\RequestStack;
@@ -296,10 +298,10 @@ public function submit(array $form, FormStateInterface $form_state) {
         unset($displays[$id]);
 
         // Redirect the user to the renamed display to be sure that the page itself exists and doesn't throw errors.
-        $form_state['redirect_route'] = array(
-          'route_name' => 'views_ui.edit_display',
-          'route_parameters' => array('view' => $view->id(), 'display_id' => $new_id),
-        );
+        $form_state->setRedirect('views_ui.edit_display', array(
+          'view' => $view->id(),
+          'display_id' => $new_id,
+        ));
       }
     }
     $view->set('display', $displays);
@@ -324,7 +326,10 @@ public function submit(array $form, FormStateInterface $form_state) {
           $query->remove('destination');
         }
       }
-      $form_state['redirect'] = $destination;
+      if (!UrlHelper::isExternal($destination)) {
+        $destination = $GLOBALS['base_url'] . '/' . $destination;
+      }
+      $form_state->setRedirectUrl(Url::createFromPath($destination));
     }
 
     $view->save();
@@ -346,7 +351,7 @@ public function cancel(array $form, FormStateInterface $form_state) {
     // Remove this view from cache so edits will be lost.
     $view = $this->entity;
     $this->tempStore->delete($view->id());
-    $form_state['redirect_route']['route_name'] = 'views_ui.list';
+    $form_state->setRedirect('views_ui.list');
   }
 
   /**
@@ -589,10 +594,10 @@ public function submitDisplayUndoDelete($form, FormStateInterface $form_state) {
     $view->cacheSet();
 
     // Redirect to the top-level edit page.
-    $form_state['redirect_route'] = array(
-      'route_name' => 'views_ui.edit_display',
-      'route_parameters' => array('view' => $view->id(), 'display_id' => $id),
-    );
+    $form_state->setRedirect('views_ui.edit_display', array(
+      'view' => $view->id(),
+      'display_id' => $id,
+    ));
   }
 
   /**
@@ -608,10 +613,10 @@ public function submitDisplayEnable($form, FormStateInterface $form_state) {
     $view->cacheSet();
 
     // Redirect to the top-level edit page.
-    $form_state['redirect_route'] = array(
-      'route_name' => 'views_ui.edit_display',
-      'route_parameters' => array('view' => $view->id(), 'display_id' => $id),
-    );
+    $form_state->setRedirect('views_ui.edit_display', array(
+      'view' => $view->id(),
+      'display_id' => $id,
+    ));
   }
 
   /**
@@ -626,10 +631,10 @@ public function submitDisplayDisable($form, FormStateInterface $form_state) {
     $view->cacheSet();
 
     // Redirect to the top-level edit page.
-    $form_state['redirect_route'] = array(
-      'route_name' => 'views_ui.edit_display',
-      'route_parameters' => array('view' => $view->id(), 'display_id' => $id),
-    );
+    $form_state->setRedirect('views_ui.edit_display', array(
+      'view' => $view->id(),
+      'display_id' => $id,
+    ));
   }
 
   /**
@@ -647,7 +652,7 @@ public function submitDisplayDelete($form, FormStateInterface $form_state) {
 
     // Redirect to the top-level edit page. The first remaining display will
     // become the active display.
-    $form_state['redirect_route'] = $view->urlInfo('edit-form');
+    $form_state->setRedirectUrl($view->urlInfo('edit-form'));
   }
 
   /**
@@ -778,22 +783,28 @@ public function renderDisplayTop(ViewUI $view) {
    * should not yet redirect to the destination.
    */
   public function submitDelayDestination($form, FormStateInterface $form_state) {
-    $query = $this->requestStack->getCurrentRequest()->query;
-    // @todo: Revisit this when http://drupal.org/node/1668866 is in.
-    $destination = $query->get('destination');
-    if (isset($destination) && $form_state['redirect'] !== FALSE) {
-      if (!isset($form_state['redirect'])) {
-        $form_state['redirect'] = current_path();
+    $request = $this->requestStack->getCurrentRequest();
+    $destination = $request->query->get('destination');
+
+    $redirect = $form_state->getRedirect();
+    // If there is a destination, and redirects are not explicitly disabled, add
+    // the destination as a query string to the redirect and suppress it for the
+    // current request.
+    if (isset($destination) && $redirect !== FALSE) {
+      // Create a valid redirect if one does not exist already.
+      if (!($redirect instanceof Url)) {
+        $redirect = Url::createFromRequest($request);
       }
-      if (is_string($form_state['redirect'])) {
-        $form_state['redirect'] = array($form_state['redirect']);
-      }
-      $options = isset($form_state['redirect'][1]) ? $form_state['redirect'][1] : array();
+
+      // Add the current destination to the redirect unless one exists already.
+      $options = $redirect->getOptions();
       if (!isset($options['query']['destination'])) {
         $options['query']['destination'] = $destination;
+        $redirect->setOptions($options);
       }
-      $form_state['redirect'][1] = $options;
-      $query->remove('destination');
+
+      $form_state->setRedirectUrl($redirect);
+      $request->query->remove('destination');
     }
   }
 
@@ -818,10 +829,10 @@ public function submitDisplayDuplicate($form, FormStateInterface $form_state) {
     $view->cacheSet();
 
     // Redirect to the new display's edit page.
-    $form_state['redirect_route'] = array(
-      'route_name' => 'views_ui.edit_display',
-      'route_parameters' => array('view' => $view->id(), 'display_id' => $new_display_id),
-    );
+    $form_state->setRedirect('views_ui.edit_display', array(
+      'view' => $view->id(),
+      'display_id' => $new_display_id,
+    ));
   }
 
   /**
@@ -840,10 +851,10 @@ public function submitDisplayAdd($form, FormStateInterface $form_state) {
     $view->cacheSet();
 
     // Redirect to the new display's edit page.
-    $form_state['redirect_route'] = array(
-      'route_name' => 'views_ui.edit_display',
-      'route_parameters' => array('view' => $view->id(), 'display_id' => $display_id),
-    );
+    $form_state->setRedirect('views_ui.edit_display', array(
+      'view' => $view->id(),
+      'display_id' => $display_id,
+    ));
   }
 
   /**
@@ -876,10 +887,10 @@ public function submitDuplicateDisplayAsType($form, FormStateInterface $form_sta
     $view->cacheSet();
 
     // Redirect to the new display's edit page.
-    $form_state['redirect_route'] = array(
-      'route_name' => 'views_ui.edit_display',
-      'route_parameters' => array('view' => $view->id(), 'display_id' => $new_display_id),
-    );
+    $form_state->setRedirect('views_ui.edit_display', array(
+      'view' => $view->id(),
+      'display_id' => $new_display_id,
+    ));
   }
 
   /**
diff --git a/core/modules/views_ui/src/ViewUI.php b/core/modules/views_ui/src/ViewUI.php
index 8909c13..9ac7d46 100644
--- a/core/modules/views_ui/src/ViewUI.php
+++ b/core/modules/views_ui/src/ViewUI.php
@@ -302,7 +302,7 @@ public function standardCancel($form, FormStateInterface $form_state) {
       $this->cacheSet();
     }
 
-    $form_state['redirect_route'] = $this->urlInfo('edit-form');
+    $form_state->setRedirectUrl($this->urlInfo('edit-form'));
   }
 
   /**
diff --git a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
index 144ed65..e071ca4 100644
--- a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
+++ b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
@@ -177,7 +177,7 @@ public function testHandleRedirectWithResponse() {
       ->will($this->returnCallback(function ($form, FormStateInterface $form_state) use ($response, $redirect) {
         // Set both the response and the redirect.
         $form_state->setResponse($response);
-        $form_state['redirect'] = $redirect;
+        $form_state->set('redirect', $redirect);
       }));
 
     $form_state = new FormState();
diff --git a/core/tests/Drupal/Tests/Core/Form/FormStateTest.php b/core/tests/Drupal/Tests/Core/Form/FormStateTest.php
index 8e1ca97..6423f60 100644
--- a/core/tests/Drupal/Tests/Core/Form/FormStateTest.php
+++ b/core/tests/Drupal/Tests/Core/Form/FormStateTest.php
@@ -42,22 +42,14 @@ public function providerTestGetRedirect() {
     $data = array();
     $data[] = array(array(), NULL);
 
-    $data[] = array(array('redirect' => 'foo'), 'foo');
-    $data[] = array(array('redirect' => array('foo')), array('foo'));
-    $data[] = array(array('redirect' => array('bar', array('query' => array('foo' => 'baz')))), array('bar', array('query' => array('foo' => 'baz'))));
-    $data[] = array(array('redirect' => array('baz', array(), 301)), array('baz', array(), 301));
-
     $redirect = new RedirectResponse('/example');
     $data[] = array(array('redirect' => $redirect), $redirect);
 
-    $data[] = array(array('redirect_route' => array('route_name' => 'test_route_a')), new Url('test_route_a', array(), array('absolute' => TRUE)));
-    $data[] = array(array('redirect_route' => array('route_name' => 'test_route_b', 'route_parameters' => array('key' => 'value'))), new Url('test_route_b', array('key' => 'value'), array('absolute' => TRUE)));
-    $data[] = array(array('redirect_route' => new Url('test_route_b', array('key' => 'value'))), new Url('test_route_b', array('key' => 'value'), array('absolute' => TRUE)));
+    $data[] = array(array('redirect' => new Url('test_route_b', array('key' => 'value'))), new Url('test_route_b', array('key' => 'value')));
 
     $data[] = array(array('programmed' => TRUE), NULL);
     $data[] = array(array('rebuild' => TRUE), NULL);
     $data[] = array(array('no_redirect' => TRUE), NULL);
-    $data[] = array(array('redirect' => FALSE), NULL);
 
     return $data;
   }
diff --git a/core/tests/Drupal/Tests/Core/Form/FormSubmitterTest.php b/core/tests/Drupal/Tests/Core/Form/FormSubmitterTest.php
index 0bdc009..f4cea43 100644
--- a/core/tests/Drupal/Tests/Core/Form/FormSubmitterTest.php
+++ b/core/tests/Drupal/Tests/Core/Form/FormSubmitterTest.php
@@ -98,57 +98,34 @@ public function providerTestHandleFormSubmissionWithResponses() {
   }
 
   /**
-   * Tests the redirectForm() method when a redirect is expected.
+   * Tests the redirectForm() method when the redirect is NULL.
    *
    * @covers ::redirectForm
-   *
-   * @dataProvider providerTestRedirectWithResult
    */
-  public function testRedirectWithResult($redirect_value, $result, $status = 303) {
+  public function testRedirectWithNull() {
     $form_submitter = $this->getFormSubmitter();
     $this->urlGenerator->expects($this->once())
       ->method('generateFromPath')
-      ->will($this->returnValueMap(array(
-          array(NULL, array('query' => array(), 'absolute' => TRUE), '<front>'),
-          array('foo', array('absolute' => TRUE), 'foo'),
-          array('bar', array('query' => array('foo' => 'baz'), 'absolute' => TRUE), 'bar'),
-          array('baz', array('absolute' => TRUE), 'baz'),
-        ))
-      );
+      ->with(NULL, array('query' => array(), 'absolute' => TRUE))
+      ->willReturn('<front>');
 
     $form_state = $this->getMock('Drupal\Core\Form\FormStateInterface');
     $form_state->expects($this->once())
       ->method('getRedirect')
-      ->willReturn($redirect_value);
+      ->willReturn(NULL);
     $redirect = $form_submitter->redirectForm($form_state);
-    $this->assertSame($result, $redirect->getTargetUrl());
-    $this->assertSame($status, $redirect->getStatusCode());
+    $this->assertSame('<front>', $redirect->getTargetUrl());
+    $this->assertSame(303, $redirect->getStatusCode());
   }
 
   /**
-   * Provides test data for testing the redirectForm() method with a redirect.
-   *
-   * @return array
-   *   Returns some test data.
-   */
-  public function providerTestRedirectWithResult() {
-    return array(
-      array(NULL, '<front>'),
-      array('foo', 'foo'),
-      array(array('foo'), 'foo'),
-      array(array('bar', array('query' => array('foo' => 'baz'))), 'bar'),
-      array(array('baz', array(), 301), 'baz', 301),
-    );
-  }
-
-  /**
-   * Tests the redirectForm() with redirect_route when a redirect is expected.
+   * Tests redirectForm() when a redirect is a Url object.
    *
    * @covers ::redirectForm
    *
-   * @dataProvider providerTestRedirectWithRouteWithResult
+   * @dataProvider providerTestRedirectWithUrl
    */
-  public function testRedirectWithRouteWithResult($redirect_value, $result, $status = 303) {
+  public function testRedirectWithUrl($redirect_value, $result, $status = 303) {
     $container = new ContainerBuilder();
     $container->set('url_generator', $this->urlGenerator);
     \Drupal::setContainer($container);
@@ -176,7 +153,7 @@ public function testRedirectWithRouteWithResult($redirect_value, $result, $statu
    * @return array
    *   Returns some test data.
    */
-  public function providerTestRedirectWithRouteWithResult() {
+  public function providerTestRedirectWithUrl() {
     return array(
       array(new Url('test_route_a', array(), array('absolute' => TRUE)), 'test-route'),
       array(new Url('test_route_b', array('key' => 'value'), array('absolute' => TRUE)), 'test-route/value'),
