diff --git a/core/includes/ajax.inc b/core/includes/ajax.inc
index df3ce78..cb85967 100644
--- a/core/includes/ajax.inc
+++ b/core/includes/ajax.inc
@@ -101,7 +101,7 @@
  * @code
  * $format_value = \Drupal\Component\Utility\NestedArray::getValue(
  *   $form_state->getValues(),
- *   $form_state['triggering_element']['#array_parents']);
+ *   $form_state->getTriggeringElement()['#array_parents']);
  * @endcode
  *
  * Once you have processed the input, you have your choice of returning HTML
diff --git a/core/includes/batch.inc b/core/includes/batch.inc
index 8a8f7f2..47f85ed 100644
--- a/core/includes/batch.inc
+++ b/core/includes/batch.inc
@@ -470,7 +470,7 @@ function _batch_finished() {
     // If no redirection happened, redirect to the originating page. In case the
     // form needs to be rebuilt, save the final $form_state for
     // \Drupal\Core\Form\FormBuilderInterface::buildForm().
-    if (!empty($_batch['form_state']['rebuild'])) {
+    if ($_batch['form_state']->isRebuilding()) {
       $_SESSION['batch_form_state'] = $_batch['form_state'];
     }
     $callback = $_batch['redirect_callback'];
diff --git a/core/includes/form.inc b/core/includes/form.inc
index d8349d0..4764d19 100644
--- a/core/includes/form.inc
+++ b/core/includes/form.inc
@@ -136,7 +136,7 @@ function form_state_values_clean(FormStateInterface $form_state) {
   // Remove button values.
   // form_builder() collects all button elements in a form. We remove the button
   // value separately for each button element.
-  foreach ($form_state['buttons'] as $button) {
+  foreach ($form_state->getButtons() as $button) {
     // Remove this button's value from the submitted form values by finding
     // the value corresponding to this button.
     // We iterate over the #parents of this button and move a reference to
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 7d23bb9..3b914a7 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -814,7 +814,7 @@ function install_get_form($form_id, array &$install_state) {
     $form = $form_builder->buildForm($form_id, $form_state);
     // If the form submission was not successful, the form needs to be rendered,
     // which means the task is not complete yet.
-    if (empty($form_state['executed'])) {
+    if (!$form_state->isExecuted()) {
       $install_state['task_not_complete'] = TRUE;
       return $form;
     }
diff --git a/core/lib/Drupal/Core/Block/BlockBase.php b/core/lib/Drupal/Core/Block/BlockBase.php
index c9db77a..11890c8 100644
--- a/core/lib/Drupal/Core/Block/BlockBase.php
+++ b/core/lib/Drupal/Core/Block/BlockBase.php
@@ -360,7 +360,7 @@ public function validateConfigurationForm(array &$form, FormStateInterface $form
         ->setValues($form_state->getValue(['visibility', $condition_id]));
       $condition->validateConfigurationForm($form, $condition_values);
       // Update the original form values.
-      $form_state->setValue(array('visibility', $condition_id), $condition_values['values']);
+      $form_state->setValue(['visibility', $condition_id], $condition_values->getValues());
     }
 
     $this->blockValidate($form, $form_state);
@@ -392,7 +392,7 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s
           ->setValues($form_state->getValue(['visibility', $condition_id]));
         $condition->submitConfigurationForm($form, $condition_values);
         // Update the original form values.
-        $form_state->setValue(array('visibility', $condition_id), $condition_values['values']);
+        $form_state->setValue(['visibility', $condition_id], $condition_values->getValues());
       }
       $this->blockSubmit($form, $form_state);
     }
diff --git a/core/lib/Drupal/Core/Controller/FormController.php b/core/lib/Drupal/Core/Controller/FormController.php
index 95e3eb5..a9b7a08 100644
--- a/core/lib/Drupal/Core/Controller/FormController.php
+++ b/core/lib/Drupal/Core/Controller/FormController.php
@@ -76,7 +76,7 @@ public function getContentResult(Request $request) {
 
     // Remove $form and $form_state from the arguments, and re-index them.
     unset($args[0], $args[1]);
-    $form_state['build_info']['args'] = array_values($args);
+    $form_state->addBuildInfo('args', array_values($args));
 
     return $this->formBuilder->buildForm($form_object, $form_state);
   }
diff --git a/core/lib/Drupal/Core/Datetime/Element/Datetime.php b/core/lib/Drupal/Core/Datetime/Element/Datetime.php
index 583372b..df0847e 100644
--- a/core/lib/Drupal/Core/Datetime/Element/Datetime.php
+++ b/core/lib/Drupal/Core/Datetime/Element/Datetime.php
@@ -330,7 +330,7 @@ public static function processDatetime(&$element, FormStateInterface $form_state
    */
   public static function validateDatetime(&$element, FormStateInterface $form_state, &$complete_form) {
     $input_exists = FALSE;
-    $input = NestedArray::getValue($form_state['values'], $element['#parents'], $input_exists);
+    $input = NestedArray::getValue($form_state->getValues(), $element['#parents'], $input_exists);
     if ($input_exists) {
 
       $title = !empty($element['#title']) ? $element['#title'] : '';
diff --git a/core/lib/Drupal/Core/Entity/ContentEntityForm.php b/core/lib/Drupal/Core/Entity/ContentEntityForm.php
index 87883bd..f1a10ca 100644
--- a/core/lib/Drupal/Core/Entity/ContentEntityForm.php
+++ b/core/lib/Drupal/Core/Entity/ContentEntityForm.php
@@ -64,7 +64,7 @@ public function validate(array $form, FormStateInterface $form_state) {
 
     // @todo Remove this.
     // Execute legacy global validation handlers.
-    unset($form_state['validate_handlers']);
+    $form_state->setValidateHandlers([]);
     form_execute_handlers('validate', $form, $form_state);
   }
 
@@ -87,13 +87,13 @@ protected function init(FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function getFormLangcode(FormStateInterface $form_state) {
-    if (empty($form_state['langcode'])) {
+    if (!$form_state->has('langcode')) {
       // Imply a 'view' operation to ensure users edit entities in the same
       // language they are displayed. This allows to keep contextual editing
       // working also for multilingual entities.
-      $form_state['langcode'] = $this->entityManager->getTranslationFromContext($this->entity)->language()->id;
+      $form_state->set('langcode', $this->entityManager->getTranslationFromContext($this->entity)->language()->id);
     }
-    return $form_state['langcode'];
+    return $form_state->get('langcode');
   }
 
   /**
@@ -124,14 +124,14 @@ protected function copyFormValuesToEntity(EntityInterface $entity, array $form,
    * {@inheritdoc}
    */
   public function getFormDisplay(FormStateInterface $form_state) {
-    return isset($form_state['form_display']) ? $form_state['form_display'] : NULL;
+    return $form_state->get('form_display');
   }
 
   /**
    * {@inheritdoc}
    */
   public function setFormDisplay(EntityFormDisplayInterface $form_display, FormStateInterface $form_state) {
-    $form_state['form_display'] = $form_display;
+    $form_state->set('form_display', $form_display);
     return $this;
   }
 
diff --git a/core/lib/Drupal/Core/Entity/EntityForm.php b/core/lib/Drupal/Core/Entity/EntityForm.php
index e5b8ba6..5e18679 100644
--- a/core/lib/Drupal/Core/Entity/EntityForm.php
+++ b/core/lib/Drupal/Core/Entity/EntityForm.php
@@ -89,7 +89,7 @@ public function getFormId() {
   public function buildForm(array $form, FormStateInterface $form_state) {
     // During the initial form build, add this form object to the form state and
     // allow for initial preparation before form building and processing.
-    if (!isset($form_state['entity_form_initialized'])) {
+    if (!$form_state->has('entity_form_initialized')) {
       $this->init($form_state);
     }
 
@@ -110,7 +110,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    */
   protected function init(FormStateInterface $form_state) {
     // Flag that this form has been initialized.
-    $form_state['entity_form_initialized'] = TRUE;
+    $form_state->set('entity_form_initialized', TRUE);
 
     // Prepare the entity to be presented in the entity form.
     $this->prepareEntity();
@@ -235,7 +235,7 @@ public function validate(array $form, FormStateInterface $form_state) {
     $this->updateFormLangcode($form_state);
     // @todo Remove this.
     // Execute legacy global validation handlers.
-    unset($form_state['validate_handlers']);
+    $form_state->setValidateHandlers([]);
     form_execute_handlers('validate', $form, $form_state);
   }
 
@@ -293,7 +293,7 @@ public function isDefaultFormLangcode(FormStateInterface $form_state) {
   protected function updateFormLangcode(FormStateInterface $form_state) {
     // Update the form language as it might have changed.
     if ($form_state->hasValue('langcode') && $this->isDefaultFormLangcode($form_state)) {
-      $form_state['langcode'] = $form_state->getValue('langcode');
+      $form_state->set('langcode', $form_state->getValue('langcode'));
     }
   }
 
diff --git a/core/lib/Drupal/Core/Entity/EntityFormBuilderInterface.php b/core/lib/Drupal/Core/Entity/EntityFormBuilderInterface.php
index 584595f..889ed6b 100644
--- a/core/lib/Drupal/Core/Entity/EntityFormBuilderInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityFormBuilderInterface.php
@@ -30,8 +30,8 @@
    *   langcode. Defaults to an empty array.
    *
    * @code
-   *   $form_state['langcode'] = $langcode;
-   *   $form = \Drupal::service('entity.form_builder')->getForm($entity, 'default', $form_state);
+   *   $form_state_additions['langcode'] = $langcode;
+   *   $form = \Drupal::service('entity.form_builder')->getForm($entity, 'default', $form_state_additions);
    * @endcode
    *
    * @return array
diff --git a/core/lib/Drupal/Core/Field/FieldItemList.php b/core/lib/Drupal/Core/Field/FieldItemList.php
index d10ecb4..6b70f96 100644
--- a/core/lib/Drupal/Core/Field/FieldItemList.php
+++ b/core/lib/Drupal/Core/Field/FieldItemList.php
@@ -368,7 +368,7 @@ public static function processDefaultValue($default_value, ContentEntityInterfac
    *   A Widget object.
    */
   protected function defaultValueWidget(FormStateInterface $form_state) {
-    if (!isset($form_state['default_value_widget'])) {
+    if (!$form_state->has('default_value_widget')) {
       $entity = $this->getEntity();
 
       // Force a non-required widget.
@@ -383,10 +383,10 @@ protected function defaultValueWidget(FormStateInterface $form_state) {
         $widget = \Drupal::service('plugin.manager.field.widget')->getInstance(array('field_definition' => $this->getFieldDefinition()));
       }
 
-      $form_state['default_value_widget'] = $widget;
+      $form_state->set('default_value_widget', $widget);
     }
 
-    return $form_state['default_value_widget'];
+    return $form_state->get('default_value_widget');
   }
 
 }
diff --git a/core/lib/Drupal/Core/Field/WidgetBase.php b/core/lib/Drupal/Core/Field/WidgetBase.php
index 50f67a5..44fe57a 100644
--- a/core/lib/Drupal/Core/Field/WidgetBase.php
+++ b/core/lib/Drupal/Core/Field/WidgetBase.php
@@ -106,8 +106,8 @@ public function form(FieldItemListInterface $items, array &$form, FormStateInter
       $elements = $this->formMultipleElements($items, $form, $form_state);
     }
 
-    // Populate the 'array_parents' information in $form_state['field'] after
-    // the form is built, so that we catch changes in the form structure
+    // Populate the 'array_parents' information in $form_state->get('field')
+    // after the form is built, so that we catch changes in the form structure
     // performed in alter() hooks.
     $elements['#after_build'][] = array(get_class($this), 'afterBuild');
     $elements['#field_name'] = $field_name;
@@ -207,8 +207,7 @@ protected function formMultipleElements(FieldItemListInterface $items, array &$f
       );
 
       // Add 'add more' button, if not working with a programmed form.
-      if ($cardinality == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED && empty($form_state['programmed'])) {
-
+      if ($cardinality == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED && !$form_state->isProgrammed()) {
         $id_prefix = implode('-', array_merge($parents, array($field_name)));
         $wrapper_id = drupal_html_id($id_prefix . '-add-more-wrapper');
         $elements['#prefix'] = '<div id="' . $wrapper_id . '">';
@@ -254,7 +253,7 @@ public static function afterBuild(array $element, FormStateInterface $form_state
    * Submission handler for the "Add another item" button.
    */
   public static function addMoreSubmit(array $form, FormStateInterface $form_state) {
-    $button = $form_state['triggering_element'];
+    $button = $form_state->getTriggeringElement();
 
     // Go one level up in the form, to the widgets container.
     $element = NestedArray::getValue($form, array_slice($button['#array_parents'], 0, -1));
@@ -266,7 +265,7 @@ public static function addMoreSubmit(array $form, FormStateInterface $form_state
     $field_state['items_count']++;
     static::setWidgetState($parents, $field_name, $form_state, $field_state);
 
-    $form_state['rebuild'] = TRUE;
+    $form_state->setRebuild();
   }
 
   /**
@@ -276,7 +275,7 @@ public static function addMoreSubmit(array $form, FormStateInterface $form_state
    * by the form submission.
    */
   public static function addMoreAjax(array $form, FormStateInterface $form_state) {
-    $button = $form_state['triggering_element'];
+    $button = $form_state->getTriggeringElement();
 
     // Go one level up in the form, to the widgets container.
     $element = NestedArray::getValue($form, array_slice($button['#array_parents'], 0, -1));
@@ -439,14 +438,14 @@ public function flagErrors(FieldItemListInterface $items, ConstraintViolationLis
    * {@inheritdoc}
    */
   public static function getWidgetState(array $parents, $field_name, FormStateInterface $form_state) {
-    return NestedArray::getValue($form_state['storage'], static::getWidgetStateParents($parents, $field_name));
+    return NestedArray::getValue($form_state->getStorage(), static::getWidgetStateParents($parents, $field_name));
   }
 
   /**
    * {@inheritdoc}
    */
   public static function setWidgetState(array $parents, $field_name, FormStateInterface $form_state, array $field_state) {
-    NestedArray::setValue($form_state['storage'], static::getWidgetStateParents($parents, $field_name), $field_state);
+    NestedArray::setValue($form_state->getStorage(), static::getWidgetStateParents($parents, $field_name), $field_state);
   }
 
   /**
@@ -462,7 +461,7 @@ public static function setWidgetState(array $parents, $field_name, FormStateInte
    */
   protected static function getWidgetStateParents(array $parents, $field_name) {
     // Field processing data is placed at
-    // $form_state['field']['#parents'][...$parents...]['#fields'][$field_name],
+    // $form_state->get(['field', '#parents', ...$parents..., '#fields', $field_name]),
     // to avoid clashes between field names and $parents parts.
     return array_merge(array('field', '#parents'), $parents, array('#fields', $field_name));
   }
diff --git a/core/lib/Drupal/Core/FileTransfer/Form/FileTransferAuthorizeForm.php b/core/lib/Drupal/Core/FileTransfer/Form/FileTransferAuthorizeForm.php
index dfc2a8f..e163c04 100644
--- a/core/lib/Drupal/Core/FileTransfer/Form/FileTransferAuthorizeForm.php
+++ b/core/lib/Drupal/Core/FileTransfer/Form/FileTransferAuthorizeForm.php
@@ -140,7 +140,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
   public function validateForm(array &$form, FormStateInterface $form_state) {
     // Only validate the form if we have collected all of the user input and are
     // ready to proceed with updating or installing.
-    if ($form_state['triggering_element']['#name'] != 'process_updates') {
+    if ($form_state->getTriggeringElement()['#name'] != 'process_updates') {
       return;
     }
 
@@ -169,7 +169,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
     $form_connection_settings = $form_state->getValue('connection_settings');
-    switch ($form_state['triggering_element']['#name']) {
+    switch ($form_state->getTriggeringElement()['#name']) {
       case 'process_updates':
 
         // Save the connection settings to the DB.
@@ -214,11 +214,11 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
         break;
 
       case 'enter_connection_settings':
-        $form_state['rebuild'] = TRUE;
+        $form_state->setRebuild();
         break;
 
       case 'change_connection_type':
-        $form_state['rebuild'] = TRUE;
+        $form_state->setRebuild();
         $form_state->unsetValue(array('connection_settings', 'authorize_filetransfer_default'));
         break;
     }
diff --git a/core/lib/Drupal/Core/Form/FormState.php b/core/lib/Drupal/Core/Form/FormState.php
index 557ac0f..b91eb2f 100644
--- a/core/lib/Drupal/Core/Form/FormState.php
+++ b/core/lib/Drupal/Core/Form/FormState.php
@@ -13,10 +13,8 @@
 
 /**
  * Stores information about the state of a form.
- *
- * @todo Remove usage of \ArrayAccess in https://www.drupal.org/node/2310255.
  */
-class FormState implements FormStateInterface, \ArrayAccess {
+class FormState implements FormStateInterface {
 
   /**
    * Tracks if any errors have been set on any form.
@@ -810,61 +808,6 @@ public function &getCompleteForm() {
 
   /**
    * {@inheritdoc}
-   *
-   * @deprecated in Drupal 8.0.x, might be removed before Drupal 8.0.0.
-   */
-  public function offsetExists($offset) {
-    return isset($this->{$offset}) || isset($this->storage[$offset]);
-  }
-
-  /**
-   * {@inheritdoc}
-   *
-   * @deprecated in Drupal 8.0.x, might be removed before Drupal 8.0.0.
-   */
-  public function &offsetGet($offset) {
-    if (property_exists($this, $offset)) {
-      $value = &$this->{$offset};
-    }
-    else {
-      if (!isset($this->storage[$offset])) {
-        $this->storage[$offset] = NULL;
-      }
-      $value = &$this->get($offset);
-    }
-    return $value;
-  }
-
-  /**
-   * {@inheritdoc}
-   *
-   * @deprecated in Drupal 8.0.x, might be removed before Drupal 8.0.0.
-   */
-  public function offsetSet($offset, $value) {
-    if (property_exists($this, $offset)) {
-      $this->{$offset} = $value;
-    }
-    else {
-      $this->set($offset, $value);
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   *
-   * @deprecated in Drupal 8.0.x, might be removed before Drupal 8.0.0.
-   */
-  public function offsetUnset($offset) {
-    if (property_exists($this, $offset)) {
-      $this->{$offset} = NULL;
-    }
-    else {
-      unset($this->storage[$offset]);
-    }
-  }
-
-  /**
-   * {@inheritdoc}
    */
   public function &get($property) {
     $value = &NestedArray::getValue($this->storage, (array) $property);
diff --git a/core/lib/Drupal/Core/Installer/Form/SelectLanguageForm.php b/core/lib/Drupal/Core/Installer/Form/SelectLanguageForm.php
index 5a00f24..79d9082 100644
--- a/core/lib/Drupal/Core/Installer/Form/SelectLanguageForm.php
+++ b/core/lib/Drupal/Core/Installer/Form/SelectLanguageForm.php
@@ -93,8 +93,9 @@ public function buildForm(array $form, FormStateInterface $form_state, $install_
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $install_state = &$form_state['build_info']['args'][0];
-    $install_state['parameters']['langcode'] = $form_state->getValue('langcode');
+    $build_info = $form_state->getBuildInfo();
+    $build_info['args'][0]['parameters']['langcode'] = $form_state->getValue('langcode');
+    $form_state->setBuildInfo($build_info);
   }
 
 }
diff --git a/core/lib/Drupal/Core/Installer/Form/SiteSettingsForm.php b/core/lib/Drupal/Core/Installer/Form/SiteSettingsForm.php
index 48fadf6..8cf65c9 100644
--- a/core/lib/Drupal/Core/Installer/Form/SiteSettingsForm.php
+++ b/core/lib/Drupal/Core/Installer/Form/SiteSettingsForm.php
@@ -126,7 +126,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
     $database['namespace'] = substr($install_namespace, 0, strrpos($install_namespace, '\\'));
     $database['driver'] = $driver;
 
-    $form_state['storage']['database'] = $database;
+    $form_state->set('database', $database);
     $errors = install_database_errors($database, $form_state->getValue('settings_file'));
     foreach ($errors as $name => $message) {
       $form_state->setErrorByName($name, $message);
@@ -141,7 +141,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
 
     // Update global settings array and save.
     $settings = array();
-    $database = $form_state['storage']['database'];
+    $database = $form_state->get('database');
     $settings['databases']['default']['default'] = (object) array(
       'value'    => $database,
       'required' => TRUE,
diff --git a/core/lib/Drupal/Core/Render/Element/MachineName.php b/core/lib/Drupal/Core/Render/Element/MachineName.php
index 6301f35..6b9a29b 100644
--- a/core/lib/Drupal/Core/Render/Element/MachineName.php
+++ b/core/lib/Drupal/Core/Render/Element/MachineName.php
@@ -142,7 +142,7 @@ public static function processMachineName(&$element, FormStateInterface $form_st
     // complete form in $form_state. By reference, because we may need to append
     // a #field_suffix that will hold the live preview.
     $key_exists = NULL;
-    $source = NestedArray::getValue($form_state['complete_form'], $element['#machine_name']['source'], $key_exists);
+    $source = NestedArray::getValue($form_state->getCompleteForm(), $element['#machine_name']['source'], $key_exists);
     if (!$key_exists) {
       return $element;
     }
@@ -160,7 +160,7 @@ public static function processMachineName(&$element, FormStateInterface $form_st
       $source['#field_suffix'] = SafeMarkup::set($source['#field_suffix'] . ' <small id="' . $suffix_id . '">&nbsp;</small>');
 
       $parents = array_merge($element['#machine_name']['source'], array('#field_suffix'));
-      NestedArray::setValue($form_state['complete_form'], $parents, $source['#field_suffix']);
+      NestedArray::setValue($form_state->getCompleteForm(), $parents, $source['#field_suffix']);
     }
 
     $js_settings = array(
diff --git a/core/lib/Drupal/Core/Render/Element/PasswordConfirm.php b/core/lib/Drupal/Core/Render/Element/PasswordConfirm.php
index f3ea4e8..9bc32b7 100644
--- a/core/lib/Drupal/Core/Render/Element/PasswordConfirm.php
+++ b/core/lib/Drupal/Core/Render/Element/PasswordConfirm.php
@@ -82,7 +82,7 @@ public static function validatePasswordConfirm(&$element, FormStateInterface $fo
         $form_state->setError($element, t('The specified passwords do not match.'));
       }
     }
-    elseif ($element['#required'] && !empty($form_state['input'])) {
+    elseif ($element['#required'] && $form_state->getUserInput()) {
       $form_state->setError($element, t('Password field is required.'));
     }
 
diff --git a/core/lib/Drupal/Core/Render/Element/RenderElement.php b/core/lib/Drupal/Core/Render/Element/RenderElement.php
index 3cbe18c..c3a74d8 100644
--- a/core/lib/Drupal/Core/Render/Element/RenderElement.php
+++ b/core/lib/Drupal/Core/Render/Element/RenderElement.php
@@ -128,7 +128,7 @@ public static function preRenderGroup($element) {
   public static function processAjaxForm(&$element, FormStateInterface $form_state, &$complete_form) {
     $element = ajax_pre_render_element($element);
     if (!empty($element['#ajax_processed'])) {
-      $form_state['cache'] = TRUE;
+      $form_state->setCached();
     }
     return $element;
   }
@@ -156,14 +156,15 @@ public static function processGroup(&$element, FormStateInterface $form_state, &
 
     // Each details element forms a new group. The #type 'vertical_tabs' basically
     // only injects a new details element.
-    $form_state['groups'][$parents]['#group_exists'] = TRUE;
-    $element['#groups'] = &$form_state['groups'];
+    $groups = &$form_state->getGroups();
+    $groups[$parents]['#group_exists'] = TRUE;
+    $element['#groups'] = &$groups;
 
     // Process vertical tabs group member details elements.
     if (isset($element['#group'])) {
       // Add this details element to the defined group (by reference).
       $group = $element['#group'];
-      $form_state['groups'][$group][] = &$element;
+      $groups[$group][] = &$element;
     }
 
     return $element;
diff --git a/core/lib/Drupal/Core/Render/Element/Table.php b/core/lib/Drupal/Core/Render/Element/Table.php
index 3751a29..29c8303 100644
--- a/core/lib/Drupal/Core/Render/Element/Table.php
+++ b/core/lib/Drupal/Core/Render/Element/Table.php
@@ -219,7 +219,8 @@ public static function processTable(&$element, FormStateInterface $form_state, &
   public static function validateTable(&$element, FormStateInterface $form_state, &$complete_form) {
     // Skip this validation if the button to submit the form does not require
     // selected table row data.
-    if (empty($form_state['triggering_element']['#tableselect'])) {
+    $trigerring_element = $form_state->getTriggeringElement();
+    if (empty($trigerring_element['#tableselect'])) {
       return;
     }
     if ($element['#multiple']) {
diff --git a/core/modules/block/src/BlockForm.php b/core/modules/block/src/BlockForm.php
index 128abe1..73e7ea4 100644
--- a/core/modules/block/src/BlockForm.php
+++ b/core/modules/block/src/BlockForm.php
@@ -61,7 +61,7 @@ public function form(array $form, FormStateInterface $form_state) {
     if (!$theme = $entity->get('theme')) {
       $theme = $this->config('system.theme')->get('default');
     }
-    $form_state['block_theme'] = $theme;
+    $form_state->set('block_theme', $theme);
 
     $form['#tree'] = TRUE;
     $form['settings'] = $entity->getPlugin()->buildConfigurationForm(array(), $form_state);
@@ -153,7 +153,7 @@ public function validate(array $form, FormStateInterface $form_state) {
     // Call the plugin validate handler.
     $this->entity->getPlugin()->validateConfigurationForm($form, $settings);
     // Update the original form values.
-    $form_state->setValue('settings', $settings['values']);
+    $form_state->setValue('settings', $settings->getValues());
   }
 
   /**
@@ -171,7 +171,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     // Call the plugin submit handler.
     $entity->getPlugin()->submitConfigurationForm($form, $settings);
     // Update the original form values.
-    $form_state->setValue('settings', $settings['values']);
+    $form_state->setValue('settings', $settings->getValues());
 
     // Save the settings of the plugin.
     $entity->save();
diff --git a/core/modules/block_content/src/BlockContentForm.php b/core/modules/block_content/src/BlockContentForm.php
index d1a422f..df923ee 100644
--- a/core/modules/block_content/src/BlockContentForm.php
+++ b/core/modules/block_content/src/BlockContentForm.php
@@ -202,7 +202,7 @@ public function save(array $form, FormStateInterface $form_state) {
 
     if ($block->id()) {
       $form_state->setValue('id', $block->id());
-      $form_state['id'] = $block->id();
+      $form_state->set('id', $block->id());
       if ($insert) {
         if (!$theme = $block->getTheme()) {
           $theme = $this->config('system.theme')->get('default');
@@ -223,7 +223,7 @@ public function save(array $form, FormStateInterface $form_state) {
       // In the unlikely case something went wrong on save, the block will be
       // rebuilt and block form redisplayed.
       drupal_set_message($this->t('The block could not be saved.'), 'error');
-      $form_state['rebuild'] = TRUE;
+      $form_state->setRebuild();
     }
   }
 
diff --git a/core/modules/book/book.module b/core/modules/book/book.module
index 5e87f43..e67b279 100644
--- a/core/modules/book/book.module
+++ b/core/modules/book/book.module
@@ -219,7 +219,7 @@ function book_node_builder($entity_type, NodeInterface $entity, &$form, FormStat
 function book_pick_book_nojs_submit($form, FormStateInterface $form_state) {
   $node = $form_state->getFormObject()->getEntity();
   $node->book = $form_state->getValue('book');
-  $form_state['rebuild'] = TRUE;
+  $form_state->setRebuild();
 }
 
 /**
diff --git a/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalImage.php b/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalImage.php
index e6e54b8..b0c88bf 100644
--- a/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalImage.php
+++ b/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalImage.php
@@ -86,7 +86,7 @@ public function settingsForm(array $form, FormStateInterface $form_state, Editor
    */
   function validateImageUploadSettings(array $element, FormStateInterface $form_state) {
     $settings = &$form_state->getValue(array('editor', 'settings', 'plugins', 'drupalimage', 'image_upload'));
-    $form_state['editor']->setImageUploadSettings($settings);
+    $form_state->get('editor')->setImageUploadSettings($settings);
     $form_state->unsetValue(array('editor', 'settings', 'plugins', 'drupalimage'));
   }
 
diff --git a/core/modules/color/color.module b/core/modules/color/color.module
index 7010ddf..a0c0896 100644
--- a/core/modules/color/color.module
+++ b/core/modules/color/color.module
@@ -47,7 +47,8 @@ function color_theme() {
  * Implements hook_form_FORM_ID_alter().
  */
 function color_form_system_theme_settings_alter(&$form, FormStateInterface $form_state) {
-  if (isset($form_state['build_info']['args'][0]) && ($theme = $form_state['build_info']['args'][0]) && color_get_info($theme) && function_exists('gd_info')) {
+  $build_info = $form_state->getBuildInfo();
+  if (isset($build_info['args'][0]) && ($theme = $build_info['args'][0]) && color_get_info($theme) && function_exists('gd_info')) {
     $form['color'] = array(
       '#type' => 'details',
       '#title' => t('Color scheme'),
@@ -303,7 +304,8 @@ function color_palette_color_value($element, $input = FALSE, FormStateInterface
     // Start with the provided value for this textfield, and validate that if
     // necessary, falling back on the default value.
     $value = Textfield::valueCallback($element, $input, $form_state);
-    if (!$value || !isset($form_state['complete form']['#token']) || color_valid_hexadecimal_string($value) || \Drupal::csrfToken()->validate($form_state->getValue('form_token'), $form_state['complete form']['#token'])) {
+    $complete_form = $form_state->getCompleteForm();
+    if (!$value || !isset($complete_form['#token']) || color_valid_hexadecimal_string($value) || \Drupal::csrfToken()->validate($form_state->getValue('form_token'), $complete_form['#token'])) {
       return $value;
     }
     else {
diff --git a/core/modules/comment/src/CommentForm.php b/core/modules/comment/src/CommentForm.php
index 045b360..2c99bf8 100644
--- a/core/modules/comment/src/CommentForm.php
+++ b/core/modules/comment/src/CommentForm.php
@@ -98,8 +98,9 @@ public function form(array $form, FormStateInterface $form_state) {
       $form['#action'] = url('comment/reply/' . $entity->getEntityTypeId() . '/' . $entity->id() . '/' . $field_name);
     }
 
-    if (isset($form_state['comment_preview'])) {
-      $form += $form_state['comment_preview'];
+    $comment_preview = $form_state->get('comment_preview');
+    if (isset($comment_preview)) {
+      $form += $comment_preview;
     }
 
     $form['author'] = array();
@@ -115,7 +116,7 @@ public function form(array $form, FormStateInterface $form_state) {
     if ($is_admin) {
       $author = $comment->getAuthorName();
       $status = $comment->getStatus();
-      if (empty($form_state['comment_preview'])) {
+      if (empty($comment_preview)) {
         $form['#title'] = $this->t('Edit comment %title', array(
           '%title' => $comment->getSubject(),
         ));
@@ -238,7 +239,7 @@ protected function actions(array $form, FormStateInterface $form_state) {
 
     // Only show the save button if comment previews are optional or if we are
     // already previewing the submission.
-    $element['submit']['#access'] = ($comment->id() && $this->currentUser->hasPermission('administer comments')) || $preview_mode != DRUPAL_REQUIRED || isset($form_state['comment_preview']);
+    $element['submit']['#access'] = ($comment->id() && $this->currentUser->hasPermission('administer comments')) || $preview_mode != DRUPAL_REQUIRED || $form_state->get('comment_preview');
 
     $element['preview'] = array(
       '#type' => 'submit',
@@ -348,10 +349,10 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
    *   The current state of the form.
    */
   public function preview(array &$form, FormStateInterface $form_state) {
-    $comment = $this->entity;
-    $form_state['comment_preview'] = comment_preview($comment, $form_state);
-    $form_state['comment_preview']['#title'] = $this->t('Preview comment');
-    $form_state['rebuild'] = TRUE;
+    $comment_preview = comment_preview($this->entity, $form_state);
+    $comment_preview['#title'] = $this->t('Preview comment');
+    $form_state->set('comment_preview', $comment_preview);
+    $form_state->setRebuild();
   }
 
   /**
diff --git a/core/modules/config/src/Form/ConfigSingleImportForm.php b/core/modules/config/src/Form/ConfigSingleImportForm.php
index 5150746..5d7a541 100644
--- a/core/modules/config/src/Form/ConfigSingleImportForm.php
+++ b/core/modules/config/src/Form/ConfigSingleImportForm.php
@@ -236,7 +236,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
   public function submitForm(array &$form, FormStateInterface $form_state) {
     // If this form has not yet been confirmed, store the values and rebuild.
     if (!$this->data) {
-      $form_state['rebuild'] = TRUE;
+      $form_state->setRebuild();
       $this->data = $form_state->getValues();
       return;
     }
diff --git a/core/modules/config/src/Form/ConfigSync.php b/core/modules/config/src/Form/ConfigSync.php
index 70c0c73..05682a0 100644
--- a/core/modules/config/src/Form/ConfigSync.php
+++ b/core/modules/config/src/Form/ConfigSync.php
@@ -179,7 +179,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     }
     else {
       // Store the comparer for use in the submit.
-      $form_state['storage_comparer'] = $storage_comparer;
+      $form_state->set('storage_comparer', $storage_comparer);
     }
 
     // Add the AJAX library to the form for dialog support.
@@ -273,7 +273,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
     $config_importer = new ConfigImporter(
-      $form_state['storage_comparer'],
+      $form_state->get('storage_comparer'),
       $this->eventDispatcher,
       $this->configManager,
       $this->lock,
diff --git a/core/modules/config_translation/src/Form/ConfigTranslationFormBase.php b/core/modules/config_translation/src/Form/ConfigTranslationFormBase.php
index d3d63be..d195d24 100644
--- a/core/modules/config_translation/src/Form/ConfigTranslationFormBase.php
+++ b/core/modules/config_translation/src/Form/ConfigTranslationFormBase.php
@@ -173,9 +173,9 @@ public function buildForm(array $form, FormStateInterface $form_state, Request $
     $this->languageManager->setConfigOverrideLanguage($this->language);
 
     // Add some information to the form state for easier form altering.
-    $form_state['config_translation_mapper'] = $this->mapper;
-    $form_state['config_translation_language'] = $this->language;
-    $form_state['config_translation_source_language'] = $this->sourceLanguage;
+    $form_state->set('config_translation_mapper', $this->mapper);
+    $form_state->set('config_translation_language', $this->language);
+    $form_state->set('config_translation_source_language', $this->sourceLanguage);
 
     $form['#attached']['library'][] = 'config_translation/drupal.config_translation.admin';
 
diff --git a/core/modules/config_translation/src/FormElement/DateFormat.php b/core/modules/config_translation/src/FormElement/DateFormat.php
index 9076d2a..b19c66c 100644
--- a/core/modules/config_translation/src/FormElement/DateFormat.php
+++ b/core/modules/config_translation/src/FormElement/DateFormat.php
@@ -58,7 +58,7 @@ public function getFormElement(DataDefinitionInterface $definition, LanguageInte
   public static function ajaxSample(array $form, FormStateInterface $form_state) {
     $response = new AjaxResponse();
 
-    $format_value = NestedArray::getValue($form_state->getValues(), $form_state['triggering_element']['#array_parents']);
+    $format_value = NestedArray::getValue($form_state->getValues(), $form_state->getTriggeringElement()['#array_parents']);
     if (!empty($format_value)) {
       // Format the date with a custom date format with the given pattern.
       // The object is not instantiated in an Ajax context, so $this->t()
diff --git a/core/modules/contact/src/MessageForm.php b/core/modules/contact/src/MessageForm.php
index 3414858..ae89455 100644
--- a/core/modules/contact/src/MessageForm.php
+++ b/core/modules/contact/src/MessageForm.php
@@ -168,7 +168,7 @@ public function actions(array $form, FormStateInterface $form_state) {
   public function preview(array $form, FormStateInterface $form_state) {
     $message = $this->entity;
     $message->preview = TRUE;
-    $form_state['rebuild'] = TRUE;
+    $form_state->setRebuild();
   }
 
   /**
diff --git a/core/modules/content_translation/content_translation.module b/core/modules/content_translation/content_translation.module
index dddad7c..bceb815 100644
--- a/core/modules/content_translation/content_translation.module
+++ b/core/modules/content_translation/content_translation.module
@@ -603,7 +603,7 @@ function content_translation_entity_extra_field_info() {
  * Implements hook_form_FORM_ID_alter() for 'field_ui_instance_edit_form'.
  */
 function content_translation_form_field_ui_field_instance_edit_form_alter(array &$form, FormStateInterface $form_state) {
-  $instance = $form_state['instance'];
+  $instance = $form_state->get('instance');
   $bundle_is_translatable = content_translation_enabled($instance->entity_type, $instance->bundle);
 
   $form['instance']['translatable'] = array(
@@ -674,11 +674,10 @@ function content_translation_element_info_alter(&$type) {
  *   The current state of the form.
  */
 function content_translation_enable_widget($entity_type, $bundle, array &$form, FormStateInterface $form_state) {
-  $key = $form_state['content_translation']['key'];
-  if (!isset($form_state['language'][$key])) {
-    $form_state['language'][$key] = array();
-  }
-  $form_state['language'][$key] += array('entity_type' => $entity_type, 'bundle' => $bundle);
+  $key = $form_state->get(['content_translation', 'key']);
+  $context = $form_state->get(['language', $key]) ?: [];
+  $context += ['entity_type' => $entity_type, 'bundle' => $bundle];
+  $form_state->set(['language', $key], $context);
   $element = content_translation_language_configuration_element_process(array('#name' => $key), $form_state, $form);
   unset($element['content_translation']['#element_validate']);
   return $element;
@@ -695,8 +694,9 @@ function content_translation_enable_widget($entity_type, $bundle, array &$form,
  */
 function content_translation_language_configuration_element_process(array $element, FormStateInterface $form_state, array &$form) {
   if (empty($element['#content_translation_skip_alter']) && \Drupal::currentUser()->hasPermission('administer content translation')) {
-    $form_state['content_translation']['key'] = $element['#name'];
-    $context = $form_state['language'][$element['#name']];
+    $key = $element['#name'];
+    $form_state->set(['content_translation', 'key'], $key);
+    $context = $form_state->get(['language', $key]);
 
     $element['content_translation'] = array(
       '#type' => 'checkbox',
@@ -721,7 +721,7 @@ function content_translation_language_configuration_element_process(array $eleme
  * @see content_translation_language_configuration_element_submit()
  */
 function content_translation_language_configuration_element_validate($element, FormStateInterface $form_state, array $form) {
-  $key = $form_state['content_translation']['key'];
+  $key = $form_state->get(['content_translation', 'key']);
   $values = $form_state->getValue($key);
   if (!$values['language_show'] && $values['content_translation'] && \Drupal::languageManager()->isLanguageLocked($values['langcode'])) {
     foreach (\Drupal::languageManager()->getLanguages(LanguageInterface::STATE_LOCKED) as $language) {
@@ -742,8 +742,8 @@ function content_translation_language_configuration_element_validate($element, F
  * @see content_translation_language_configuration_element_validate()
  */
 function content_translation_language_configuration_element_submit(array $form, FormStateInterface $form_state) {
-  $key = $form_state['content_translation']['key'];
-  $context = $form_state['language'][$key];
+  $key = $form_state->get(['content_translation', 'key']);
+  $context = $form_state->get(['language', $key]);
   $enabled = $form_state->getValue(array($key, 'content_translation'));
 
   if (content_translation_enabled($context['entity_type'], $context['bundle']) != $enabled) {
diff --git a/core/modules/content_translation/src/ContentTranslationHandler.php b/core/modules/content_translation/src/ContentTranslationHandler.php
index 60eb6f3..dcc8746 100644
--- a/core/modules/content_translation/src/ContentTranslationHandler.php
+++ b/core/modules/content_translation/src/ContentTranslationHandler.php
@@ -77,7 +77,10 @@ public function getTranslationAccess(EntityInterface $entity, $op) {
    * {@inheritdoc}
    */
   public function getSourceLangcode(FormStateInterface $form_state) {
-    return isset($form_state['content_translation']['source']) ? $form_state['content_translation']['source']->id : FALSE;
+    if ($source = $form_state->get(['content_translation', 'source'])) {
+      return $source->id;
+    }
+    return FALSE;
   }
 
   /**
@@ -315,7 +318,7 @@ public function entityFormSharedElements($element, FormStateInterface $form_stat
           // If we are displaying a multilingual entity form we need to provide
           // translatability clues, otherwise the shared form elements should be
           // hidden.
-          if (empty($form_state['content_translation']['translation_form'])) {
+          if (!$form_state->get(['content_translation', 'translation_form'])) {
             $this->addTranslatabilityClue($element[$key]);
           }
           else {
diff --git a/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeFieldItemList.php b/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeFieldItemList.php
index 5963db0..e78a194 100644
--- a/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeFieldItemList.php
+++ b/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeFieldItemList.php
@@ -69,7 +69,7 @@ public function defaultValuesForm(array &$form, FormStateInterface $form_state)
    * {@inheritdoc}
    */
   public function defaultValuesFormValidate(array $element, array &$form, FormStateInterface $form_state) {
-    if ($form_state['values']['default_value_input']['default_date_type'] == static::DEFAULT_VALUE_CUSTOM) {
+    if ($form_state->getValue(['default_value_input', 'default_date_type']) == static::DEFAULT_VALUE_CUSTOM) {
       $is_strtotime = @strtotime($form_state->getValue(array('default_value_input', 'default_date')));
       if (!$is_strtotime) {
         $form_state->setErrorByName('default_value_input][default_date', t('The relative date value entered is invalid.'));
diff --git a/core/modules/editor/editor.module b/core/modules/editor/editor.module
index 9b544ae..85f58fa 100644
--- a/core/modules/editor/editor.module
+++ b/core/modules/editor/editor.module
@@ -10,7 +10,6 @@
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Render\Element;
 use Drupal\Core\Routing\RouteMatchInterface;
-use Drupal\editor\Entity\Editor;
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\filter\FilterFormatInterface;
@@ -90,11 +89,11 @@ function editor_form_filter_admin_overview_alter(&$form, FormStateInterface $for
  * Implements hook_form_BASE_FORM_ID_alter() for 'filter_format_form'.
  */
 function editor_form_filter_format_form_alter(&$form, FormStateInterface $form_state) {
-  if (!isset($form_state['editor'])) {
+  if (!$editor = $form_state->get('editor')) {
     $format_id = $form_state->getFormObject()->getEntity()->id();
-    $form_state['editor'] = editor_load($format_id);
+    $editor = editor_load($format_id);
+    $form_state->set('editor', $editor);
   }
-  $editor = $form_state['editor'];
 
   // Associate a text editor with this text format.
   $manager = \Drupal::service('plugin.manager.editor');
@@ -167,20 +166,20 @@ function editor_form_filter_format_form_alter(&$form, FormStateInterface $form_s
  * Button submit handler for filter_format_form()'s 'editor_configure' button.
  */
 function editor_form_filter_admin_format_editor_configure($form, FormStateInterface $form_state) {
-  $editor = $form_state['editor'];
+  $editor = $form_state->get('editor');
   if ($editor_value = $form_state->getValue(array('editor', 'editor'))) {
     if ($editor_value === '') {
-      $form_state['editor'] = FALSE;
+      $form_state->set('editor', FALSE);
     }
     elseif (empty($editor) || $editor_value !== $editor->getEditor()) {
       $editor = entity_create('editor', array(
         'format' => $form_state->getFormObject()->getEntity()->id(),
         'editor' => $editor_value,
       ));
-      $form_state['editor'] = $editor;
+      $form_state->set('editor', $editor);
     }
   }
-  $form_state['rebuild'] = TRUE;
+  $form_state->setRebuild();
 }
 
 /**
@@ -195,7 +194,7 @@ function editor_form_filter_admin_form_ajax($form, FormStateInterface $form_stat
  */
 function editor_form_filter_admin_format_validate($form, FormStateInterface $form_state) {
   // This validate handler is not applicable when using the 'Configure' button.
-  if ($form_state['triggering_element']['#name'] === 'editor_configure') {
+  if ($form_state->getTriggeringElement()['#name'] === 'editor_configure') {
     return;
   }
 
@@ -203,7 +202,7 @@ function editor_form_filter_admin_format_validate($form, FormStateInterface $for
   // 'Configure' button won't be clicked automatically. So, when the user has
   // selected a text editor and has then clicked 'Save configuration', we should
   // point out that the user must still configure the text editor.
-  if ($form_state->getValue(array('editor', 'editor')) !== '' && empty($form_state['editor'])) {
+  if ($form_state->getValue(['editor', 'editor']) !== '' && !$form_state->get('editor')) {
     $form_state->setErrorByName('editor][editor', t('You must configure the selected text editor.'));
   }
 }
@@ -220,12 +219,12 @@ function editor_form_filter_admin_format_submit($form, FormStateInterface $form_
   }
 
   // Create a new editor or update the existing editor.
-  if (!empty($form_state['editor'])) {
+  if ($editor = $form_state->get('editor')) {
     // Ensure the text format is set: when creating a new text format, this
     // would equal the empty string.
-    $form_state['editor']->set('format', $format_id);
-    $form_state['editor']->setSettings($form_state->getValue(array('editor', 'settings')));
-    $form_state['editor']->save();
+    $editor->set('format', $format_id);
+    $editor->setSettings($form_state->getValue(['editor', 'settings']));
+    $editor->save();
   }
 }
 
diff --git a/core/modules/editor/src/Form/EditorImageDialog.php b/core/modules/editor/src/Form/EditorImageDialog.php
index 342f283..be51dc4 100644
--- a/core/modules/editor/src/Form/EditorImageDialog.php
+++ b/core/modules/editor/src/Form/EditorImageDialog.php
@@ -37,11 +37,11 @@ public function getFormId() {
   public function buildForm(array $form, FormStateInterface $form_state, FilterFormat $filter_format = NULL) {
     // The default values are set directly from \Drupal::request()->request,
     // provided by the editor plugin opening the dialog.
-    if (!isset($form_state['image_element'])) {
+    if (!$image_element = $form_state->get('image_element')) {
       $user_input = $form_state->getUserInput();
-      $form_state['image_element'] = isset($user_input['editor_object']) ? $user_input['editor_object'] : array();
+      $image_element = isset($user_input['editor_object']) ? $user_input['editor_object'] : [];
+      $form_state->set('image_element', $image_element);
     }
-    $image_element = $form_state['image_element'];
 
     $form['#tree'] = TRUE;
     $form['#attached']['library'][] = 'editor/drupal.editor.dialog';
diff --git a/core/modules/entity_reference/entity_reference.module b/core/modules/entity_reference/entity_reference.module
index 75ab68c..2fcfecd 100644
--- a/core/modules/entity_reference/entity_reference.module
+++ b/core/modules/entity_reference/entity_reference.module
@@ -159,8 +159,7 @@ function _entity_reference_element_validate_filter(&$element, FormStateInterface
  * @see entity_reference_field_instance_settings_form()
  */
 function entity_reference_settings_ajax($form, FormStateInterface $form_state) {
-  $trigger = $form_state['triggering_element'];
-  return NestedArray::getValue($form, $trigger['#ajax']['element']);
+  return NestedArray::getValue($form, $form_state->getTriggeringElement()['#ajax']['element']);
 }
 
 /**
@@ -169,7 +168,7 @@ function entity_reference_settings_ajax($form, FormStateInterface $form_state) {
  * @see entity_reference_field_instance_settings_form()
  */
 function entity_reference_settings_ajax_submit($form, FormStateInterface $form_state) {
-  $form_state['rebuild'] = TRUE;
+  $form_state->setRebuild();
 }
 
 /**
diff --git a/core/modules/entity_reference/src/ConfigurableEntityReferenceItem.php b/core/modules/entity_reference/src/ConfigurableEntityReferenceItem.php
index 954fbde..f4fd800 100644
--- a/core/modules/entity_reference/src/ConfigurableEntityReferenceItem.php
+++ b/core/modules/entity_reference/src/ConfigurableEntityReferenceItem.php
@@ -178,7 +178,7 @@ public function settingsForm(array &$form, FormStateInterface $form_state, $has_
    * {@inheritdoc}
    */
   public function instanceSettingsForm(array $form, FormStateInterface $form_state) {
-    $instance = $form_state['instance'];
+    $instance = $form_state->get('instance');
 
     // Get all selection plugins for this entity type.
     $selection_plugins = \Drupal::service('plugin.manager.entity_reference.selection')->getSelectionGroups($this->getSetting('target_type'));
@@ -251,7 +251,7 @@ public function instanceSettingsForm(array $form, FormStateInterface $form_state
   public static function instanceSettingsFormValidate(array $form, FormStateInterface $form_state) {
     if ($form_state->hasValue('instance')) {
       $form_state->unsetValue(array('instance', 'settings', 'handler_submit'));
-      $form_state['instance']->settings = $form_state->getValue(array('instance', 'settings'));
+      $form_state->get('instance')->settings = $form_state->getValue(['instance', 'settings']);
     }
   }
 
diff --git a/core/modules/field/field.module b/core/modules/field/field.module
index 87ba4f7..4207d28 100644
--- a/core/modules/field/field.module
+++ b/core/modules/field/field.module
@@ -349,10 +349,11 @@ function field_form_config_admin_import_form_alter(&$form, FormStateInterface $f
   // Only display the message when there is a storage comparer available and the
   // form is not submitted.
   $user_input = $form_state->getUserInput();
-  if (isset($form_state['storage_comparer']) && empty($user_input)) {
+  $storage_comparer = $form_state->get('storage_comparer');
+  if ($storage_comparer && empty($user_input)) {
     $field_storages = \Drupal\field\ConfigImporterFieldPurger::getFieldStoragesToPurge(
-      $form_state['storage_comparer']->getSourceStorage()->read('core.extension'),
-      $form_state['storage_comparer']->getChangelist('delete')
+      $storage_comparer->getSourceStorage()->read('core.extension'),
+      $storage_comparer->getChangelist('delete')
     );
     if ($field_storages) {
       foreach ($field_storages as $field) {
diff --git a/core/modules/field/src/Plugin/views/field/Field.php b/core/modules/field/src/Plugin/views/field/Field.php
index 0bd93b2..fb38edf 100644
--- a/core/modules/field/src/Plugin/views/field/Field.php
+++ b/core/modules/field/src/Plugin/views/field/Field.php
@@ -675,7 +675,7 @@ public function buildGroupByForm(&$form, FormStateInterface $form_state) {
 
   public function submitGroupByForm(&$form, FormStateInterface $form_state) {
     parent::submitGroupByForm($form, $form_state);
-    $item = &$form_state['handler']->options;
+    $item = &$form_state->get('handler')->options;
 
     // Add settings for "field API" fields.
     $item['group_column'] = $form_state->getValue(array('options', 'group_column'));
diff --git a/core/modules/field/src/Tests/FieldAttachOtherTest.php b/core/modules/field/src/Tests/FieldAttachOtherTest.php
index d41808f..978ea0e 100644
--- a/core/modules/field/src/Tests/FieldAttachOtherTest.php
+++ b/core/modules/field/src/Tests/FieldAttachOtherTest.php
@@ -331,7 +331,7 @@ function testEntityFormDisplayExtractFormValues() {
     $values_2[1]['value'] = 0;
 
     // Pretend the form has been built.
-    $form_state['build_info']['callback_object'] = \Drupal::entityManager()->getFormObject($entity_type, 'default');
+    $form_state->setFormObject(\Drupal::entityManager()->getFormObject($entity_type, 'default'));
     \Drupal::formBuilder()->prepareForm('field_test_entity_form', $form, $form_state);
     drupal_process_form('field_test_entity_form', $form, $form_state);
     $form_state->setValue($this->fieldTestData->field_name, $values);
diff --git a/core/modules/field/tests/modules/field_test/src/Form/NestedEntityTestForm.php b/core/modules/field/tests/modules/field_test/src/Form/NestedEntityTestForm.php
index b1f9d1c..7e07f1a 100644
--- a/core/modules/field/tests/modules/field_test/src/Form/NestedEntityTestForm.php
+++ b/core/modules/field/tests/modules/field_test/src/Form/NestedEntityTestForm.php
@@ -29,13 +29,15 @@ public function getFormId() {
    */
   public function buildForm(array $form, FormStateInterface $form_state, EntityInterface $entity_1 = NULL, EntityInterface $entity_2 = NULL) {
     // First entity.
-    $form_state['entity_1'] = $entity_1;
-    $form_state['form_display_1'] = EntityFormDisplay::collectRenderDisplay($entity_1, 'default');
-    $form_state['form_display_1']->buildForm($entity_1, $form, $form_state);
+    $form_state->set('entity_1', $entity_1);
+    $form_display_1 = EntityFormDisplay::collectRenderDisplay($entity_1, 'default');
+    $form_state->set('form_display_1', $form_display_1);
+    $form_display_1->buildForm($entity_1, $form, $form_state);
 
     // Second entity.
-    $form_state['entity_2'] = $entity_2;
-    $form_state['form_display_2'] = EntityFormDisplay::collectRenderDisplay($entity_2, 'default');
+    $form_state->set('entity_2', $entity_2);
+    $form_display_2 = EntityFormDisplay::collectRenderDisplay($entity_2, 'default');
+    $form_state->set('form_display_2', $form_display_2);
     $form['entity_2'] = array(
       '#type' => 'details',
       '#title' => t('Second entity'),
@@ -44,7 +46,7 @@ public function buildForm(array $form, FormStateInterface $form_state, EntityInt
       '#weight' => 50,
     );
 
-    $form_state['form_display_2']->buildForm($entity_2, $form['entity_2'], $form_state);
+    $form_display_2->buildForm($entity_2, $form['entity_2'], $form_state);
 
     $form['save'] = array(
       '#type' => 'submit',
@@ -59,15 +61,15 @@ public function buildForm(array $form, FormStateInterface $form_state, EntityInt
    * {@inheritdoc]
    */
   public function validateForm(array &$form, FormStateInterface $form_state) {
-    $entity_1 = $form_state['entity_1'];
+    $entity_1 = $form_state->get('entity_1');
     /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display_1 */
-    $form_display_1 = $form_state['form_display_1'];
+    $form_display_1 = $form_state->get('form_display_1');
     $form_display_1->extractFormValues($entity_1, $form, $form_state);
     $form_display_1->validateFormValues($entity_1, $form, $form_state);
 
-    $entity_2 = $form_state['entity_2'];
+    $entity_2 = $form_state->get('entity_2');
     /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display_2 */
-    $form_display_2 = $form_state['form_display_2'];
+    $form_display_2 = $form_state->get('form_display_2');
     $form_display_2->extractFormValues($entity_2, $form['entity_2'], $form_state);
     $form_display_2->validateFormValues($entity_2, $form['entity_2'], $form_state);
   }
@@ -77,11 +79,11 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
     /** @var \Drupal\Core\Entity\EntityInterface $entity_1 */
-    $entity_1 = $form_state['entity_1'];
+    $entity_1 = $form_state->get('entity_1');
     $entity_1->save();
 
     /** @var \Drupal\Core\Entity\EntityInterface $entity_2 */
-    $entity_2 = $form_state['entity_2'];
+    $entity_2 = $form_state->get('entity_2');
     $entity_2->save();
 
     drupal_set_message($this->t('test_entities @id_1 and @id_2 have been updated.', array('@id_1' => $entity_1->id(), '@id_2' => $entity_2->id())));
diff --git a/core/modules/field_ui/field_ui.module b/core/modules/field_ui/field_ui.module
index 4cd3bce..06764d0 100644
--- a/core/modules/field_ui/field_ui.module
+++ b/core/modules/field_ui/field_ui.module
@@ -200,7 +200,7 @@ function field_ui_entity_operation(EntityInterface $entity) {
  * @see field_ui_form_node_type_form_alter()
  */
 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->getValue('type'))) {
+  if ($form_state->getTriggeringElement()['#parents'][0] === 'save_continue' && $route_info = FieldUI::getOverviewRouteInfo('node', $form_state->getValue('type'))) {
     $form_state->setRedirectUrl($route_info);
   }
 }
diff --git a/core/modules/field_ui/src/DisplayOverviewBase.php b/core/modules/field_ui/src/DisplayOverviewBase.php
index 1bad243..802d012 100644
--- a/core/modules/field_ui/src/DisplayOverviewBase.php
+++ b/core/modules/field_ui/src/DisplayOverviewBase.php
@@ -322,11 +322,12 @@ protected function buildFieldRow(FieldDefinitionInterface $field_definition, Ent
     if ($display_type = $form_state->getValue(array('fields', $field_name, 'type'))) {
       $display_options['type'] = $display_type;
     }
-    if (isset($form_state['plugin_settings'][$field_name]['settings'])) {
-      $display_options['settings'] = $form_state['plugin_settings'][$field_name]['settings'];
+    $plugin_settings = $form_state->get('plugin_settings');
+    if (isset($plugin_settings[$field_name]['settings'])) {
+      $display_options['settings'] = $plugin_settings[$field_name]['settings'];
     }
-    if (isset($form_state['plugin_settings'][$field_name]['third_party_settings'])) {
-      $display_options['third_party_settings'] = $form_state['plugin_settings'][$field_name]['third_party_settings'];
+    if (isset($plugin_settings[$field_name]['third_party_settings'])) {
+      $display_options['third_party_settings'] = $plugin_settings[$field_name]['third_party_settings'];
     }
 
     // Get the corresponding plugin object.
@@ -343,7 +344,7 @@ protected function buildFieldRow(FieldDefinitionInterface $field_definition, Ent
       '#field_name' => $field_name,
     );
 
-    if ($form_state['plugin_settings_edit'] == $field_name) {
+    if ($form_state->get('plugin_settings_edit') == $field_name) {
       // We are currently editing this field's plugin settings. Display the
       // settings form and submit buttons.
       $field_row['plugin']['settings_edit_form'] = array();
@@ -519,12 +520,13 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
         // Get plugin settings. They lie either directly in submitted form
         // values (if the whole form was submitted while some plugin settings
         // were being edited), or have been persisted in $form_state.
+        $plugin_settings = $form_state->get('plugin_settings');
         $settings = array();
         if (isset($values['settings_edit_form']['settings'])) {
           $settings = $values['settings_edit_form']['settings'];
         }
-        elseif (isset($form_state['plugin_settings'][$field_name]['settings'])) {
-          $settings = $form_state['plugin_settings'][$field_name]['settings'];
+        elseif (isset($plugin_settings[$field_name]['settings'])) {
+          $settings = $plugin_settings[$field_name]['settings'];
         }
         elseif ($current_options = $display->getComponent($field_name)) {
           $settings = $current_options['settings'];
@@ -533,8 +535,8 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
         if (isset($values['settings_edit_form']['third_party_settings'])) {
           $third_party_settings = $values['settings_edit_form']['third_party_settings'];
         }
-        elseif (isset($form_state['plugin_settings'][$field_name]['third_party_settings'])) {
-          $third_party_settings = $form_state['plugin_settings'][$field_name]['third_party_settings'];
+        elseif (isset($plugin_settings[$field_name]['third_party_settings'])) {
+          $third_party_settings = $plugin_settings[$field_name]['third_party_settings'];
         }
         elseif (($current_options = $display->getComponent($field_name)) && isset($current_options['third_party_settings'])) {
           $third_party_settings = $current_options['third_party_settings'];
@@ -609,51 +611,53 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
    * Form submission handler for multistep buttons.
    */
   public function multistepSubmit($form, FormStateInterface $form_state) {
-    $trigger = $form_state['triggering_element'];
+    $trigger = $form_state->getTriggeringElement();
     $op = $trigger['#op'];
 
     switch ($op) {
       case 'edit':
         // Store the field whose settings are currently being edited.
         $field_name = $trigger['#field_name'];
-        $form_state['plugin_settings_edit'] = $field_name;
+        $form_state->set('plugin_settings_edit', $field_name);
         break;
 
       case 'update':
         // Store the saved settings, and set the field back to 'non edit' mode.
         $field_name = $trigger['#field_name'];
         if ($plugin_settings = $form_state->getValue(array('fields', $field_name, 'settings_edit_form', 'settings'))) {
-          $form_state['plugin_settings'][$field_name]['settings'] = $plugin_settings;
+          $form_state->set(['plugin_settings', $field_name, 'settings'], $plugin_settings);
         }
         if ($plugin_third_party_settings = $form_state->getValue(array('fields', $field_name, 'settings_edit_form', 'third_party_settings'))) {
-          $form_state['plugin_settings'][$field_name]['third_party_settings'] = $plugin_third_party_settings;
+          $form_state->set(['plugin_settings', $field_name, 'third_party_settings'], $plugin_third_party_settings);
         }
-        unset($form_state['plugin_settings_edit']);
+        $form_state->set('plugin_settings_edit', NULL);
         break;
 
       case 'cancel':
         // Set the field back to 'non edit' mode.
-        unset($form_state['plugin_settings_edit']);
+        $form_state->set('plugin_settings_edit', NULL);
         break;
 
       case 'refresh_table':
         // If the currently edited field is one of the rows to be refreshed, set
         // it back to 'non edit' mode.
         $updated_rows = explode(' ', $form_state->getValue('refresh_rows'));
-        if (isset($form_state['plugin_settings_edit']) && in_array($form_state['plugin_settings_edit'], $updated_rows)) {
-          unset($form_state['plugin_settings_edit']);
+        $plugin_settings_edit = $form_state->get('plugin_settings_edit');
+        if ($plugin_settings_edit && in_array($plugin_settings_edit, $updated_rows)) {
+
+          $form_state->set('plugin_settings_edit', NULL);
         }
         break;
     }
 
-    $form_state['rebuild'] = TRUE;
+    $form_state->setRebuild();
   }
 
   /**
    * Ajax handler for multistep buttons.
    */
   public function multistepAjax($form, FormStateInterface $form_state) {
-    $trigger = $form_state['triggering_element'];
+    $trigger = $form_state->getTriggeringElement();
     $op = $trigger['#op'];
 
     // Pick the elements that need to receive the ajax-new-content effect.
diff --git a/core/modules/field_ui/src/FieldOverview.php b/core/modules/field_ui/src/FieldOverview.php
index 59088f0..f6f819e 100644
--- a/core/modules/field_ui/src/FieldOverview.php
+++ b/core/modules/field_ui/src/FieldOverview.php
@@ -414,7 +414,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
         $destinations[] = array('route_name' => 'field_ui.instance_edit_' . $this->entity_type, 'route_parameters' => $route_parameters);
 
         // Store new field information for any additional submit handlers.
-        $form_state['fields_added']['_add_new_field'] = $values['field_name'];
+        $form_state->set(['fields_added', '_add_new_field'], $values['field_name']);
       }
       catch (\Exception $e) {
         $error = TRUE;
@@ -464,7 +464,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
             ),
           );
           // Store new field information for any additional submit handlers.
-          $form_state['fields_added']['_add_existing_field'] = $instance['field_name'];
+          $form_state->set(['fields_added', '_add_existing_field'], $instance['field_name']);
         }
         catch (\Exception $e) {
           $error = TRUE;
diff --git a/core/modules/field_ui/src/Form/FieldInstanceEditForm.php b/core/modules/field_ui/src/Form/FieldInstanceEditForm.php
index e8d4469..a670399 100644
--- a/core/modules/field_ui/src/Form/FieldInstanceEditForm.php
+++ b/core/modules/field_ui/src/Form/FieldInstanceEditForm.php
@@ -64,7 +64,8 @@ public function getFormId() {
    * {@inheritdoc}
    */
   public function buildForm(array $form, FormStateInterface $form_state, FieldInstanceConfigInterface $field_instance_config = NULL) {
-    $this->instance = $form_state['instance'] = $field_instance_config;
+    $this->instance = $field_instance_config;
+    $form_state->set('instance', $field_instance_config);
 
     $bundle = $this->instance->bundle;
     $entity_type = $this->instance->entity_type;
diff --git a/core/modules/field_ui/src/Form/FieldStorageEditForm.php b/core/modules/field_ui/src/Form/FieldStorageEditForm.php
index 903a614..edb6d22 100644
--- a/core/modules/field_ui/src/Form/FieldStorageEditForm.php
+++ b/core/modules/field_ui/src/Form/FieldStorageEditForm.php
@@ -76,7 +76,8 @@ public static function create(ContainerInterface $container) {
    * {@inheritdoc}
    */
   public function buildForm(array $form, FormStateInterface $form_state, FieldInstanceConfigInterface $field_instance_config = NULL) {
-    $this->instance = $form_state['instance'] = $field_instance_config;
+    $this->instance = $field_instance_config;
+    $form_state->set('instance', $field_instance_config);
     $form['#title'] = $this->instance->label();
 
     $field_storage = $this->instance->getFieldStorageDefinition();
diff --git a/core/modules/field_ui/src/OverviewBase.php b/core/modules/field_ui/src/OverviewBase.php
index bd1685e..2de43ee 100644
--- a/core/modules/field_ui/src/OverviewBase.php
+++ b/core/modules/field_ui/src/OverviewBase.php
@@ -78,15 +78,17 @@ public static function create(ContainerInterface $container) {
   public function buildForm(array $form, FormStateInterface $form_state, $entity_type_id = NULL, $bundle = NULL) {
     $entity_type = $this->entityManager->getDefinition($entity_type_id);
     $this->bundleEntityType = $entity_type->getBundleEntityType();
-    if (!isset($form_state['bundle'])) {
+    $stored_bundle = $form_state->get('bundle');
+    if (!$stored_bundle) {
       if (!$bundle) {
         $bundle = $this->getRequest()->attributes->get('_raw_variables')->get($this->bundleEntityType);
       }
-      $form_state['bundle'] = $bundle;
+      $stored_bundle = $bundle;
+      $form_state->set('bundle', $bundle);
     }
 
     $this->entity_type = $entity_type_id;
-    $this->bundle = $form_state['bundle'];
+    $this->bundle = $stored_bundle;
   }
 
   /**
diff --git a/core/modules/file/file.module b/core/modules/file/file.module
index e17ab46..104ef86 100644
--- a/core/modules/file/file.module
+++ b/core/modules/file/file.module
@@ -1331,7 +1331,7 @@ function file_managed_file_validate(&$element, FormStateInterface $form_state) {
   // If referencing an existing file, only allow if there are existing
   // references. This prevents unmanaged files from being deleted if this
   // item were to be deleted.
-  $clicked_button = end($form_state['triggering_element']['#parents']);
+  $clicked_button = end($form_state->getTriggeringElement()['#parents']);
   if ($clicked_button != 'remove_button' && !empty($element['fids']['#value'])) {
     $fids = $element['fids']['#value'];
     foreach ($fids as $fid) {
@@ -1368,7 +1368,7 @@ function file_managed_file_validate(&$element, FormStateInterface $form_state) {
 function file_managed_file_submit($form, FormStateInterface $form_state) {
   // Determine whether it was the upload or the remove button that was clicked,
   // and set $element to the managed_file element that contains that button.
-  $parents = $form_state['triggering_element']['#array_parents'];
+  $parents = $form_state->getTriggeringElement()['#array_parents'];
   $button_key = array_pop($parents);
   $element = NestedArray::getValue($form, $parents);
 
@@ -1418,10 +1418,10 @@ 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['no_redirect'] to TRUE would suffice.
+  // situation and calling $form_state->disableRedirect() would suffice.
   // However, we choose to always rebuild, to keep the form processing workflow
   // consistent between the two buttons.
-  $form_state['rebuild'] = TRUE;
+  $form_state->setRebuild();
 }
 
 /**
diff --git a/core/modules/file/src/Plugin/Field/FieldWidget/FileWidget.php b/core/modules/file/src/Plugin/Field/FieldWidget/FileWidget.php
index fa5c28e..0a8ea88 100644
--- a/core/modules/file/src/Plugin/Field/FieldWidget/FileWidget.php
+++ b/core/modules/file/src/Plugin/Field/FieldWidget/FileWidget.php
@@ -132,7 +132,7 @@ protected function formMultipleElements(FieldItemListInterface $items, array &$f
     }
 
     $empty_single_allowed = ($cardinality == 1 && $delta == 0);
-    $empty_multiple_allowed = ($cardinality == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED || $delta < $cardinality) && empty($form_state['programmed']);
+    $empty_multiple_allowed = ($cardinality == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED || $delta < $cardinality) && !$form_state->isProgrammed();
 
     // Add one more empty row for new uploads except when this is a programmed
     // multiple form as it is not necessary.
@@ -491,11 +491,10 @@ public static function submit($form, FormStateInterface $form_state) {
     // avoid a mismatch between old and new deltas. The rebuilt elements will
     // have #default_value set appropriately for the current state of the field,
     // so nothing is lost in doing this.
-    $parents = array_slice($form_state['triggering_element']['#parents'], 0, -2);
+    $button = $form_state->getTriggeringElement();
+    $parents = array_slice($button['#parents'], 0, -2);
     NestedArray::setValue($form_state->getUserInput(), $parents, NULL);
 
-    $button = $form_state['triggering_element'];
-
     // Go one level up in the form, to the widgets container.
     $element = NestedArray::getValue($form, array_slice($button['#array_parents'], 0, -1));
     $field_name = $element['#field_name'];
diff --git a/core/modules/history/src/Plugin/views/filter/HistoryUserTimestamp.php b/core/modules/history/src/Plugin/views/filter/HistoryUserTimestamp.php
index 70866c8..f25f53c 100644
--- a/core/modules/history/src/Plugin/views/filter/HistoryUserTimestamp.php
+++ b/core/modules/history/src/Plugin/views/filter/HistoryUserTimestamp.php
@@ -44,7 +44,7 @@ protected function valueForm(&$form, FormStateInterface $form_state) {
     // Only present a checkbox for the exposed filter itself. There's no way
     // to tell the difference between not checked and the default value, so
     // specifying the default value via the views UI is meaningless.
-    if (!empty($form_state['exposed'])) {
+    if ($form_state->get('exposed')) {
       if (isset($this->options['expose']['label'])) {
         $label = $this->options['expose']['label'];
       }
diff --git a/core/modules/image/src/Form/ImageEffectFormBase.php b/core/modules/image/src/Form/ImageEffectFormBase.php
index 910c781..535f2a9 100644
--- a/core/modules/image/src/Form/ImageEffectFormBase.php
+++ b/core/modules/image/src/Form/ImageEffectFormBase.php
@@ -109,7 +109,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
     $effect_data = (new FormState())->setValues($form_state->getValue('data'));
     $this->imageEffect->validateConfigurationForm($form, $effect_data);
     // Update the original form values.
-    $form_state->setValue('data', $effect_data['values']);
+    $form_state->setValue('data', $effect_data->getValues());
   }
 
   /**
@@ -123,7 +123,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $effect_data = (new FormState())->setValues($form_state->getValue('data'));
     $this->imageEffect->submitConfigurationForm($form, $effect_data);
     // Update the original form values.
-    $form_state->setValue('data', $effect_data['values']);
+    $form_state->setValue('data', $effect_data->getValues());
 
     $this->imageEffect->setWeight($form_state->getValue('weight'));
     if (!$this->imageEffect->getUuid()) {
diff --git a/core/modules/image/src/Plugin/Field/FieldWidget/ImageWidget.php b/core/modules/image/src/Plugin/Field/FieldWidget/ImageWidget.php
index 93b5c03..b0a2914 100644
--- a/core/modules/image/src/Plugin/Field/FieldWidget/ImageWidget.php
+++ b/core/modules/image/src/Plugin/Field/FieldWidget/ImageWidget.php
@@ -231,7 +231,7 @@ public static function process($element, FormStateInterface $form_state, $form)
   public static function validateRequiredFields($element, FormStateInterface $form_state) {
     // Only do validation if the function is triggered from other places than
     // the image process form.
-    if (!in_array('file_managed_file_submit', $form_state['triggering_element']['#submit'])) {
+    if (!in_array('file_managed_file_submit', $form_state->getTriggeringElement()['#submit'])) {
       // If the image is not there, we do not check for empty values.
       $parents = $element['#parents'];
       $field = array_pop($parents);
diff --git a/core/modules/language/language.module b/core/modules/language/language.module
index e095d8d..fb7ba22 100644
--- a/core/modules/language/language.module
+++ b/core/modules/language/language.module
@@ -242,15 +242,14 @@ function language_configuration_element_process($element, FormStateInterface $fo
   // They will be used, in the submit handler, to generate the names of the
   // variables that will store the settings and are a way to uniquely identify
   // the entity.
-  if (!isset($form_state['language'])) {
-    $form_state['language'] = array();
-  }
-  $form_state['language'] += array(
-    $element['#name'] => array(
+  $language = $form_state->get('language') ?: [];
+  $language += [
+    $element['#name'] => [
       'entity_type' => $element['#entity_information']['entity_type'],
       'bundle' => $element['#entity_information']['bundle'],
-    ),
-  );
+    ],
+  ];
+  $form_state->set('language', $language);
 
   // Do not add the submit callback for the language content settings page,
   // which is handled separately.
@@ -273,8 +272,8 @@ function language_configuration_element_process($element, FormStateInterface $fo
 function language_configuration_element_submit(&$form, FormStateInterface $form_state) {
   // Iterate through all the language_configuration elements and save their
   // values.
-  if (isset($form_state['language'])) {
-    foreach ($form_state['language'] as $element_name => $values) {
+  if ($language = $form_state->get('language')) {
+    foreach ($language as $element_name => $values) {
       language_save_default_configuration($values['entity_type'], $values['bundle'],  $form_state->getValue($element_name));
     }
   }
diff --git a/core/modules/language/src/Form/NegotiationBrowserForm.php b/core/modules/language/src/Form/NegotiationBrowserForm.php
index 39d47cb..766ecb5 100644
--- a/core/modules/language/src/Form/NegotiationBrowserForm.php
+++ b/core/modules/language/src/Form/NegotiationBrowserForm.php
@@ -162,14 +162,14 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
       $unique_values[$data['browser_langcode']] = $data['drupal_langcode'];
     }
 
-    $form_state['mappings'] = $unique_values;
+    $form_state->set('mappings', $unique_values);
   }
 
   /**
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $mappings = $form_state['mappings'];
+    $mappings = $form_state->get('mappings');
     if (!empty($mappings)) {
       $config = $this->config('language.mappings');
       $config->setData($mappings);
diff --git a/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
index cb95532..21e078f 100644
--- a/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
+++ b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
@@ -84,7 +84,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
     // Post-process the title field to make it conditionally required if URL is
     // non-empty. Omit the validation on the field edit form, since the field
     // settings cannot be saved otherwise.
-    if (empty($form_state['default_value_widget']) && $this->getFieldSetting('title') == DRUPAL_REQUIRED) {
+    if (!$form_state->get('default_value_widget') && $this->getFieldSetting('title') == DRUPAL_REQUIRED) {
       $element['#element_validate'][] = array($this, 'validateTitle');
     }
 
diff --git a/core/modules/menu_link_content/src/Form/MenuLinkContentForm.php b/core/modules/menu_link_content/src/Form/MenuLinkContentForm.php
index 8d66838..2d37566 100644
--- a/core/modules/menu_link_content/src/Form/MenuLinkContentForm.php
+++ b/core/modules/menu_link_content/src/Form/MenuLinkContentForm.php
@@ -340,7 +340,7 @@ public function save(array $form, FormStateInterface $form_state) {
     }
     else {
       drupal_set_message($this->t('There was an error saving the menu link.'), 'error');
-      $form_state['rebuild'] = TRUE;
+      $form_state->setRebuild();
     }
   }
 
diff --git a/core/modules/menu_ui/menu_ui.module b/core/modules/menu_ui/menu_ui.module
index 69c23e3..dcedc00 100644
--- a/core/modules/menu_ui/menu_ui.module
+++ b/core/modules/menu_ui/menu_ui.module
@@ -226,7 +226,7 @@ function menu_ui_node_predelete(EntityInterface $node) {
  * Implements hook_node_prepare_form().
  */
 function menu_ui_node_prepare_form(NodeInterface $node, $operation, FormStateInterface $form_state) {
-  if (empty($form_state['menu_link_definition'])) {
+  if (!$form_state->get('menu_link_definition')) {
     // Prepare the node for the edit form so that $node->menu always exists.
     /** @var \Drupal\node\NodeTypeInterface $node_type */
     $node_type = $node->type->entity;
@@ -285,7 +285,7 @@ function menu_ui_node_prepare_form(NodeInterface $node, $operation, FormStateInt
       );
     }
     // Set default values.
-    $form_state['menu_link_definition'] = $definition;
+    $form_state->set('menu_link_definition', $definition);
   }
 }
 
@@ -300,7 +300,7 @@ function menu_ui_form_node_form_alter(&$form, FormStateInterface $form_state) {
   // Generate a list of possible parents (not including this link or descendants).
   // @todo This must be handled in a #process handler.
   $node = $form_state->getFormObject()->getEntity();
-  $definition = $form_state['menu_link_definition'];
+  $definition = $form_state->get('menu_link_definition');
   /** @var \Drupal\node\NodeTypeInterface $node_type */
   $node_type = $node->type->entity;
   /** @var \Drupal\Core\Menu\MenuParentFormSelectorInterface $menu_parent_selector */
diff --git a/core/modules/menu_ui/src/MenuForm.php b/core/modules/menu_ui/src/MenuForm.php
index 8684e59..1115070 100644
--- a/core/modules/menu_ui/src/MenuForm.php
+++ b/core/modules/menu_ui/src/MenuForm.php
@@ -144,7 +144,7 @@ public function form(array $form, FormStateInterface $form_state) {
       // equally separated yet. Therefore, we use a $form_state key to point to
       // the parents of the form section.
       // @see self::submitOverviewForm()
-      $form_state['menu_overview_form_parents'] = array('links');
+      $form_state->set('menu_overview_form_parents', ['links']);
       $form['links'] = array();
       $form['links'] = $this->buildOverviewForm($form['links'], $form_state);
     }
@@ -359,7 +359,7 @@ protected function submitOverviewForm(array $complete_form, FormStateInterface $
     // within forms, but does not allow to handle the form section's submission
     // equally separated yet. Therefore, we use a $form_state key to point to
     // the parents of the form section.
-    $parents = $form_state['menu_overview_form_parents'];
+    $parents = $form_state->get('menu_overview_form_parents');
     $input = NestedArray::getValue($form_state->getUserInput(), $parents);
     $form = &NestedArray::getValue($complete_form, $parents);
 
diff --git a/core/modules/node/src/Form/NodePreviewForm.php b/core/modules/node/src/Form/NodePreviewForm.php
index cdca58c..81fd61c 100644
--- a/core/modules/node/src/Form/NodePreviewForm.php
+++ b/core/modules/node/src/Form/NodePreviewForm.php
@@ -118,8 +118,8 @@ public function buildForm(array $form, FormStateInterface $form_state, EntityInt
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
     $form_state->setRedirect('entity.node.preview', array(
-      'node_preview' => $form_state['values']['uuid'],
-      'view_mode_id' => $form_state['values']['view_mode'],
+      'node_preview' => $form_state->getValue('uuid'),
+      'view_mode_id' => $form_state->getValue('view_mode'),
     ));
   }
 
diff --git a/core/modules/node/src/NodeForm.php b/core/modules/node/src/NodeForm.php
index 9a78a3c..45343d5 100644
--- a/core/modules/node/src/NodeForm.php
+++ b/core/modules/node/src/NodeForm.php
@@ -79,10 +79,11 @@ public function form(array $form, FormStateInterface $form_state) {
     }
 
     if ($preview = $store->get($uuid)) {
+      /** @var $preview \Drupal\Core\Form\FormStateInterface */
       $form_state = $preview;
 
       // Rebuild the form.
-      $form_state['rebuild'] = TRUE;
+      $form_state->setRebuild();
       $this->entity = $preview->getFormObject()->getEntity();
       unset($this->entity->in_preview);
     }
@@ -215,7 +216,7 @@ protected function actions(array $form, FormStateInterface $form_state) {
     $node = $this->entity;
     $preview_mode = $node->type->entity->getPreviewMode();
 
-    $element['submit']['#access'] = $preview_mode != DRUPAL_REQUIRED || (!$form_state->getErrors() && isset($form_state['node_preview']));
+    $element['submit']['#access'] = $preview_mode != DRUPAL_REQUIRED || (!$form_state->getErrors() && $form_state->get('node_preview'));
 
     // If saving is an option, privileged users get dedicated form submit
     // buttons to adjust the publishing status while saving in one go.
@@ -422,7 +423,7 @@ public function save(array $form, FormStateInterface $form_state) {
 
     if ($node->id()) {
       $form_state->setValue('nid', $node->id());
-      $form_state['nid'] = $node->id();
+      $form_state->set('nid', $node->id());
       if ($node->access('view')) {
         $form_state->setRedirect(
           'entity.node.canonical',
@@ -443,7 +444,7 @@ public function save(array $form, FormStateInterface $form_state) {
       // In the unlikely case something went wrong on save, the node will be
       // rebuilt and node form redisplayed the same way as in preview.
       drupal_set_message(t('The post could not be saved.'), 'error');
-      $form_state['rebuild'] = TRUE;
+      $form_state->setRebuild();
     }
   }
 
diff --git a/core/modules/node/src/NodeTypeForm.php b/core/modules/node/src/NodeTypeForm.php
index 8694501..97eb1eb 100644
--- a/core/modules/node/src/NodeTypeForm.php
+++ b/core/modules/node/src/NodeTypeForm.php
@@ -237,15 +237,16 @@ public function save(array $form, FormStateInterface $form_state) {
     $fields = $this->entityManager->getFieldDefinitions('node', $type->id());
     // Update title field definition.
     $title_field = $fields['title'];
-    if ($title_field->getLabel() != $form_state['values']['title_label']) {
-      $title_field->getConfig($type->id())->setLabel($form_state['values']['title_label'])->save();
+    $title_label = $form_state->getValue('title_label');
+    if ($title_field->getLabel() != $title_label) {
+      $title_field->getConfig($type->id())->setLabel($title_label)->save();
     }
     // Update workflow options.
     // @todo Make it possible to get default values without an entity.
     //   https://www.drupal.org/node/2318187
     $node = $this->entityManager->getStorage('node')->create(array('type' => $type->id()));
     foreach (array('status', 'promote', 'sticky')  as $field_name) {
-      $value = (bool) $form_state['values']['options'][$field_name];
+      $value = (bool) $form_state->getValue(['options', $field_name]);
       if ($node->$field_name->value != $value) {
         $fields[$field_name]->getConfig($type->id())->setDefaultValue($value)->save();
       }
diff --git a/core/modules/quickedit/src/Form/QuickEditFieldForm.php b/core/modules/quickedit/src/Form/QuickEditFieldForm.php
index d4fc95e..f67baa2 100644
--- a/core/modules/quickedit/src/Form/QuickEditFieldForm.php
+++ b/core/modules/quickedit/src/Form/QuickEditFieldForm.php
@@ -85,12 +85,12 @@ public function getFormId() {
    * Builds a form for a single entity field.
    */
   public function buildForm(array $form, FormStateInterface $form_state, EntityInterface $entity = NULL, $field_name = NULL) {
-    if (!isset($form_state['entity'])) {
+    if (!$form_state->has('entity')) {
       $this->init($form_state, $entity, $field_name);
     }
 
     // Add the field form.
-    $form_state['form_display']->buildForm($entity, $form, $form_state);
+    $form_state->get('form_display')->buildForm($entity, $form, $form_state);
 
     // Add a dummy changed timestamp field to attach form errors to.
     if ($entity instanceof EntityChangedInterface) {
@@ -126,8 +126,8 @@ protected function init(FormStateInterface $form_state, EntityInterface $entity,
       $entity->revision_log = NULL;
     }
 
-    $form_state['entity'] = $entity;
-    $form_state['field_name'] = $field_name;
+    $form_state->set('entity', $entity);
+    $form_state->set('field_name', $field_name);
 
     // Fetch the display used by the form. It is the display for the 'default'
     // form mode, with only the current field visible.
@@ -137,7 +137,7 @@ protected function init(FormStateInterface $form_state, EntityInterface $entity,
         $display->removeComponent($name);
       }
     }
-    $form_state['form_display'] = $display;
+    $form_state->set('form_display', $display);
   }
 
   /**
@@ -146,7 +146,7 @@ protected function init(FormStateInterface $form_state, EntityInterface $entity,
   public function validateForm(array &$form, FormStateInterface $form_state) {
     $entity = $this->buildEntity($form, $form_state);
 
-    $form_state['form_display']->validateFormValues($entity, $form, $form_state);
+    $form_state->get('form_display')->validateFormValues($entity, $form, $form_state);
 
     // Do validation on the changed field as well and assign the error to the
     // dummy form element we added for this. We don't know the name of this
@@ -165,10 +165,11 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
    * Saves the entity with updated values for the edited field.
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $form_state['entity'] = $this->buildEntity($form, $form_state);
+    $entity = $this->buildEntity($form, $form_state);
+    $form_state->set('entity', $entity);
 
     // Store entity in tempstore with its UUID as tempstore key.
-    $this->tempStoreFactory->get('quickedit')->set($form_state['entity']->uuid(), $form_state['entity']);
+    $this->tempStoreFactory->get('quickedit')->set($entity->uuid(), $entity);
   }
 
   /**
@@ -179,10 +180,10 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
    */
   protected function buildEntity(array $form, FormStateInterface $form_state) {
     /** @var $entity \Drupal\Core\Entity\EntityInterface */
-    $entity = clone $form_state['entity'];
-    $field_name = $form_state['field_name'];
+    $entity = clone $form_state->get('entity');
+    $field_name = $form_state->get('field_name');
 
-    $form_state['form_display']->extractFormValues($entity, $form, $form_state);
+    $form_state->get('form_display')->extractFormValues($entity, $form, $form_state);
 
     // @todo Refine automated log messages and abstract them to all entity
     //   types: http://drupal.org/node/1678002.
@@ -207,7 +208,7 @@ protected function buildEntity(array $form, FormStateInterface $form_state) {
    *   The current state of the form.
    */
   protected function simplify(array &$form, FormStateInterface $form_state) {
-    $field_name = $form_state['field_name'];
+    $field_name = $form_state->get('field_name');
     $widget_element =& $form[$field_name]['widget'];
 
     // Hide the field label from displaying within the form, because JavaScript
diff --git a/core/modules/quickedit/src/QuickEditController.php b/core/modules/quickedit/src/QuickEditController.php
index 1ccf969..0e6d497 100644
--- a/core/modules/quickedit/src/QuickEditController.php
+++ b/core/modules/quickedit/src/QuickEditController.php
@@ -184,7 +184,7 @@ public function fieldForm(EntityInterface $entity, $field_name, $langcode, $view
       ->addBuildInfo('args', [$entity, $field_name]);
     $form = $this->formBuilder()->buildForm('Drupal\quickedit\Form\QuickEditFieldForm', $form_state);
 
-    if (!empty($form_state['executed'])) {
+    if ($form_state->isExecuted()) {
       // The form submission saved the entity in TempStore. Return the
       // updated view of the field from the TempStore copy.
       $entity = $this->tempStoreFactory->get('quickedit')->get($entity->uuid());
diff --git a/core/modules/search/src/Form/SearchPageForm.php b/core/modules/search/src/Form/SearchPageForm.php
index 795cbc0..eab451a 100644
--- a/core/modules/search/src/Form/SearchPageForm.php
+++ b/core/modules/search/src/Form/SearchPageForm.php
@@ -40,7 +40,7 @@ public function getFormID() {
    */
   public function form(array $form, FormStateInterface $form_state) {
     $plugin = $this->entity->getPlugin();
-    $form_state['search_page_id'] = $this->entity->id();
+    $form_state->set('search_page_id', $this->entity->id());
 
     $form['basic'] = array(
       '#type' => 'container',
@@ -90,7 +90,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     // into the GET as well. If so, make sure to put 'keys' into the GET
     // parameters so that the search results generation is triggered.
     $query = $this->entity->getPlugin()->buildSearchUrlQuery($form_state);
-    $route = 'search.view_' . $form_state['search_page_id'];
+    $route = 'search.view_' . $form_state->get('search_page_id');
     $form_state->setRedirect(
       $route,
       array(),
diff --git a/core/modules/search/src/Plugin/SearchInterface.php b/core/modules/search/src/Plugin/SearchInterface.php
index 6eabf18..3c5f76d 100644
--- a/core/modules/search/src/Plugin/SearchInterface.php
+++ b/core/modules/search/src/Plugin/SearchInterface.php
@@ -95,7 +95,7 @@ public function buildResults();
    * @param \Drupal\Core\Form\FormStateInterface $form_state
    *   The current state of the form. The arguments that
    *   \Drupal::formBuilder()->getForm() was originally called with are
-   *   available in the array $form_state['build_info']['args'].
+   *   available in the array $form_state->getBuildInfo()['args'].
    *
    * @see SearchInterface::buildSearchUrlQuery()
    */
diff --git a/core/modules/search/src/Plugin/views/filter/Search.php b/core/modules/search/src/Plugin/views/filter/Search.php
index 7635125..1f8d193 100644
--- a/core/modules/search/src/Plugin/views/filter/Search.php
+++ b/core/modules/search/src/Plugin/views/filter/Search.php
@@ -92,7 +92,7 @@ protected function valueForm(&$form, FormStateInterface $form_state) {
       '#size' => 15,
       '#default_value' => $this->value,
       '#attributes' => array('title' => $this->t('Search keywords')),
-      '#title' => empty($form_state['exposed']) ? $this->t('Keywords') : '',
+      '#title' => !$form_state->get('exposed') ? $this->t('Keywords') : '',
     );
   }
 
diff --git a/core/modules/simpletest/src/Form/SimpletestResultsForm.php b/core/modules/simpletest/src/Form/SimpletestResultsForm.php
index 7f85f65..09abc1d 100644
--- a/core/modules/simpletest/src/Form/SimpletestResultsForm.php
+++ b/core/modules/simpletest/src/Form/SimpletestResultsForm.php
@@ -273,13 +273,13 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $form_execute = array();
     $form_state_execute = new FormState();
     foreach ($classes as $class) {
-      $form_state_execute['values']['tests'][$class] = $class;
+      $form_state_execute->setValue(['tests', $class], $class);
     }
 
     // Submit the simpletest test form to rerun the tests.
     // Under normal circumstances, a form object's submitForm() should never be
     // called directly, FormBuilder::submitForm() should be called instead.
-    // However, it sets $form_state['programmed'], which disables the Batch API.
+    // However, it calls $form_state->setProgrammed(), which disables the Batch API.
     $simpletest_test_form = new SimpletestTestForm();
     $simpletest_test_form->buildForm($form_execute, $form_state_execute);
     $simpletest_test_form->submitForm($form_execute, $form_state_execute);
diff --git a/core/modules/system/entity.api.php b/core/modules/system/entity.api.php
index 7b0559c..3c8c084 100644
--- a/core/modules/system/entity.api.php
+++ b/core/modules/system/entity.api.php
@@ -1564,7 +1564,7 @@ function hook_entity_display_build_alter(&$build, $context) {
 function hook_entity_prepare_form(\Drupal\Core\Entity\EntityInterface $entity, $operation, \Drupal\Core\Form\FormStateInterface $form_state) {
   if ($operation == 'edit') {
     $entity->label->value = 'Altered label';
-    $form_state['mymodule']['label_altered'] = TRUE;
+    $form_state->set('label_altered', TRUE);
   }
 }
 
@@ -1590,7 +1590,7 @@ function hook_entity_prepare_form(\Drupal\Core\Entity\EntityInterface $entity, $
 function hook_ENTITY_TYPE_prepare_form(\Drupal\Core\Entity\EntityInterface $entity, $operation, \Drupal\Core\Form\FormStateInterface $form_state) {
   if ($operation == 'edit') {
     $entity->label->value = 'Altered label';
-    $form_state['mymodule']['label_altered'] = TRUE;
+    $form_state->set('label_altered', TRUE);
   }
 }
 
diff --git a/core/modules/system/src/Controller/FormAjaxController.php b/core/modules/system/src/Controller/FormAjaxController.php
index 5285cfd..c3c678c 100644
--- a/core/modules/system/src/Controller/FormAjaxController.php
+++ b/core/modules/system/src/Controller/FormAjaxController.php
@@ -73,8 +73,9 @@ public function content(Request $request) {
     // button) that triggered the Ajax request to determine what needs to be
     // rendered.
     $callback = NULL;
-    if (!empty($form_state['triggering_element'])) {
-      $callback = $form_state['triggering_element']['#ajax']['callback'];
+    /** @var $form_state \Drupal\Core\Form\FormStateInterface */
+    if ($triggering_element = $form_state->getTriggeringElement()) {
+      $callback = $triggering_element['#ajax']['callback'];
     }
     $callback = $form_state->prepareCallback($callback);
     if (empty($callback) || !is_callable($callback)) {
@@ -118,13 +119,15 @@ protected function getForm(Request $request) {
     }
 
     // Since some of the submit handlers are run, redirects need to be disabled.
-    $form_state['no_redirect'] = TRUE;
+    $form_state->disableRedirect();
 
     // When a form is rebuilt after Ajax processing, its #build_id and #action
     // should not change.
     // @see \Drupal\Core\Form\FormBuilderInterface::rebuildForm()
-    $form_state['rebuild_info']['copy']['#build_id'] = TRUE;
-    $form_state['rebuild_info']['copy']['#action'] = TRUE;
+    $form_state->addRebuildInfo('copy', [
+      '#build_id' => TRUE,
+      '#action' => TRUE,
+    ]);
 
     // The form needs to be processed; prepare for that by setting a few internal
     // variables.
diff --git a/core/modules/system/src/Plugin/Block/SystemBrandingBlock.php b/core/modules/system/src/Plugin/Block/SystemBrandingBlock.php
index 7740c79..f50a287 100644
--- a/core/modules/system/src/Plugin/Block/SystemBrandingBlock.php
+++ b/core/modules/system/src/Plugin/Block/SystemBrandingBlock.php
@@ -85,7 +85,7 @@ public function defaultConfiguration() {
    */
   public function blockForm($form, FormStateInterface $form_state) {
     // Get the theme.
-    $theme = $form_state['block_theme'];
+    $theme = $form_state->get('block_theme');
 
     // Get permissions.
     $url_system_theme_settings = new Url('system.theme_settings');
diff --git a/core/modules/system/src/Plugin/views/field/BulkForm.php b/core/modules/system/src/Plugin/views/field/BulkForm.php
index bae235d..ce34c90 100644
--- a/core/modules/system/src/Plugin/views/field/BulkForm.php
+++ b/core/modules/system/src/Plugin/views/field/BulkForm.php
@@ -251,7 +251,7 @@ protected function getBulkOptions($filtered = TRUE) {
    *   The current state of the form.
    */
   public function viewsFormSubmit(&$form, FormStateInterface $form_state) {
-    if ($form_state['step'] == 'views_form_views_form') {
+    if ($form_state->get('step') == 'views_form_views_form') {
       // Filter only selected checkboxes.
       $selected = array_filter($form_state->getValue($this->options['id']));
       $entities = array();
diff --git a/core/modules/system/src/Tests/Entity/EntityTranslationFormTest.php b/core/modules/system/src/Tests/Entity/EntityTranslationFormTest.php
index 32a154d..f320dd8 100644
--- a/core/modules/system/src/Tests/Entity/EntityTranslationFormTest.php
+++ b/core/modules/system/src/Tests/Entity/EntityTranslationFormTest.php
@@ -73,8 +73,8 @@ function testEntityFormLanguage() {
 
     // Explicitly set form langcode.
     $langcode = $this->langcodes[0];
-    $form_state['langcode'] = $langcode;
-    \Drupal::service('entity.form_builder')->getForm($node, 'default', $form_state);
+    $form_state_additions['langcode'] = $langcode;
+    \Drupal::service('entity.form_builder')->getForm($node, 'default', $form_state_additions);
     $form_langcode = \Drupal::state()->get('entity_test.form_langcode');
     $this->assertTrue($langcode == $form_langcode, 'Form language is the same as the language parameter.');
 
diff --git a/core/modules/system/src/Tests/Entity/FieldWidgetConstraintValidatorTest.php b/core/modules/system/src/Tests/Entity/FieldWidgetConstraintValidatorTest.php
index 5fa873d..e915ec1 100644
--- a/core/modules/system/src/Tests/Entity/FieldWidgetConstraintValidatorTest.php
+++ b/core/modules/system/src/Tests/Entity/FieldWidgetConstraintValidatorTest.php
@@ -32,7 +32,7 @@ public function testValidation() {
     $display->buildForm($entity, $form, $form_state);
 
     // Pretend the form has been built.
-    $form_state['build_info']['callback_object'] = \Drupal::entityManager()->getFormObject($entity_type, 'default');
+    $form_state->setFormObject(\Drupal::entityManager()->getFormObject($entity_type, 'default'));
     \Drupal::formBuilder()->prepareForm('field_test_entity_form', $form, $form_state);
     \Drupal::formBuilder()->processForm('field_test_entity_form', $form, $form_state);
 
diff --git a/core/modules/system/src/Tests/Form/ElementsTableSelectTest.php b/core/modules/system/src/Tests/Form/ElementsTableSelectTest.php
index 0bde8d0..e9c66f3 100644
--- a/core/modules/system/src/Tests/Form/ElementsTableSelectTest.php
+++ b/core/modules/system/src/Tests/Form/ElementsTableSelectTest.php
@@ -218,7 +218,7 @@ private function formSubmitHelper($form, $edit) {
 
     $edit['form_id'] = $form_id;
     $form_state->setUserInput($edit);
-    $form_state['build_info']['callback_object'] = new StubForm($form_id, $form);
+    $form_state->setFormObject(new StubForm($form_id, $form));
 
     \Drupal::formBuilder()->prepareForm($form_id, $form, $form_state);
 
@@ -228,7 +228,7 @@ private function formSubmitHelper($form, $edit) {
 
     // Clear errors and messages.
     drupal_get_messages();
-    $form_state['errors'] = array();
+    $form_state->clearErrors();
 
     // Return the processed form together with form_state and errors
     // to allow the caller lowlevel access to the form.
diff --git a/core/modules/system/src/Tests/Form/FormCacheTest.php b/core/modules/system/src/Tests/Form/FormCacheTest.php
index 84a7056..20404d5 100644
--- a/core/modules/system/src/Tests/Form/FormCacheTest.php
+++ b/core/modules/system/src/Tests/Form/FormCacheTest.php
@@ -49,7 +49,7 @@ protected function setUp() {
       '#property' => $this->randomMachineName(),
     );
     $this->form_state = new FormState();
-    $this->form_state['example'] = $this->randomMachineName();
+    $this->form_state->set('example', $this->randomMachineName());
   }
 
   /**
@@ -63,7 +63,7 @@ function testCacheToken() {
     $cached_form = form_get_cache($this->form_build_id, $cached_form_state);
     $this->assertEqual($this->form['#property'], $cached_form['#property']);
     $this->assertTrue(!empty($cached_form['#cache_token']), 'Form has a cache token');
-    $this->assertEqual($this->form_state['example'], $cached_form_state['example']);
+    $this->assertEqual($this->form_state->get('example'), $cached_form_state->get('example'));
 
     // Test that the form cache isn't loaded when the session/token has changed.
     // Change the private key. (We cannot change the session ID because this
@@ -72,13 +72,15 @@ function testCacheToken() {
     $cached_form_state = new FormState();
     $cached_form = form_get_cache($this->form_build_id, $cached_form_state);
     $this->assertFalse($cached_form, 'No form returned from cache');
-    $this->assertTrue(empty($cached_form_state['example']));
+    $cached_form_state_example = $cached_form_state->get('example');
+    $this->assertTrue(empty($cached_form_state_example));
 
     // Test that loading the cache with a different form_id fails.
     $wrong_form_build_id = $this->randomMachineName(9);
     $cached_form_state = new FormState();
     $this->assertFalse(form_get_cache($wrong_form_build_id, $cached_form_state), 'No form returned from cache');
-    $this->assertTrue(empty($cached_form_state['example']), 'Cached form state was not loaded');
+    $cached_form_state_example = $cached_form_state->get('example');
+    $this->assertTrue(empty($cached_form_state_example), 'Cached form state was not loaded');
   }
 
   /**
@@ -87,14 +89,14 @@ function testCacheToken() {
   function testNoCacheToken() {
     $this->container->set('current_user', new UserSession(array('uid' => 0)));
 
-    $this->form_state['example'] = $this->randomMachineName();
+    $this->form_state->set('example', $this->randomMachineName());
     form_set_cache($this->form_build_id, $this->form, $this->form_state);
 
     $cached_form_state = new FormState();
     $cached_form = form_get_cache($this->form_build_id, $cached_form_state);
     $this->assertEqual($this->form['#property'], $cached_form['#property']);
     $this->assertTrue(empty($cached_form['#cache_token']), 'Form has no cache token');
-    $this->assertEqual($this->form_state['example'], $cached_form_state['example']);
+    $this->assertEqual($this->form_state->get('example'), $cached_form_state->get('example'));
   }
 
 }
diff --git a/core/modules/system/src/Tests/Form/FormDefaultHandlersTest.php b/core/modules/system/src/Tests/Form/FormDefaultHandlersTest.php
index d51cc1a..3717c6f 100644
--- a/core/modules/system/src/Tests/Form/FormDefaultHandlersTest.php
+++ b/core/modules/system/src/Tests/Form/FormDefaultHandlersTest.php
@@ -47,28 +47,36 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function customValidateForm(array &$form, FormStateInterface $form_state) {
-    $form_state['test_handlers']['validate'][] = __FUNCTION__;
+    $test_handlers = $form_state->get('test_handlers');
+    $test_handlers['validate'][] = __FUNCTION__;
+    $form_state->set('test_handlers', $test_handlers);
   }
 
   /**
    * {@inheritdoc}
    */
   public function validateForm(array &$form, FormStateInterface $form_state) {
-    $form_state['test_handlers']['validate'][] = __FUNCTION__;
+    $test_handlers = $form_state->get('test_handlers');
+    $test_handlers['validate'][] = __FUNCTION__;
+    $form_state->set('test_handlers', $test_handlers);
   }
 
   /**
    * {@inheritdoc}
    */
   public function customSubmitForm(array &$form, FormStateInterface $form_state) {
-    $form_state['test_handlers']['submit'][] = __FUNCTION__;
+    $test_handlers = $form_state->get('test_handlers');
+    $test_handlers['submit'][] = __FUNCTION__;
+    $form_state->set('test_handlers', $test_handlers);
   }
 
   /**
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $form_state['test_handlers']['submit'][] = __FUNCTION__;
+    $test_handlers = $form_state->get('test_handlers');
+    $test_handlers['submit'][] = __FUNCTION__;
+    $form_state->set('test_handlers', $test_handlers);
   }
 
   /**
@@ -79,7 +87,7 @@ function testDefaultAndCustomHandlers() {
     $form_builder = $this->container->get('form_builder');
     $form_builder->submitForm($this, $form_state);
 
-    $handlers = $form_state['test_handlers'];
+    $handlers = $form_state->get('test_handlers');
 
     $this->assertIdentical(count($handlers['validate']), 2);
     $this->assertIdentical($handlers['validate'][0], 'customValidateForm');
diff --git a/core/modules/system/src/Tests/Form/FormTest.php b/core/modules/system/src/Tests/Form/FormTest.php
index be8d7e0..a377e6e 100644
--- a/core/modules/system/src/Tests/Form/FormTest.php
+++ b/core/modules/system/src/Tests/Form/FormTest.php
@@ -111,8 +111,8 @@ function testRequiredFields() {
           $user_input[$element] = $empty;
           $user_input['form_id'] = $form_id;
           $form_state->setUserInput($user_input);
-          $form_state['build_info']['callback_object'] = new StubForm($form_id, $form);
-          $form_state['method'] = 'post';
+          $form_state->setFormObject(new StubForm($form_id, $form));
+          $form_state->setMethod('POST');
           // The form token CSRF protection should not interfere with this test,
           // so we bypass it by setting the token to FALSE.
           $form['#token'] = FALSE;
diff --git a/core/modules/system/src/Tests/Form/ProgrammaticTest.php b/core/modules/system/src/Tests/Form/ProgrammaticTest.php
index 9b0234a..ef8130c 100644
--- a/core/modules/system/src/Tests/Form/ProgrammaticTest.php
+++ b/core/modules/system/src/Tests/Form/ProgrammaticTest.php
@@ -86,9 +86,8 @@ private function submitForm($values, $valid_input) {
 
     // We check submitted values only if we have a valid input.
     if ($valid_input) {
-      // By fetching the values from $form_state['storage'] we ensure that the
-      // submission handler was properly executed.
-      $stored_values = $form_state['storage']['programmatic_form_submit'];
+      // Fetching the values that were set in the submission handler.
+      $stored_values = $form_state->get('programmatic_form_submit');
       foreach ($values as $key => $value) {
         $this->assertEqual($stored_values[$key], $value, format_string('Submission handler correctly executed: %stored_key is %stored_value', array('%stored_key' => $key, '%stored_value' => print_r($value, TRUE))));
       }
@@ -108,16 +107,16 @@ public function testProgrammaticAccessBypass() {
     // Since programmed_bypass_access_check is set to TRUE by default, the
     // field is accessible and can be set.
     \Drupal::formBuilder()->submitForm('\Drupal\form_test\Form\FormTestProgrammaticForm', $form_state);
-    $values = $form_state['storage']['programmatic_form_submit'];
+    $values = $form_state->get('programmatic_form_submit');
     $this->assertEqual($values['field_restricted'], 'dummy value', 'The value for the restricted field is stored correctly.');
 
     // Programmatically submit the form with a value for the restricted field
     // with programmed_bypass_access_check set to FALSE. Since access
     // restrictions apply, the restricted field is inaccessible, and the value
     // should not be stored.
-    $form_state['programmed_bypass_access_check'] = FALSE;
+    $form_state->setProgrammedBypassAccessCheck(FALSE);
     \Drupal::formBuilder()->submitForm('\Drupal\form_test\Form\FormTestProgrammaticForm', $form_state);
-    $values = $form_state['storage']['programmatic_form_submit'];
+    $values = $form_state->get('programmatic_form_submit');
     $this->assertNotEqual($values['field_restricted'], 'dummy value', 'The value for the restricted field is not stored.');
 
   }
diff --git a/core/modules/system/src/Tests/Form/StorageTest.php b/core/modules/system/src/Tests/Form/StorageTest.php
index 8b60f2c..01189d1 100644
--- a/core/modules/system/src/Tests/Form/StorageTest.php
+++ b/core/modules/system/src/Tests/Form/StorageTest.php
@@ -64,7 +64,7 @@ function testForm() {
   }
 
   /**
-   * Tests using the form with an activated $form_state['cache'] property.
+   * Tests using the form after calling $form_state->setCached().
    */
   function testFormCached() {
     $this->drupalGet('form_test/form-storage', array('query' => array('cache' => 1)));
diff --git a/core/modules/system/src/Tests/Form/TriggeringElementProgrammedUnitTest.php b/core/modules/system/src/Tests/Form/TriggeringElementProgrammedUnitTest.php
index 19d683b..65a1ae0 100644
--- a/core/modules/system/src/Tests/Form/TriggeringElementProgrammedUnitTest.php
+++ b/core/modules/system/src/Tests/Form/TriggeringElementProgrammedUnitTest.php
@@ -62,7 +62,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    */
   public function validateForm(array &$form, FormStateInterface $form_state) {
     // Verify that the only submit button was recognized as triggering_element.
-    $this->assertEqual($form['actions']['submit']['#array_parents'], $form_state['triggering_element']['#array_parents']);
+    $this->assertEqual($form['actions']['submit']['#array_parents'], $form_state->getTriggeringElement()['#array_parents']);
   }
 
   /**
diff --git a/core/modules/system/src/Tests/Form/TriggeringElementTest.php b/core/modules/system/src/Tests/Form/TriggeringElementTest.php
index 21a2195..24cc2d2 100644
--- a/core/modules/system/src/Tests/Form/TriggeringElementTest.php
+++ b/core/modules/system/src/Tests/Form/TriggeringElementTest.php
@@ -10,7 +10,7 @@
 use Drupal\simpletest\WebTestBase;
 
 /**
- * Tests that FAPI correctly determines $form_state['triggering_element'].
+ * Tests that FAPI correctly determines the triggering element.
  *
  * @group Form
  */
@@ -24,7 +24,7 @@ class TriggeringElementTest extends WebTestBase {
   public static $modules = array('form_test');
 
   /**
-   * Test the determination of $form_state['triggering_element'] when no button
+   * Test the determination of the triggering element when no button
    * information is included in the POST data, as is sometimes the case when
    * the ENTER key is pressed in a textfield in Internet Explorer.
    */
@@ -33,50 +33,47 @@ function testNoButtonInfoInPost() {
     $edit = array();
     $form_html_id = 'form-test-clicked-button';
 
-    // Ensure submitting a form with no buttons results in no
-    // $form_state['triggering_element'] and the form submit handler not
-    // running.
+    // Ensure submitting a form with no buttons results in no triggering element
+    // and the form submit handler not running.
     $this->drupalPostForm($path, $edit, NULL, array(), array(), $form_html_id);
-    $this->assertText('There is no clicked button.', '$form_state[\'triggering_element\'] set to NULL.');
+    $this->assertText('There is no clicked button.', '$form_state->getTriggeringElement() set to NULL.');
     $this->assertNoText('Submit handler for form_test_clicked_button executed.', 'Form submit handler did not execute.');
 
-    // Ensure submitting a form with one or more submit buttons results in
-    // $form_state['triggering_element'] being set to the first one the user has
-    // access to. An argument with 'r' in it indicates a restricted
-    // (#access=FALSE) button.
+    // Ensure submitting a form with one or more submit buttons results in the
+    // triggering element being set to the first one the user has access to. An
+    // argument with 'r' in it indicates a restricted (#access=FALSE) button.
     $this->drupalPostForm($path . '/s', $edit, NULL, array(), array(), $form_html_id);
-    $this->assertText('The clicked button is button1.', '$form_state[\'triggering_element\'] set to only button.');
+    $this->assertText('The clicked button is button1.', '$form_state->getTriggeringElement() set to only button.');
     $this->assertText('Submit handler for form_test_clicked_button executed.', 'Form submit handler executed.');
 
     $this->drupalPostForm($path . '/s/s', $edit, NULL, array(), array(), $form_html_id);
-    $this->assertText('The clicked button is button1.', '$form_state[\'triggering_element\'] set to first button.');
+    $this->assertText('The clicked button is button1.', '$form_state->getTriggeringElement() set to first button.');
     $this->assertText('Submit handler for form_test_clicked_button executed.', 'Form submit handler executed.');
 
     $this->drupalPostForm($path . '/rs/s', $edit, NULL, array(), array(), $form_html_id);
-    $this->assertText('The clicked button is button2.', '$form_state[\'triggering_element\'] set to first available button.');
+    $this->assertText('The clicked button is button2.', '$form_state->getTriggeringElement() set to first available button.');
     $this->assertText('Submit handler for form_test_clicked_button executed.', 'Form submit handler executed.');
 
-    // Ensure submitting a form with buttons of different types results in
-    // $form_state['triggering_element'] being set to the first button,
-    // regardless of type. For the FAPI 'button' type, this should result in the
-    // submit handler not executing. The types are 's'(ubmit), 'b'(utton), and
-    // 'i'(mage_button).
+    // Ensure submitting a form with buttons of different types results in the
+    // triggering element being set to the first button, regardless of type. For
+    // the FAPI 'button' type, this should result in the submit handler not
+    // executing. The types are 's'(ubmit), 'b'(utton), and 'i'(mage_button).
     $this->drupalPostForm($path . '/s/b/i', $edit, NULL, array(), array(), $form_html_id);
-    $this->assertText('The clicked button is button1.', '$form_state[\'triggering_element\'] set to first button.');
+    $this->assertText('The clicked button is button1.', '$form_state->getTriggeringElement() set to first button.');
     $this->assertText('Submit handler for form_test_clicked_button executed.', 'Form submit handler executed.');
 
     $this->drupalPostForm($path . '/b/s/i', $edit, NULL, array(), array(), $form_html_id);
-    $this->assertText('The clicked button is button1.', '$form_state[\'triggering_element\'] set to first button.');
+    $this->assertText('The clicked button is button1.', '$form_state->getTriggeringElement() set to first button.');
     $this->assertNoText('Submit handler for form_test_clicked_button executed.', 'Form submit handler did not execute.');
 
     $this->drupalPostForm($path . '/i/s/b', $edit, NULL, array(), array(), $form_html_id);
-    $this->assertText('The clicked button is button1.', '$form_state[\'triggering_element\'] set to first button.');
+    $this->assertText('The clicked button is button1.', '$form_state->getTriggeringElement() set to first button.');
     $this->assertText('Submit handler for form_test_clicked_button executed.', 'Form submit handler executed.');
   }
 
   /**
-   * Test that $form_state['triggering_element'] does not get set to a button
-   * with #access=FALSE.
+   * Test that the triggering element does not get set to a button with
+   * #access=FALSE.
    */
   function testAttemptAccessControlBypass() {
     $path = 'form-test/clicked-button';
@@ -94,12 +91,11 @@ function testAttemptAccessControlBypass() {
     $elements[0]['name'] = 'button1';
     $this->drupalPostForm(NULL, array('button1' => 'button1'), NULL, array(), array(), $form_html_id);
 
-    // Ensure that $form_state['triggering_element'] was not set to the
-    // restricted button. Do this with both a negative and positive assertion,
-    // because negative assertions alone can be brittle. See
-    // testNoButtonInfoInPost() for why the triggering element gets set to
-    // 'button2'.
-    $this->assertNoText('The clicked button is button1.', '$form_state[\'triggering_element\'] not set to a restricted button.');
-    $this->assertText('The clicked button is button2.', '$form_state[\'triggering_element\'] not set to a restricted button.');
+    // Ensure that the triggering element was not set to the restricted button.
+    // Do this with both a negative and positive assertion, because negative
+    // assertions alone can be brittle. See testNoButtonInfoInPost() for why the
+    //triggering element gets set to 'button2'.
+    $this->assertNoText('The clicked button is button1.', '$form_state->getTriggeringElement() not set to a restricted button.');
+    $this->assertText('The clicked button is button2.', '$form_state->getTriggeringElement() not set to a restricted button.');
   }
 }
diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php
index 76a0680..e7a60a3 100644
--- a/core/modules/system/system.api.php
+++ b/core/modules/system/system.api.php
@@ -697,7 +697,7 @@ function hook_page_alter(&$page) {
  * @param $form_state
  *   The current state of the form. The arguments that
  *   \Drupal::formBuilder()->getForm() was originally called with are available
- *   in the array $form_state['build_info']['args'].
+ *   in the array $form_state->getBuildInfo()['args'].
  * @param $form_id
  *   String representing the name of the form itself. Typically this is the
  *   name of the function that generated the form.
@@ -736,7 +736,7 @@ function hook_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_stat
  * @param $form_state
  *   The current state of the form. The arguments that
  *   \Drupal::formBuilder()->getForm() was originally called with are available
- *   in the array $form_state['build_info']['args'].
+ *   in the array $form_state->getBuildInfo()['args'].
  * @param $form_id
  *   String representing the name of the form itself. Typically this is the
  *   name of the function that generated the form.
@@ -773,7 +773,7 @@ function hook_form_FORM_ID_alter(&$form, \Drupal\Core\Form\FormStateInterface $f
  *
  * To identify the base form ID for a particular form (or to determine whether
  * one exists) check the $form_state. The base form ID is stored under
- * $form_state['build_info']['base_form_id'].
+ * $form_state->getBuildInfo()['base_form_id'].
  *
  * Form alter hooks are called in the following order: hook_form_alter(),
  * hook_form_BASE_FORM_ID_alter(), hook_form_FORM_ID_alter(). See
diff --git a/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestLazyLoadForm.php b/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestLazyLoadForm.php
index d413195..96f5cd5 100644
--- a/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestLazyLoadForm.php
+++ b/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestLazyLoadForm.php
@@ -75,7 +75,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       drupal_render($attached);
       drupal_process_attached($attached);
     }
-    $form_state['rebuild'] = TRUE;
+    $form_state->setRebuild();
   }
 
 }
diff --git a/core/modules/system/tests/modules/batch_test/batch_test.module b/core/modules/system/tests/modules/batch_test/batch_test.module
index bc22b92..9cb123c 100644
--- a/core/modules/system/tests/modules/batch_test/batch_test.module
+++ b/core/modules/system/tests/modules/batch_test/batch_test.module
@@ -11,9 +11,9 @@
  * Batch operation: Submits form_test_mock_form() using drupal_form_submit().
  */
 function _batch_test_nested_drupal_form_submit_callback($value) {
-  $state = new FormState();
-  $state['values']['test_value'] = $value;
-  \Drupal::formBuilder()->submitForm('Drupal\batch_test\Form\BatchTestMockForm', $state);
+  $form_state = (new FormState())
+    ->setValue('test_value', $value);
+  \Drupal::formBuilder()->submitForm('Drupal\batch_test\Form\BatchTestMockForm', $form_state);
 }
 
 /**
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 e5c72e9..8d40948 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
@@ -26,12 +26,14 @@ public function getFormId() {
    * {@inheritdoc}
    */
   public function buildForm(array $form, FormStateInterface $form_state) {
-    if (empty($form_state['storage']['step'])) {
-      $form_state['storage']['step'] = 1;
+    $step = $form_state->get('step');
+    if (empty($step)) {
+      $step = 1;
+      $form_state->set('step', $step);
     }
 
     $form['step_display'] = array(
-      '#markup' => 'step ' . $form_state['storage']['step'] . '<br/>',
+      '#markup' => 'step ' . $step . '<br/>',
     );
     $form['submit'] = array(
       '#type' => 'submit',
@@ -47,7 +49,8 @@ public function buildForm(array $form, FormStateInterface $form_state) {
   public function submitForm(array &$form, FormStateInterface $form_state) {
     batch_test_stack(NULL, TRUE);
 
-    switch ($form_state['storage']['step']) {
+    $step = $form_state->get('step');
+    switch ($step) {
       case 1:
         batch_set(_batch_test_batch_1());
         break;
@@ -56,9 +59,9 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
         break;
     }
 
-    if ($form_state['storage']['step'] < 2) {
-      $form_state['storage']['step']++;
-      $form_state['rebuild'] = TRUE;
+    if ($step < 2) {
+      $form_state->set('step', ++$step);
+      $form_state->setRebuild();
     }
 
     $form_state->setRedirect('batch_test.redirect');
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 2051884..6845520 100644
--- a/core/modules/system/tests/modules/entity_test/src/EntityTestForm.php
+++ b/core/modules/system/tests/modules/entity_test/src/EntityTestForm.php
@@ -93,7 +93,7 @@ public function save(array $form, FormStateInterface $form_state) {
     else {
       // Error on save.
       drupal_set_message(t('The entity could not be saved.'), 'error');
-      $form_state['rebuild'] = TRUE;
+      $form_state->setRebuild();
     }
   }
 
diff --git a/core/modules/system/tests/modules/form_test/form_test.module b/core/modules/system/tests/modules/form_test/form_test.module
index ad38397..380241b 100644
--- a/core/modules/system/tests/modules/form_test/form_test.module
+++ b/core/modules/system/tests/modules/form_test/form_test.module
@@ -99,7 +99,7 @@ function form_test_form_form_test_state_persist_alter(&$form, FormStateInterface
   // Simulate a form alter implementation inserting form elements that enable
   // caching of the form, e.g. elements having #ajax.
   if (\Drupal::request()->get('cache')) {
-    $form_state['cache'] = TRUE;
+    $form_state->setCached();
   }
 }
 
@@ -119,5 +119,5 @@ function form_test_form_user_register_form_alter(&$form, FormStateInterface $for
  */
 function form_test_user_register_form_rebuild($form, FormStateInterface $form_state) {
   drupal_set_message('Form rebuilt.');
-  $form_state['rebuild'] = TRUE;
+  $form_state->setRebuild();
 }
diff --git a/core/modules/system/tests/modules/form_test/src/Callbacks.php b/core/modules/system/tests/modules/form_test/src/Callbacks.php
index ed26dd9..3edf0fa 100644
--- a/core/modules/system/tests/modules/form_test/src/Callbacks.php
+++ b/core/modules/system/tests/modules/form_test/src/Callbacks.php
@@ -28,15 +28,15 @@ public function validateName(&$element, FormStateInterface $form_state) {
       $triggered = TRUE;
     }
     if ($form_state->getValue('name') == 'element_validate_access') {
-      $form_state['storage']['form_test_name'] = $form_state->getValue('name');
+      $form_state->set('form_test_name', $form_state->getValue('name'));
       // Alter the form element.
       $element['#access'] = FALSE;
 
       $triggered = TRUE;
     }
-    elseif (!empty($form_state['storage']['form_test_name'])) {
+    elseif ($form_state->has('form_test_name')) {
       // To simplify this test, just take over the element's value into $form_state.
-      form_set_value($element, $form_state['storage']['form_test_name'], $form_state);
+      form_set_value($element, $form_state->get('form_test_name'), $form_state);
 
       $triggered = TRUE;
     }
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 a302fb0..ccd752f 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
@@ -27,7 +27,7 @@ public function getFormId() {
    * {@inheritdoc}
    */
   public function buildForm(array $form, FormStateInterface $form_state, $json = TRUE) {
-    $form_state['json'] = $json;
+    $form_state->set('json', $json);
     $form['checkbox_off'] = array(
       '#title' => t('Checkbox off'),
       '#type' => 'checkboxes',
@@ -56,11 +56,11 @@ public function buildForm(array $form, FormStateInterface $form_state, $json = T
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    if (!empty($form_state['json'])) {
+    if ($form_state->has('json')) {
       $form_state->setResponse(new JsonResponse($form_state->getValues()));
     }
     else {
-      $form_state['no_redirect'] = TRUE;
+      $form_state->disableRedirect();
     }
   }
 
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestClickedButtonForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestClickedButtonForm.php
index b0c4957..72ac7ac 100644
--- a/core/modules/system/tests/modules/form_test/src/Form/FormTestClickedButtonForm.php
+++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestClickedButtonForm.php
@@ -85,8 +85,8 @@ public function buildForm(array $form, FormStateInterface $form_state, $first =
    * {@inheritdoc}
    */
   public function validateForm(array &$form, FormStateInterface $form_state) {
-    if (isset($form_state['triggering_element'])) {
-      drupal_set_message(t('The clicked button is %name.', array('%name' => $form_state['triggering_element']['#name'])));
+    if ($triggering_element = $form_state->getTriggeringElement()) {
+      drupal_set_message(t('The clicked button is %name.', ['%name' => $triggering_element['#name']]));
     }
     else {
       drupal_set_message('There is no clicked button.');
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestFormStateDatabaseForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestFormStateDatabaseForm.php
index a0dda13..87014c7 100644
--- a/core/modules/system/tests/modules/form_test/src/Form/FormTestFormStateDatabaseForm.php
+++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestFormStateDatabaseForm.php
@@ -38,10 +38,10 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     );
 
     $db = Database::getConnection('default');
-    $form_state['storage']['database'] = $db;
-    $form_state['storage']['database_class'] = get_class($db);
+    $form_state->set('database', $db);
+    $form_state->set('database_class', get_class($db));
 
-    if (isset($form_state['storage']['database_connection_found'])) {
+    if ($form_state->has('database_connection_found')) {
       $form['database']['#markup'] = 'Database connection found';
     }
 
@@ -52,11 +52,12 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $form_state['cache'] = TRUE;
-    $form_state['rebuild'] = TRUE;
+    $form_state->setCached();
+    $form_state->setRebuild();
 
-    if ($form_state['storage']['database'] instanceof $form_state['storage']['database_class']) {
-      $form_state['storage']['database_connection_found'] = TRUE;
+    $database_class = $form_state->get('database_class');
+    if ($form_state->get('database') instanceof $database_class) {
+      $form_state->set('database_connection_found', TRUE);
     }
   }
 
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestProgrammaticForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestProgrammaticForm.php
index baa146b..f5d1667 100644
--- a/core/modules/system/tests/modules/form_test/src/Form/FormTestProgrammaticForm.php
+++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestProgrammaticForm.php
@@ -99,7 +99,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $form_state['storage']['programmatic_form_submit'] = $form_state->getValues();
+    $form_state->set('programmatic_form_submit', $form_state->getValues());
   }
 
 }
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestRebuildPreserveValuesForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestRebuildPreserveValuesForm.php
index 00a9570..45d485c 100644
--- a/core/modules/system/tests/modules/form_test/src/Form/FormTestRebuildPreserveValuesForm.php
+++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestRebuildPreserveValuesForm.php
@@ -49,7 +49,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     // checkboxes and a textfield. The test is to make sure that the rebuild
     // triggered by this button preserves the user input values for the initial
     // elements and initializes the new elements with the correct default values.
-    if (empty($form_state['storage']['add_more'])) {
+    if (!$form_state->has('add_more')) {
       $form['add_more'] = array(
         '#type' => 'submit',
         '#value' => 'Add more',
@@ -88,8 +88,8 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    */
   public function addMoreSubmitForm(array &$form, FormStateInterface $form_state) {
     // Rebuild, to test preservation of input values.
-    $form_state['storage']['add_more'] = TRUE;
-    $form_state['rebuild'] = TRUE;
+    $form_state->set('add_more', TRUE);
+    $form_state->setRebuild();
   }
 
   /**
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 c00dc1b..7fc352e 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
@@ -58,7 +58,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       }
     }
     else {
-      $form_state['no_redirect'] = TRUE;
+      $form_state->disableRedirect();
     }
   }
 
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestStatePersistForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestStatePersistForm.php
index f34f926..a4e570e 100644
--- a/core/modules/system/tests/modules/form_test/src/Form/FormTestStatePersistForm.php
+++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestStatePersistForm.php
@@ -32,7 +32,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#default_value' => 'DEFAULT',
       '#required' => TRUE,
     );
-    $form_state['value'] = 'State persisted.';
+    $form_state->set('value', 'State persisted.');
 
     $form['submit'] = array(
       '#type' => 'submit',
@@ -45,8 +45,8 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    drupal_set_message($form_state['value']);
-    $form_state['rebuild'] = TRUE;
+    drupal_set_message($form_state->get('value'));
+    $form_state->setRebuild();
   }
 
 }
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 fb23160..c5f166b 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
@@ -32,22 +32,24 @@ public function getFormId() {
    * {@inheritdoc}
    */
   public function buildForm(array $form, FormStateInterface $form_state) {
-    if ($form_state['rebuild']) {
+    if ($form_state->isRebuilding()) {
       $form_state->setUserInput(array());
     }
     // Initialize
-    if (empty($form_state['storage'])) {
+    $storage = $form_state->getStorage();
+    if (empty($storage)) {
       $user_input = $form_state->getUserInput();
       if (empty($user_input)) {
         $_SESSION['constructions'] = 0;
       }
       // Put the initial thing into the storage
-      $form_state['storage'] = array(
-        'thing' => array(
+      $storage = [
+        'thing' => [
           'title' => 'none',
           'value' => '',
-        ),
-      );
+        ],
+      ];
+      $form_state->setStorage($storage);
     }
     // Count how often the form is constructed.
     $_SESSION['constructions']++;
@@ -56,13 +58,13 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     $form['title'] = array(
       '#type' => 'textfield',
       '#title' => 'Title',
-      '#default_value' => $form_state['storage']['thing']['title'],
+      '#default_value' => $storage['thing']['title'],
       '#required' => TRUE,
     );
     $form['value'] = array(
       '#type' => 'textfield',
       '#title' => 'Value',
-      '#default_value' => $form_state['storage']['thing']['value'],
+      '#default_value' => $storage['thing']['value'],
       '#element_validate' => array('::elementValidateValueCached'),
     );
     $form['continue_button'] = array(
@@ -83,7 +85,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     if (\Drupal::request()->get('cache')) {
       // Manually activate caching, so we can test that the storage keeps working
       // when it's enabled.
-      $form_state['cache'] = TRUE;
+      $form_state->setCached();
     }
 
     return $form;
@@ -100,7 +102,7 @@ public function elementValidateValueCached($element, FormStateInterface $form_st
     // elsewhere in the form. Form API should still update the cached form storage
     // though.
     if (\Drupal::request()->get('cache') && $form_state->getValue('value') == 'change_title') {
-      $form_state['storage']['thing']['changed'] = TRUE;
+      $form_state->set(['thing', 'changed'], TRUE);
     }
   }
 
@@ -108,9 +110,9 @@ public function elementValidateValueCached($element, FormStateInterface $form_st
    * {@inheritdoc}
    */
   public function continueSubmitForm(array &$form, FormStateInterface $form_state) {
-    $form_state['storage']['thing']['title'] = $form_state->getValue('title');
-    $form_state['storage']['thing']['value'] = $form_state->getValue('value');
-    $form_state['rebuild'] = TRUE;
+    $form_state->set(['thing', 'title'], $form_state->getValue('title'));
+    $form_state->set(['thing', 'value'], $form_state->getValue('value'));
+    $form_state->setRebuild();
   }
 
   /**
@@ -119,7 +121,7 @@ public function continueSubmitForm(array &$form, FormStateInterface $form_state)
   public function submitForm(array &$form, FormStateInterface $form_state) {
     drupal_set_message("Title: " . String::checkPlain($form_state->getValue('title')));
     drupal_set_message("Form constructions: " . $_SESSION['constructions']);
-    if (isset($form_state['storage']['thing']['changed'])) {
+    if ($form_state->has(['thing', 'changed'])) {
       drupal_set_message("The thing has been changed.");
     }
     $form_state->setRedirect('<front>');
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestValidateForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestValidateForm.php
index d9293b4..7da8f5d 100644
--- a/core/modules/system/tests/modules/form_test/src/Form/FormTestValidateForm.php
+++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestValidateForm.php
@@ -51,7 +51,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
 
     // To simplify this test, enable form caching and use form storage to
     // remember our alteration.
-    $form_state['cache'] = TRUE;
+    $form_state->setCached();
 
     return $form;
   }
diff --git a/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/TestToolkit.php b/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/TestToolkit.php
index 81688ab..f72eaaa 100644
--- a/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/TestToolkit.php
+++ b/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/TestToolkit.php
@@ -112,7 +112,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
    * {@inheritdoc}
    */
   public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
-    if ($form_state['values']['test']['test_parameter'] == 0) {
+    if ($form_state->getValue(['test', 'test_parameter']) == 0) {
       $form_state->setErrorByName('test][test_parameter', $this->t('Test parameter should be different from 0.'));
     }
   }
diff --git a/core/modules/taxonomy/src/Form/OverviewTerms.php b/core/modules/taxonomy/src/Form/OverviewTerms.php
index ce54c1c..6020b61 100644
--- a/core/modules/taxonomy/src/Form/OverviewTerms.php
+++ b/core/modules/taxonomy/src/Form/OverviewTerms.php
@@ -71,7 +71,7 @@ public function buildForm(array $form, FormStateInterface $form_state, Vocabular
     // @todo Remove global variables when http://drupal.org/node/2044435 is in.
     global $pager_page_array, $pager_total, $pager_total_items;
 
-    $form_state['taxonomy']['vocabulary'] = $taxonomy_vocabulary;
+    $form_state->set(['taxonomy', 'vocabulary'], $taxonomy_vocabulary);
     $parent_fields = FALSE;
 
     $page = $this->getRequest()->query->get('page') ?: 0;
@@ -369,7 +369,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     // Sort term order based on weight.
     uasort($form_state->getValue('terms'), array('Drupal\Component\Utility\SortArray', 'sortByWeightElement'));
 
-    $vocabulary = $form_state['taxonomy']['vocabulary'];
+    $vocabulary = $form_state->get(['taxonomy', 'vocabulary']);
     // Update the current hierarchy type as we go.
     $hierarchy = TAXONOMY_HIERARCHY_DISABLED;
 
@@ -452,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'];
+    $vocabulary = $form_state->get(['taxonomy', 'vocabulary']);
     $form_state->setRedirectUrl($vocabulary->urlInfo('reset-form'));
   }
 
diff --git a/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php b/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php
index 5c3e50a..39da170 100644
--- a/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php
+++ b/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php
@@ -161,7 +161,7 @@ protected function valueForm(&$form, FormStateInterface $form_state) {
 
       $default_value = (array) $this->value;
 
-      if (!empty($form_state['exposed'])) {
+      if ($exposed = $form_state->get('exposed')) {
         $identifier = $this->options['expose']['identifier'];
 
         if (!empty($this->options['expose']['reduce'])) {
@@ -201,13 +201,13 @@ protected function valueForm(&$form, FormStateInterface $form_state) {
       );
 
       $user_input = $form_state->getUserInput();
-      if (!empty($form_state['exposed']) && isset($identifier) && !isset($user_input[$identifier])) {
+      if ($exposed && isset($identifier) && !isset($user_input[$identifier])) {
         $user_input[$identifier] = $default_value;
         $form_state->setUserInput($user_input);
       }
     }
 
-    if (empty($form_state['exposed'])) {
+    if (!$form_state->get('exposed')) {
       // Retain the helper option
       $this->helper->buildOptionsForm($form, $form_state);
     }
diff --git a/core/modules/taxonomy/src/TermForm.php b/core/modules/taxonomy/src/TermForm.php
index 4a82e67..2fa6f4b 100644
--- a/core/modules/taxonomy/src/TermForm.php
+++ b/core/modules/taxonomy/src/TermForm.php
@@ -25,8 +25,8 @@ public function form(array $form, FormStateInterface $form_state) {
     $vocabulary = $vocab_storage->load($term->bundle());
 
     $parent = array_keys(taxonomy_term_load_parents($term->id()));
-    $form_state['taxonomy']['parent'] = $parent;
-    $form_state['taxonomy']['vocabulary'] = $vocabulary;
+    $form_state->set(['taxonomy', 'parent'], $parent);
+    $form_state->set(['taxonomy', 'vocabulary'], $vocabulary);
 
     $language_configuration = $this->moduleHandler->moduleExists('language') ? language_get_default_configuration('taxonomy_term', $vocabulary->id()) : FALSE;
     $form['langcode'] = array(
@@ -146,7 +146,7 @@ public function save(array $form, FormStateInterface $form_state) {
     }
 
     $current_parent_count = count($form_state->getValue('parent'));
-    $previous_parent_count = count($form_state['taxonomy']['parent']);
+    $previous_parent_count = count($form_state->get(['taxonomy', 'parent']));
     // Root doesn't count if it's the only parent.
     if ($current_parent_count == 1 && $form_state->hasValue(array('parent', 0))) {
       $current_parent_count = 0;
@@ -155,18 +155,19 @@ public function save(array $form, FormStateInterface $form_state) {
 
     // If the number of parents has been reduced to one or none, do a check on the
     // parents of every term in the vocabulary value.
+    $vocabulary = $form_state->get(['taxonomy', 'vocabulary']);
     if ($current_parent_count < $previous_parent_count && $current_parent_count < 2) {
-      taxonomy_check_vocabulary_hierarchy($form_state['taxonomy']['vocabulary'], $form_state->getValues());
+      taxonomy_check_vocabulary_hierarchy($vocabulary, $form_state->getValues());
     }
     // If we've increased the number of parents and this is a single or flat
     // hierarchy, update the vocabulary immediately.
-    elseif ($current_parent_count > $previous_parent_count && $form_state['taxonomy']['vocabulary']->hierarchy != TAXONOMY_HIERARCHY_MULTIPLE) {
-      $form_state['taxonomy']['vocabulary']->hierarchy = $current_parent_count == 1 ? TAXONOMY_HIERARCHY_SINGLE : TAXONOMY_HIERARCHY_MULTIPLE;
-      $form_state['taxonomy']['vocabulary']->save();
+    elseif ($current_parent_count > $previous_parent_count && $vocabulary->hierarchy != TAXONOMY_HIERARCHY_MULTIPLE) {
+      $vocabulary->hierarchy = $current_parent_count == 1 ? TAXONOMY_HIERARCHY_SINGLE : TAXONOMY_HIERARCHY_MULTIPLE;
+      $vocabulary->save();
     }
 
     $form_state->setValue('tid', $term->id());
-    $form_state['tid'] = $term->id();
+    $form_state->set('tid', $term->id());
   }
 
 }
diff --git a/core/modules/taxonomy/src/VocabularyForm.php b/core/modules/taxonomy/src/VocabularyForm.php
index 5a70f8d..ef61676 100644
--- a/core/modules/taxonomy/src/VocabularyForm.php
+++ b/core/modules/taxonomy/src/VocabularyForm.php
@@ -91,7 +91,7 @@ public function form(array $form, FormStateInterface $form_state) {
    */
   protected function actions(array $form, FormStateInterface $form_state) {
     // If we are displaying the delete confirmation skip the regular actions.
-    if (empty($form_state['confirm_delete'])) {
+    if (!$form_state->get('confirm_delete')) {
       $actions = parent::actions($form, $form_state);
       // Add the language configuration submit handler. This is needed because
       // the submit button has custom submit handlers.
@@ -125,7 +125,7 @@ public function languageConfigurationSubmit(array &$form, FormStateInterface $fo
     // Since the machine name is not known yet, and it can be changed anytime,
     // we have to also update the bundle property for the default language
     // configuration in order to have the correct bundle value.
-    $form_state['language']['default_language']['bundle'] = $form_state->getValue('vid');
+    $form_state->set(['language', 'default_language', 'bundle'], $form_state->getValue('vid'));
   }
 
   /**
@@ -154,7 +154,7 @@ public function save(array $form, FormStateInterface $form_state) {
     }
 
     $form_state->setValue('vid', $vocabulary->id());
-    $form_state['vid'] = $vocabulary->id();
+    $form_state->set('vid', $vocabulary->id());
   }
 
 }
diff --git a/core/modules/update/src/UpdateSettingsForm.php b/core/modules/update/src/UpdateSettingsForm.php
index b1e0f32..fb872b6 100644
--- a/core/modules/update/src/UpdateSettingsForm.php
+++ b/core/modules/update/src/UpdateSettingsForm.php
@@ -72,7 +72,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    * Implements \Drupal\Core\Form\FormInterface::validateForm().
    */
   public function validateForm(array &$form, FormStateInterface $form_state) {
-    $form_state['notify_emails'] = array();
+    $form_state->set('notify_emails', []);
     if (!$form_state->isValueEmpty('update_notify_emails')) {
       $valid = array();
       $invalid = array();
@@ -88,7 +88,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
         }
       }
       if (empty($invalid)) {
-        $form_state['notify_emails'] = $valid;
+        $form_state->set('notify_emails', $valid);
       }
       elseif (count($invalid) == 1) {
         $form_state->setErrorByName('update_notify_emails', $this->t('%email is not a valid email address.', array('%email' => reset($invalid))));
@@ -115,7 +115,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $config
       ->set('check.disabled_extensions', $form_state->getValue('update_check_disabled'))
       ->set('check.interval_days', $form_state->getValue('update_check_frequency'))
-      ->set('notification.emails', $form_state['notify_emails'])
+      ->set('notification.emails', $form_state->get('notify_emails'))
       ->set('notification.threshold', $form_state->getValue('update_notification_threshold'))
       ->save();
 
diff --git a/core/modules/user/src/AccountForm.php b/core/modules/user/src/AccountForm.php
index 3e428f6..ba11c0e 100644
--- a/core/modules/user/src/AccountForm.php
+++ b/core/modules/user/src/AccountForm.php
@@ -156,7 +156,7 @@ public function form(array $form, FormStateInterface $form_state) {
           '#attributes' => array('autocomplete' => 'off'),
         );
 
-        $form_state['user'] = $account;
+        $form_state->set('user', $account);
         $form['#validate'][] = 'user_validate_current_pass';
       }
     }
diff --git a/core/modules/user/src/AccountSettingsForm.php b/core/modules/user/src/AccountSettingsForm.php
index d164f6e..9a85569 100644
--- a/core/modules/user/src/AccountSettingsForm.php
+++ b/core/modules/user/src/AccountSettingsForm.php
@@ -106,7 +106,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
         '#open' => TRUE,
         '#tree' => TRUE,
       );
-      $form_state['content_translation']['key'] = 'language';
+      $form_state->set(['content_translation', 'key'], 'language');
       $form['language'] += content_translation_enable_widget('user', 'user', $form, $form_state);
     }
 
diff --git a/core/modules/user/src/Form/UserLoginForm.php b/core/modules/user/src/Form/UserLoginForm.php
index 25511a8..e1275a4 100644
--- a/core/modules/user/src/Form/UserLoginForm.php
+++ b/core/modules/user/src/Form/UserLoginForm.php
@@ -116,7 +116,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $account = $this->userStorage->load($form_state['uid']);
+    $account = $this->userStorage->load($form_state->get('uid'));
 
     // A destination was set, probably on an exception controller,
     if (!$this->getRequest()->request->has('destination')) {
@@ -145,7 +145,7 @@ public function validateName(array &$form, FormStateInterface $form_state) {
   /**
    * Checks supplied username/password against local users table.
    *
-   * If successful, $form_state['uid'] is set to the matching user ID.
+   * If successful, $form_state->get('uid') is set to the matching user ID.
    */
   public function validateAuthentication(array &$form, FormStateInterface $form_state) {
     $password = trim($form_state->getValue('pass'));
@@ -157,7 +157,7 @@ public function validateAuthentication(array &$form, FormStateInterface $form_st
       // in to many different user accounts.  We have a reasonably high limit
       // since there may be only one apparent IP for all users at an institution.
       if (!$this->flood->isAllowed('user.failed_login_ip', $flood_config->get('ip_limit'), $flood_config->get('ip_window'))) {
-        $form_state['flood_control_triggered'] = 'ip';
+        $form_state->set('flood_control_triggered', 'ip');
         return;
       }
       $accounts = $this->userStorage->loadByProperties(array('name' => $form_state->getValue('name'), 'status' => 1));
@@ -174,18 +174,19 @@ public function validateAuthentication(array &$form, FormStateInterface $form_st
           // could lock out all users with public user names.
           $identifier = $account->id() . '-' . $this->getRequest()->getClientIP();
         }
-        $form_state['flood_control_user_identifier'] = $identifier;
+        $form_state->set('flood_control_user_identifier', $identifier);
 
         // Don't allow login if the limit for this user has been reached.
         // Default is to allow 5 failed attempts every 6 hours.
         if (!$this->flood->isAllowed('user.failed_login_user', $flood_config->get('user_limit'), $flood_config->get('user_window'), $identifier)) {
-          $form_state['flood_control_triggered'] = 'user';
+          $form_state->set('flood_control_triggered', 'user');
           return;
         }
       }
       // We are not limited by flood control, so try to authenticate.
-      // Set $form_state['uid'] as a flag for self::validateFinal().
-      $form_state['uid'] = $this->userAuth->authenticate($form_state->getValue('name'), $password);
+      // Store $uid in form state as a flag for self::validateFinal().
+      $uid = $this->userAuth->authenticate($form_state->getValue('name'), $password);
+      $form_state->set('uid', $uid);
     }
   }
 
@@ -196,16 +197,16 @@ public function validateAuthentication(array &$form, FormStateInterface $form_st
    */
   public function validateFinal(array &$form, FormStateInterface $form_state) {
     $flood_config = $this->config('user.flood');
-    if (empty($form_state['uid'])) {
+    if (!$form_state->get('uid')) {
       // Always register an IP-based failed login event.
       $this->flood->register('user.failed_login_ip', $flood_config->get('ip_window'));
       // Register a per-user failed login event.
-      if (isset($form_state['flood_control_user_identifier'])) {
-        $this->flood->register('user.failed_login_user', $flood_config->get('user_window'), $form_state['flood_control_user_identifier']);
+      if ($flood_control_user_identifier = $form_state->get('flood_control_user_identifier')) {
+        $this->flood->register('user.failed_login_user', $flood_config->get('user_window'), $flood_control_user_identifier);
       }
 
-      if (isset($form_state['flood_control_triggered'])) {
-        if ($form_state['flood_control_triggered'] == 'user') {
+      if ($flood_control_triggered = $form_state->get('flood_control_triggered')) {
+        if ($flood_control_triggered == 'user') {
           $form_state->setErrorByName('name', format_plural($flood_config->get('user_limit'), 'Sorry, there has been more than one failed login attempt for this account. It is temporarily blocked. Try again later or <a href="@url">request a new password</a>.', 'Sorry, there have been more than @count failed login attempts for this account. It is temporarily blocked. Try again later or <a href="@url">request a new password</a>.', array('@url' => url('user/password'))));
         }
         else {
@@ -226,10 +227,10 @@ public function validateFinal(array &$form, FormStateInterface $form_state) {
         }
       }
     }
-    elseif (isset($form_state['flood_control_user_identifier'])) {
+    elseif ($flood_control_user_identifier = $form_state->get('flood_control_user_identifier')) {
       // Clear past failures for this user so as not to block a user who might
       // log in and out more than once in an hour.
-      $this->flood->clear('user.failed_login_user', $form_state['flood_control_user_identifier']);
+      $this->flood->clear('user.failed_login_user', $flood_control_user_identifier);
     }
   }
 
diff --git a/core/modules/user/src/Plugin/views/filter/Name.php b/core/modules/user/src/Plugin/views/filter/Name.php
index fb72e08..c32abe1 100644
--- a/core/modules/user/src/Plugin/views/filter/Name.php
+++ b/core/modules/user/src/Plugin/views/filter/Name.php
@@ -47,7 +47,7 @@ protected function valueForm(&$form, FormStateInterface $form_state) {
     );
 
     $user_input = $form_state->getUserInput();
-    if (!empty($form_state['exposed']) && !isset($user_input[$this->options['expose']['identifier']])) {
+    if ($form_state->get('exposed') && !isset($user_input[$this->options['expose']['identifier']])) {
       $user_input[$this->options['expose']['identifier']] = $default_value;
       $form_state->setUserInput($user_input);
     }
diff --git a/core/modules/user/src/RegisterForm.php b/core/modules/user/src/RegisterForm.php
index 64843fb..5d2d5ec 100644
--- a/core/modules/user/src/RegisterForm.php
+++ b/core/modules/user/src/RegisterForm.php
@@ -112,7 +112,7 @@ public function save(array $form, FormStateInterface $form_state) {
     // Assume save has gone through correctly.
     $account->save();
 
-    $form_state['user'] = $account;
+    $form_state->set('user', $account);
     $form_state->setValue('uid', $account->id());
 
     $this->logger('user')->notice('New user: %name %email.', array('%name' => $form_state->getValue('name'), '%email' => '<' . $form_state->getValue('mail') . '>', 'type' => l($this->t('Edit'), 'user/' . $account->id() . '/edit')));
diff --git a/core/modules/user/src/Tests/UserAccountFormFieldsTest.php b/core/modules/user/src/Tests/UserAccountFormFieldsTest.php
index 492218f..df01adc 100644
--- a/core/modules/user/src/Tests/UserAccountFormFieldsTest.php
+++ b/core/modules/user/src/Tests/UserAccountFormFieldsTest.php
@@ -33,7 +33,7 @@ function testInstallConfigureForm() {
     require_once DRUPAL_ROOT . '/core/includes/install.inc';
     $install_state = install_state_defaults();
     $form_state = new FormState();
-    $form_state['build_info']['args'][] = &$install_state;
+    $form_state->addBuildInfo('args', [&$install_state]);
     $form = $this->container->get('form_builder')
       ->buildForm('Drupal\Core\Installer\Form\SiteConfigureForm', $form_state);
 
diff --git a/core/modules/user/tests/modules/user_form_test/src/Form/TestCurrentPassword.php b/core/modules/user/tests/modules/user_form_test/src/Form/TestCurrentPassword.php
index b01fc79..3dd75e1 100644
--- a/core/modules/user/tests/modules/user_form_test/src/Form/TestCurrentPassword.php
+++ b/core/modules/user/tests/modules/user_form_test/src/Form/TestCurrentPassword.php
@@ -30,7 +30,7 @@ public function getFormId() {
    *   The user account.
    */
   public function buildForm(array $form, FormStateInterface $form_state, UserInterface $user = NULL) {
-    $form_state['user'] = $user ;
+    $form_state->set('user', $user);
     $form['user_form_test_field'] = array(
       '#type' => 'textfield',
       '#title' => $this->t('Test field'),
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index aed59c7..eb3d5ae 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -498,7 +498,7 @@ function _user_language_selector_langcode_value($element, $input, FormStateInter
  * @see AccountForm::form()
  */
 function user_validate_current_pass(&$form, FormStateInterface $form_state) {
-  $account = $form_state['user'];
+  $account = $form_state->get('user');
   foreach ($form_state->getValue('current_pass_required_values') as $key => $name) {
     // This validation only works for required textfields (like mail) or
     // form values like password_confirm that have their own validation
diff --git a/core/modules/views/includes/ajax.inc b/core/modules/views/includes/ajax.inc
index c6daa71..16f4546 100644
--- a/core/modules/views/includes/ajax.inc
+++ b/core/modules/views/includes/ajax.inc
@@ -5,6 +5,7 @@
  * Handles the server side AJAX interactions of Views.
  */
 
+use Drupal\Component\Utility\Html;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\views\Ajax\HighlightCommand;
 use Drupal\Core\Ajax\OpenModalDialogCommand;
@@ -20,9 +21,10 @@ function views_ajax_form_wrapper($form_class, FormStateInterface &$form_state) {
   if (!$form_state->has('rerender')) {
     $form_state->set('rerender', FALSE);
   }
+  $ajax = $form_state->get('ajax');
   // Do not overwrite if the redirect has been disabled.
   if (!$form_state->isRedirectDisabled()) {
-    $form_state->disableRedirect(!empty($form_state['ajax']));
+    $form_state->disableRedirect($ajax);
   }
   $form_state->disableCache();
 
@@ -31,11 +33,12 @@ function views_ajax_form_wrapper($form_class, FormStateInterface &$form_state) {
   drupal_process_attached($form);
 
   // These forms have the title built in, so set the title here:
-  if (empty($form_state['ajax']) && !empty($form_state['title'])) {
+  $title = $form_state->get('title') ?: '';
+  if (!$ajax && $title) {
     $form['#attached']['css'][] = drupal_get_path('module', 'views_ui') . '/css/views_ui.admin.css';
   }
 
-  if (!empty($form_state['ajax']) && (empty($form_state['executed']) || !empty($form_state['rerender']))) {
+  if ($ajax && (!$form_state->isExecuted() || $form_state->get('rerender'))) {
     // If the form didn't execute and we're using ajax, build up a
     // Ajax command list to execute.
     $response = new AjaxResponse();
@@ -47,7 +50,6 @@ function views_ajax_form_wrapper($form_class, FormStateInterface &$form_state) {
     }
     $display .= $output;
 
-    $title = empty($form_state['title']) ? '' : $form_state['title'];
     $options = array(
       'dialogClass' => 'views-ui-dialog',
       'width' => '50%',
@@ -55,12 +57,12 @@ function views_ajax_form_wrapper($form_class, FormStateInterface &$form_state) {
 
     $response->addCommand(new OpenModalDialogCommand($title, $display, $options));
 
-    if (!empty($form_state['#section'])) {
-      $response->addCommand(new HighlightCommand('.' . drupal_clean_css_identifier($form_state['#section'])));
+    if ($section = $form_state->get('#section')) {
+      $response->addCommand(new HighlightCommand('.' . Html::cleanCssIdentifier($section)));
     }
 
     return $response;
   }
 
-  return (!empty($form_state['title'])) ? array('#title' => $form_state['title'], '#markup' => $output) : $output;
+  return $title ? ['#title' => $title, '#markup' => $output] : $output;
 }
diff --git a/core/modules/views/src/Form/ViewsExposedForm.php b/core/modules/views/src/Form/ViewsExposedForm.php
index 6b6d610..ee2fa2d 100644
--- a/core/modules/views/src/Form/ViewsExposedForm.php
+++ b/core/modules/views/src/Form/ViewsExposedForm.php
@@ -63,15 +63,15 @@ public function buildForm(array $form, FormStateInterface $form_state) {
 
     // Make sure that we validate because this form might be submitted
     // multiple times per page.
-    $form_state['must_validate'] = TRUE;
+    $form_state->setValidationEnforced();
     /** @var \Drupal\views\ViewExecutable $view */
-    $view = $form_state['view'];
-    $display = &$form_state['display'];
+    $view = $form_state->get('view');
+    $display = &$form_state->get('display');
 
     $form_state->setUserInput($view->getExposedInput());
 
     // Let form plugins know this is for exposed widgets.
-    $form_state['exposed'] = TRUE;
+    $form_state->set('exposed', TRUE);
     // Check if the form was already created
     if ($cache = $this->exposedFormCache->getForm($view->storage->id(), $view->current_display)) {
       return $cache;
@@ -120,7 +120,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     // $form['#attributes']['class'] = array('views-exposed-form');
 
     /** @var \Drupal\views\Plugin\views\exposed_form\ExposedFormPluginBase $exposed_form_plugin */
-    $exposed_form_plugin = $form_state['exposed_form_plugin'];
+    $exposed_form_plugin = $form_state->get('exposed_form_plugin');
     $exposed_form_plugin->exposedFormAlter($form, $form_state);
 
     // Save the form.
@@ -135,13 +135,13 @@ public function buildForm(array $form, FormStateInterface $form_state) {
   public function validateForm(array &$form, FormStateInterface $form_state) {
     foreach (array('field', 'filter') as $type) {
       /** @var \Drupal\views\Plugin\views\ViewsHandlerInterface[] $handlers */
-      $handlers = &$form_state['view']->$type;
+      $handlers = &$form_state->get('view')->$type;
       foreach ($handlers as $key => $handler) {
         $handlers[$key]->validateExposed($form, $form_state);
       }
     }
     /** @var \Drupal\views\Plugin\views\exposed_form\ExposedFormPluginBase $exposed_form_plugin */
-    $exposed_form_plugin = $form_state['exposed_form_plugin'];
+    $exposed_form_plugin = $form_state->get('exposed_form_plugin');
     $exposed_form_plugin->exposedFormValidate($form, $form_state);
   }
 
@@ -151,22 +151,23 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
   public function submitForm(array &$form, FormStateInterface $form_state) {
     foreach (array('field', 'filter') as $type) {
       /** @var \Drupal\views\Plugin\views\ViewsHandlerInterface[] $handlers */
-      $handlers = &$form_state['view']->$type;
+      $handlers = &$form_state->get('view')->$type;
       foreach ($handlers as $key => $info) {
         $handlers[$key]->submitExposed($form, $form_state);
       }
     }
-    $form_state['view']->exposed_data = $form_state->getValues();
-    $form_state['view']->exposed_raw_input = array();
+    $view = $form_state->get('view');
+    $view->exposed_data = $form_state->getValues();
+    $view->exposed_raw_input = [];
 
     $exclude = array('submit', 'form_build_id', 'form_id', 'form_token', 'exposed_form_plugin', '', 'reset');
     /** @var \Drupal\views\Plugin\views\exposed_form\ExposedFormPluginBase $exposed_form_plugin */
-    $exposed_form_plugin = $form_state['exposed_form_plugin'];
+    $exposed_form_plugin = $form_state->get('exposed_form_plugin');
     $exposed_form_plugin->exposedFormSubmit($form, $form_state, $exclude);
 
     foreach ($form_state->getValues() as $key => $value) {
       if (!in_array($key, $exclude)) {
-        $form_state['view']->exposed_raw_input[$key] = $value;
+        $view->exposed_raw_input[$key] = $value;
       }
     }
   }
diff --git a/core/modules/views/src/Form/ViewsForm.php b/core/modules/views/src/Form/ViewsForm.php
index 2273f90..1884cd4 100644
--- a/core/modules/views/src/Form/ViewsForm.php
+++ b/core/modules/views/src/Form/ViewsForm.php
@@ -117,14 +117,17 @@ public function getFormID() {
    * {@inheritdoc}
    */
   public function buildForm(array $form, FormStateInterface $form_state, ViewExecutable $view = NULL, $output = NULL) {
-    $form_state['step'] = isset($form_state['step']) ? $form_state['step'] : 'views_form_views_form';
-    $form_state['step_controller']['views_form_views_form'] = 'Drupal\views\Form\ViewsFormMainForm';
+    if (!$step = $form_state->get('step')) {
+      $step = 'views_form_views_form';
+      $form_state->set('step', $step);
+    }
+    $form_state->set(['step_controller', 'views_form_views_form'], 'Drupal\views\Form\ViewsFormMainForm');
 
     // Cache the built form to prevent it from being rebuilt prior to validation
     // and submission, which could lead to data being processed incorrectly,
     // because the views rows (and thus, the form elements as well) have changed
     // in the meantime.
-    $form_state['cache'] = TRUE;
+    $form_state->setCached();
 
     $form = array();
 
@@ -135,7 +138,7 @@ public function buildForm(array $form, FormStateInterface $form_state, ViewExecu
     // Tell the preprocessor whether it should hide the header, footer, pager...
     $form['show_view_elements'] = array(
       '#type' => 'value',
-      '#value' => ($form_state['step'] == 'views_form_views_form') ? TRUE : FALSE,
+      '#value' => ($step == 'views_form_views_form') ? TRUE : FALSE,
     );
 
     $form_object = $this->getFormObject($form_state);
@@ -171,7 +174,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
    */
   protected function getFormObject(FormStateInterface $form_state) {
     // If this is a class, instantiate it.
-    $form_step_class = isset($form_state['step_controller'][$form_state['step']]) ? $form_state['step_controller'][$form_state['step']] : 'Drupal\views\Form\ViewsFormMainForm';
+    $form_step_class = $form_state->get(['step_controller', $form_state->get('step')]) ?: 'Drupal\views\Form\ViewsFormMainForm';
     return $this->classResolver->getInstanceFromDefinition($form_step_class);
   }
 
diff --git a/core/modules/views/src/Form/ViewsFormMainForm.php b/core/modules/views/src/Form/ViewsFormMainForm.php
index 6c48b7e..0d21e8e 100644
--- a/core/modules/views/src/Form/ViewsFormMainForm.php
+++ b/core/modules/views/src/Form/ViewsFormMainForm.php
@@ -108,7 +108,7 @@ public function buildForm(array $form, FormStateInterface $form_state, ViewExecu
    * {@inheritdoc}
    */
   public function validateForm(array &$form, FormStateInterface $form_state) {
-    $view = $form_state['build_info']['args'][0];
+    $view = $form_state->getBuildInfo()['args'][0];
 
     // Call the validation method on every field handler that has it.
     foreach ($view->field as $field) {
@@ -131,7 +131,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $view = $form_state['build_info']['args'][0];
+    $view = $form_state->getBuildInfo()['args'][0];
 
     // Call the submit method on every field handler that has it.
     foreach ($view->field as $field) {
diff --git a/core/modules/views/src/Plugin/views/HandlerBase.php b/core/modules/views/src/Plugin/views/HandlerBase.php
index 27d24d7..964ce9c 100644
--- a/core/modules/views/src/Plugin/views/HandlerBase.php
+++ b/core/modules/views/src/Plugin/views/HandlerBase.php
@@ -338,9 +338,9 @@ public function usesGroupBy() {
    * Provide a form for aggregation settings.
    */
   public function buildGroupByForm(&$form, FormStateInterface $form_state) {
-    $display_id = $form_state['display_id'];
-    $type = $form_state['type'];
-    $id = $form_state['id'];
+    $display_id = $form_state->get('display_id');
+    $type = $form_state->get('type');
+    $id = $form_state->get('id');
 
     $form['#section'] = $display_id . '-' . $type . '-' . $id;
 
@@ -364,7 +364,7 @@ public function buildGroupByForm(&$form, FormStateInterface $form_state) {
    * There is no need for this function to actually store the data.
    */
   public function submitGroupByForm(&$form, FormStateInterface $form_state) {
-    $form_state['handler']->options['group_type'] = $form_state->getValue(array('options', 'group_type'));
+    $form_state->get('handler')->options['group_type'] = $form_state->getValue(['options', 'group_type']);
   }
 
   /**
@@ -460,7 +460,7 @@ public function showExposeForm(&$form, FormStateInterface $form_state) {
     // have no data in POST so their defaults get wiped out. This prevents
     // these defaults from getting wiped out. This setting will only be TRUE
     // during a 2nd pass rerender.
-    if (!empty($form_state['force_expose_options'])) {
+    if ($form_state->get('force_expose_options')) {
       foreach (Element::children($form['expose']) as $id) {
         if (isset($form['expose'][$id]['#default_value']) && !isset($form['expose'][$id]['#value'])) {
           $form['expose'][$id]['#value'] = $form['expose'][$id]['#default_value'];
@@ -761,14 +761,18 @@ public function displayExposedForm($form, FormStateInterface $form_state) {
       $this->defaultExposeOptions();
     }
 
-    $form_state['view']->getExecutable()->setHandler($form_state['display_id'], $form_state['type'], $form_state['id'], $item);
+    $view = $form_state->get('view');
+    $display_id = $form_state->get('display_id');
+    $type = $form_state->get('type');
+    $id = $form_state->get('id');
+    $view->getExecutable()->setHandler($display_id, $type, $id, $item);
 
-    $form_state['view']->addFormToStack($form_state['form_key'], $form_state['display_id'], $form_state['type'], $form_state['id'], TRUE, TRUE);
+    $view->addFormToStack($form_state->get('form_key'), $display_id, $type, $id, TRUE, TRUE);
 
-    $form_state['view']->cacheSet();
-    $form_state['rerender'] = TRUE;
-    $form_state['rebuild'] = TRUE;
-    $form_state['force_expose_options'] = TRUE;
+    $view->cacheSet();
+    $form_state->set('rerender', TRUE);
+    $form_state->setRebuild();
+    $form_state->set('force_expose_options', TRUE);
   }
 
   /**
@@ -783,13 +787,14 @@ public function submitTemporaryForm($form, FormStateInterface $form_state) {
 
     // For footer/header $handler_type is area but $type is footer/header.
     // For all other handle types it's the same.
-    $handler_type = $type = $form_state['type'];
+    $handler_type = $type = $form_state->get('type');
     if (!empty($types[$type]['type'])) {
       $handler_type = $types[$type]['type'];
     }
 
     $override = NULL;
-    $executable = $form_state['view']->getExecutable();
+    $view = $form_state->get('view');
+    $executable = $view->getExecutable();
     if ($executable->display_handler->useGroupBy() && !empty($item['group_type'])) {
       if (empty($executable->query)) {
         $executable->initQuery();
@@ -814,19 +819,19 @@ public function submitTemporaryForm($form, FormStateInterface $form_state) {
     $handler->unpackOptions($handler->options, $options, NULL, FALSE);
 
     // Store the item back on the view.
-    $executable = $form_state['view']->getExecutable();
-    $executable->temporary_options[$type][$form_state['id']] = $handler->options;
+    $executable = $view->getExecutable();
+    $executable->temporary_options[$type][$form_state->get('id')] = $handler->options;
 
     // @todo Decide if \Drupal\views_ui\Form\Ajax\ViewsFormBase::getForm() is
     //   perhaps the better place to fix the issue.
     // \Drupal\views_ui\Form\Ajax\ViewsFormBase::getForm() drops the current
     // form from the stack, even if it's an #ajax. So add the item back to the top
     // of the stack.
-    $form_state['view']->addFormToStack($form_state['form_key'], $form_state['display_id'], $type, $item['id'], TRUE);
+    $view->addFormToStack($form_state->get('form_key'), $form_state->get('display_id'), $type, $item['id'], TRUE);
 
-    $form_state['rerender'] = TRUE;
-    $form_state['rebuild'] = TRUE;
+    $form_state->get('rerender', TRUE);
+    $form_state->setRebuild();
     // Write to cache
-    $form_state['view']->cacheSet();
+    $view->cacheSet();
   }
 }
diff --git a/core/modules/views/src/Plugin/views/area/AreaPluginBase.php b/core/modules/views/src/Plugin/views/area/AreaPluginBase.php
index 54a11bf..1269638 100644
--- a/core/modules/views/src/Plugin/views/area/AreaPluginBase.php
+++ b/core/modules/views/src/Plugin/views/area/AreaPluginBase.php
@@ -85,7 +85,7 @@ public function adminSummary() {
   public function buildOptionsForm(&$form, FormStateInterface $form_state) {
     parent::buildOptionsForm($form, $form_state);
 
-    if ($form_state['type'] != 'empty') {
+    if ($form_state->get('type') != 'empty') {
       $form['empty'] = array(
         '#type' => 'checkbox',
         '#title' => t('Display even if view has no result'),
diff --git a/core/modules/views/src/Plugin/views/display/Attachment.php b/core/modules/views/src/Plugin/views/display/Attachment.php
index 30870a0..663fb59 100644
--- a/core/modules/views/src/Plugin/views/display/Attachment.php
+++ b/core/modules/views/src/Plugin/views/display/Attachment.php
@@ -145,7 +145,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
     // It is very important to call the parent function here:
     parent::buildOptionsForm($form, $form_state);
 
-    switch ($form_state['section']) {
+    switch ($form_state->get('section')) {
       case 'inherit_arguments':
         $form['#title'] .= t('Inherit contextual filters');
         $form['inherit_arguments'] = array(
@@ -218,15 +218,16 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
   public function submitOptionsForm(&$form, FormStateInterface $form_state) {
     // It is very important to call the parent function here:
     parent::submitOptionsForm($form, $form_state);
-    switch ($form_state['section']) {
+    $section = $form_state->get('section');
+    switch ($section) {
       case 'displays':
-        $form_state->setValue($form_state['section'], array_filter($form_state->getValue($form_state['section'])));
+        $form_state->setValue($section, array_filter($form_state->getValue($section)));
       case 'inherit_arguments':
       case 'inherit_pager':
       case 'render_pager':
       case 'inherit_exposed_filters':
       case 'attachment_position':
-        $this->setOption($form_state['section'], $form_state->getValue($form_state['section']));
+        $this->setOption($section, $form_state->getValue($section));
         break;
     }
   }
diff --git a/core/modules/views/src/Plugin/views/display/Block.php b/core/modules/views/src/Plugin/views/display/Block.php
index c42a75e..544bd41 100644
--- a/core/modules/views/src/Plugin/views/display/Block.php
+++ b/core/modules/views/src/Plugin/views/display/Block.php
@@ -141,7 +141,7 @@ public function optionsSummary(&$categories, &$options) {
   public function buildOptionsForm(&$form, FormStateInterface $form_state) {
     parent::buildOptionsForm($form, $form_state);
 
-    switch ($form_state['section']) {
+    switch ($form_state->get('section')) {
       case 'block_description':
         $form['#title'] .= t('Block admin description');
         $form['block_description'] = array(
@@ -201,12 +201,13 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
    */
   public function submitOptionsForm(&$form, FormStateInterface $form_state) {
     parent::submitOptionsForm($form, $form_state);
-    switch ($form_state['section']) {
+    $section = $form_state->get('section');
+    switch ($section) {
       case 'block_description':
       case 'block_category':
       case 'allow':
       case 'block_hide_empty':
-        $this->setOption($form_state['section'], $form_state->getValue($form_state['section']));
+        $this->setOption($section, $form_state->getValue($section));
         break;
     }
   }
diff --git a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
index d7d5ea4..b7bc4de 100644
--- a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
+++ b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
@@ -1372,8 +1372,9 @@ public function optionsSummary(&$categories, &$options) {
    */
   public function buildOptionsForm(&$form, FormStateInterface $form_state) {
     parent::buildOptionsForm($form, $form_state);
-    if ($this->defaultableSections($form_state['section'])) {
-      views_ui_standard_display_dropdown($form, $form_state, $form_state['section']);
+    $section = $form_state->get('section');
+    if ($this->defaultableSections($section)) {
+      views_ui_standard_display_dropdown($form, $form_state, $section);
     }
     $form['#title'] = String::checkPlain($this->display['display_title']) . ': ';
 
@@ -1381,14 +1382,14 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
     // If it's the item we're looking at is pulling from the default display,
     // reflect that. Don't use is_defaulted since we want it to show up even
     // on the default display.
-    if (!empty($this->options['defaults'][$form_state['section']])) {
-      $form['#section'] = 'default-' . $form_state['section'];
+    if (!empty($this->options['defaults'][$section])) {
+      $form['#section'] = 'default-' . $section;
     }
     else {
-      $form['#section'] = $this->display['id'] . '-' . $form_state['section'];
+      $form['#section'] = $this->display['id'] . '-' . $section;
     }
 
-    switch ($form_state['section']) {
+    switch ($section) {
       case 'display_id':
         $form['#title'] .= t('The machine name of this display');
         $form['display_id'] = array(
@@ -1675,10 +1676,10 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
         }
         $plugin = $this->getPlugin(empty($style) ? 'row' : 'style', $name);
         if ($plugin) {
-          $form[$form_state['section']] = array(
+          $form[$section] = [
             '#tree' => TRUE,
-          );
-          $plugin->buildOptionsForm($form[$form_state['section']], $form_state);
+          ];
+          $plugin->buildOptionsForm($form[$section], $form_state);
         }
         break;
       case 'row':
@@ -1858,7 +1859,8 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
    * Validate the options form.
    */
   public function validateOptionsForm(&$form, FormStateInterface $form_state) {
-    switch ($form_state['section']) {
+    $section = $form_state->get('section');
+    switch ($section) {
       case 'display_title':
         if ($form_state->isValueEmpty('display_title')) {
           form_error($form['display_title'], $form_state, t('Display title may not be empty.'));
@@ -1892,11 +1894,11 @@ public function validateOptionsForm(&$form, FormStateInterface $form_state) {
 
     // Validate plugin options. Every section with "_options" in it, belongs to
     // a plugin type, like "style_options".
-    if (strpos($form_state['section'], '_options') !== FALSE) {
-      $plugin_type = str_replace('_options', '', $form_state['section']);
+    if (strpos($section, '_options') !== FALSE) {
+      $plugin_type = str_replace('_options', '', $section);
       // Load the plugin and let it handle the validation.
       if ($plugin = $this->getPlugin($plugin_type)) {
-        $plugin->validateOptionsForm($form[$form_state['section']], $form_state);
+        $plugin->validateOptionsForm($form[$section], $form_state);
       }
     }
 
@@ -1916,7 +1918,7 @@ public function submitOptionsForm(&$form, FormStateInterface $form_state) {
       $cache_plugin->cacheFlush();
     }
 
-    $section = $form_state['section'];
+    $section = $form_state->get('section');
     switch ($section) {
       case 'display_id':
         if ($form_state->hasValue('display_id')) {
@@ -1980,7 +1982,7 @@ public function submitOptionsForm(&$form, FormStateInterface $form_state) {
             );
             $this->setOption($plugin_type, $plugin_options);
             if ($plugin->usesOptions()) {
-              $form_state['view']->addFormToStack('display', $this->display['id'], $plugin_type . '_options');
+              $form_state->get('view')->addFormToStack('display', $this->display['id'], $plugin_type . '_options');
             }
           }
         }
@@ -1994,7 +1996,7 @@ public function submitOptionsForm(&$form, FormStateInterface $form_state) {
       case 'style_options':
         // Submit plugin options. Every section with "_options" in it, belongs to
         // a plugin type, like "style_options".
-        $plugin_type = str_replace('_options', '', $form_state['section']);
+        $plugin_type = str_replace('_options', '', $section);
         if ($plugin = $this->getPlugin($plugin_type)) {
           $plugin_options = $this->getOption($plugin_type);
           $plugin->submitOptionsForm($form[$plugin_type . '_options'], $form_state);
@@ -2013,7 +2015,7 @@ public function submitOptionsForm(&$form, FormStateInterface $form_state) {
    * If override/revert was clicked, perform the proper toggle.
    */
   public function optionsOverride($form, FormStateInterface $form_state) {
-    $this->setOverride($form_state['section']);
+    $this->setOverride($form_state->get('section'));
   }
 
   /**
diff --git a/core/modules/views/src/Plugin/views/display/Feed.php b/core/modules/views/src/Plugin/views/display/Feed.php
index bd84581..75e77c1 100644
--- a/core/modules/views/src/Plugin/views/display/Feed.php
+++ b/core/modules/views/src/Plugin/views/display/Feed.php
@@ -198,7 +198,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
     // It is very important to call the parent function here.
     parent::buildOptionsForm($form, $form_state);
 
-    switch ($form_state['section']) {
+    switch ($form_state->get('section')) {
       case 'title':
         $title = $form['title'];
         // A little juggling to move the 'title' field beyond our checkbox.
@@ -242,12 +242,13 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
    */
   public function submitOptionsForm(&$form, FormStateInterface $form_state) {
     parent::submitOptionsForm($form, $form_state);
-    switch ($form_state['section']) {
+    $section = $form_state->get('section');
+    switch ($section) {
       case 'title':
         $this->setOption('sitename_title', $form_state->getValue('sitename_title'));
         break;
       case 'displays':
-        $this->setOption($form_state['section'], $form_state->getValue($form_state['section']));
+        $this->setOption($section, $form_state->getValue($section));
         break;
     }
   }
diff --git a/core/modules/views/src/Plugin/views/display/Page.php b/core/modules/views/src/Plugin/views/display/Page.php
index 2b41335..8216654 100644
--- a/core/modules/views/src/Plugin/views/display/Page.php
+++ b/core/modules/views/src/Plugin/views/display/Page.php
@@ -153,7 +153,7 @@ public function optionsSummary(&$categories, &$options) {
   public function buildOptionsForm(&$form, FormStateInterface $form_state) {
     parent::buildOptionsForm($form, $form_state);
 
-    switch ($form_state['section']) {
+    switch ($form_state->get('section')) {
       case 'menu':
         $form['#title'] .= t('Menu item entry');
         $form['menu'] = array(
@@ -383,7 +383,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
   public function validateOptionsForm(&$form, FormStateInterface $form_state) {
     parent::validateOptionsForm($form, $form_state);
 
-    if ($form_state['section'] == 'menu') {
+    if ($form_state->get('section') == 'menu') {
       $path = $this->getOption('path');
       $menu_type = $form_state->getValue(array('menu', 'type'));
       if ($menu_type == 'normal' && strpos($path, '%') !== FALSE) {
@@ -410,14 +410,14 @@ public function validateOptionsForm(&$form, FormStateInterface $form_state) {
   public function submitOptionsForm(&$form, FormStateInterface $form_state) {
     parent::submitOptionsForm($form, $form_state);
 
-    switch ($form_state['section']) {
+    switch ($form_state->get('section')) {
       case 'menu':
         $menu = $form_state->getValue('menu');
         list($menu['menu_name'], $menu['parent']) = explode(':', $menu['parent'], 2);
         $this->setOption('menu', $menu);
         // send ajax form to options page if we use it.
         if ($form_state->getValue(array('menu', 'type')) == 'default tab') {
-          $form_state['view']->addFormToStack('display', $this->display['id'], 'tab_options');
+          $form_state->get('view')->addFormToStack('display', $this->display['id'], 'tab_options');
         }
         break;
       case 'tab_options':
diff --git a/core/modules/views/src/Plugin/views/display/PathPluginBase.php b/core/modules/views/src/Plugin/views/display/PathPluginBase.php
index 07a2816..4f6e220 100644
--- a/core/modules/views/src/Plugin/views/display/PathPluginBase.php
+++ b/core/modules/views/src/Plugin/views/display/PathPluginBase.php
@@ -380,7 +380,7 @@ public function optionsSummary(&$categories, &$options) {
   public function buildOptionsForm(&$form, FormStateInterface $form_state) {
     parent::buildOptionsForm($form, $form_state);
 
-    switch ($form_state['section']) {
+    switch ($form_state->get('section')) {
       case 'path':
         $form['#title'] .= t('The menu path or URL of this view');
         $form['path'] = array(
@@ -404,7 +404,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
   public function validateOptionsForm(&$form, FormStateInterface $form_state) {
     parent::validateOptionsForm($form, $form_state);
 
-    if ($form_state['section'] == 'path') {
+    if ($form_state->get('section') == 'path') {
       $errors = $this->validatePath($form_state->getValue('path'));
       foreach ($errors as $error) {
         $form_state->setError($form['path'], $error);
@@ -421,7 +421,7 @@ public function validateOptionsForm(&$form, FormStateInterface $form_state) {
   public function submitOptionsForm(&$form, FormStateInterface $form_state) {
     parent::submitOptionsForm($form, $form_state);
 
-    if ($form_state['section'] == 'path') {
+    if ($form_state->get('section') == 'path') {
       $this->setOption('path', $form_state->getValue('path'));
     }
   }
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 4f30943..4fc9a27 100644
--- a/core/modules/views/src/Plugin/views/exposed_form/ExposedFormPluginBase.php
+++ b/core/modules/views/src/Plugin/views/exposed_form/ExposedFormPluginBase.php
@@ -143,14 +143,14 @@ public function renderExposedForm($block = FALSE) {
     // filters of their parent displays instead of showing an additional
     // exposed filter form for the attachment as well as that for the parent.
     if (!$this->view->display_handler->displaysExposed() || (!$block && $this->view->display_handler->getOption('exposed_block'))) {
-      unset($form_state['rerender']);
+      $form_state->set('rerender', NULL);
     }
 
     if (!empty($this->ajax)) {
-      $form_state['ajax'] = TRUE;
+      $form_state->set('ajax', TRUE);
     }
 
-    $form_state['exposed_form_plugin'] = $this;
+    $form_state->set('exposed_form_plugin', $this);
     $form = \Drupal::formBuilder()->buildForm('\Drupal\views\Form\ViewsExposedForm', $form_state);
 
     if (!$this->view->display_handler->displaysExposed() || (!$block && $this->view->display_handler->getOption('exposed_block'))) {
@@ -275,13 +275,13 @@ public function exposedFormAlter(&$form, FormStateInterface $form_state) {
     $pager = $this->view->display_handler->getPlugin('pager');
     if ($pager) {
       $pager->exposedFormAlter($form, $form_state);
-      $form_state['pager_plugin'] = $pager;
+      $form_state->set('pager_plugin', $pager);
     }
   }
 
   public function exposedFormValidate(&$form, FormStateInterface $form_state) {
-    if (isset($form_state['pager_plugin'])) {
-      $form_state['pager_plugin']->exposedFormValidate($form, $form_state);
+    if ($pager_plugin = $form_state->get('pager_plugin')) {
+      $pager_plugin->exposedFormValidate($form, $form_state);
     }
   }
 
@@ -300,8 +300,8 @@ public function exposedFormSubmit(&$form, FormStateInterface $form_state, &$excl
     if (!$form_state->isValueEmpty('op') && $form_state->getValue('op') == $this->options['reset_button_label']) {
       $this->resetForm($form, $form_state);
     }
-    if (isset($form_state['pager_plugin'])) {
-      $form_state['pager_plugin']->exposedFormSubmit($form, $form_state, $exclude);
+    if ($pager_plugin = $form_state->get('pager_plugin')) {
+      $pager_plugin->exposedFormSubmit($form, $form_state, $exclude);
       $exclude[] = 'pager_plugin';
     }
   }
@@ -321,14 +321,12 @@ public function resetForm(&$form, FormStateInterface $form_state) {
 
     // Set the form to allow redirect.
     if (empty($this->view->live_preview)) {
-      $form_state['no_redirect'] = FALSE;
+      $form_state->disableRedirect(FALSE);
     }
     else {
-      $form_state['rebuild'] = TRUE;
+      $form_state->setRebuild();
       $this->view->exposed_data = array();
     }
-
-    $form_state['redirect'] = current_path();
   }
 
 }
diff --git a/core/modules/views/src/Plugin/views/filter/BooleanOperator.php b/core/modules/views/src/Plugin/views/filter/BooleanOperator.php
index 7a75a11..7a87faa 100644
--- a/core/modules/views/src/Plugin/views/filter/BooleanOperator.php
+++ b/core/modules/views/src/Plugin/views/filter/BooleanOperator.php
@@ -137,7 +137,7 @@ protected function valueForm(&$form, FormStateInterface $form_state) {
       // Initialize the array of possible values for this filter.
       $this->getValueOptions();
     }
-    if (!empty($form_state['exposed'])) {
+    if ($exposed = $form_state->get('exposed')) {
       // Exposed filter: use a select box to save space.
       $filter_form_type = 'select';
     }
@@ -154,12 +154,12 @@ protected function valueForm(&$form, FormStateInterface $form_state) {
     if (!empty($this->options['exposed'])) {
       $identifier = $this->options['expose']['identifier'];
       $user_input = $form_state->getUserInput();
-      if (!empty($form_state['exposed']) && !isset($user_input[$identifier])) {
+      if ($exposed && !isset($user_input[$identifier])) {
         $user_input[$identifier] = $this->value;
         $form_state->setUserInput($user_input);
       }
       // If we're configuring an exposed filter, add an - Any - option.
-      if (empty($form_state['exposed']) || empty($this->options['expose']['required'])) {
+      if (!$exposed || empty($this->options['expose']['required'])) {
         $form['value']['#options'] = array('All' => t('- Any -')) + $form['value']['#options'];
       }
     }
diff --git a/core/modules/views/src/Plugin/views/filter/Date.php b/core/modules/views/src/Plugin/views/filter/Date.php
index c0e1b9a..aca1508 100644
--- a/core/modules/views/src/Plugin/views/filter/Date.php
+++ b/core/modules/views/src/Plugin/views/filter/Date.php
@@ -31,7 +31,7 @@ protected function defineOptions() {
    * Add a type selector to the value form
    */
   protected function valueForm(&$form, FormStateInterface $form_state) {
-    if (empty($form_state['exposed'])) {
+    if (!$form_state->get('exposed')) {
       $form['value']['type'] = array(
         '#type' => 'radios',
         '#title' => t('Value type'),
diff --git a/core/modules/views/src/Plugin/views/filter/Equality.php b/core/modules/views/src/Plugin/views/filter/Equality.php
index 7e30335..9d25e0b 100644
--- a/core/modules/views/src/Plugin/views/filter/Equality.php
+++ b/core/modules/views/src/Plugin/views/filter/Equality.php
@@ -42,7 +42,7 @@ protected function valueForm(&$form, FormStateInterface $form_state) {
       '#default_value' => $this->value,
     );
 
-    if (!empty($form_state['exposed'])) {
+    if ($exposed = $form_state->get('exposed')) {
       $identifier = $this->options['expose']['identifier'];
       $user_input = $form_state->getUserInput();
       if (!isset($user_input[$identifier])) {
diff --git a/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php b/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php
index c7ff6bb..2df07ed 100644
--- a/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php
+++ b/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php
@@ -363,7 +363,7 @@ public function showBuildGroupForm(&$form, FormStateInterface $form_state) {
     // have no data in POST so their defaults get wiped out. This prevents
     // these defaults from getting wiped out. This setting will only be TRUE
     // during a 2nd pass rerender.
-    if (!empty($form_state['force_build_group_options'])) {
+    if ($form_state->get('force_build_group_options')) {
       foreach (Element::children($form['group_info']) as $id) {
         if (isset($form['group_info'][$id]['#default_value']) && !isset($form['group_info'][$id]['#value'])) {
           $form['group_info'][$id]['#value'] = $form['group_info'][$id]['#default_value'];
@@ -437,14 +437,18 @@ public function buildGroupForm($form, FormStateInterface $form_state) {
       $this->buildGroupOptions();
     }
 
-    $form_state['view']->getExecutable()->setHandler($form_state['display_id'], $form_state['type'], $form_state['id'], $item);
+    $view = $form_state->get('view');
+    $display_id = $form_state->get('display_id');
+    $type = $form_state->get('type');
+    $id = $form_state->get('id');
+    $view->getExecutable()->setHandler($display_id, $type, $id, $item);
 
-    $form_state['view']->addFormToStack($form_state['form_key'], $form_state['display_id'], $form_state['type'], $form_state['id'], TRUE, TRUE);
+    $view->addFormToStack($form_state->get('form_key'), $display_id, $type, $id, TRUE, TRUE);
 
-    $form_state['view']->cacheSet();
-    $form_state['rerender'] = TRUE;
-    $form_state['rebuild'] = TRUE;
-    $form_state['force_build_group_options'] = TRUE;
+    $view->cacheSet();
+    $form_state->set('rerender', TRUE);
+    $form_state->setRebuild();
+    $form_state->get('force_build_group_options', TRUE);
   }
 
   /**
@@ -622,7 +626,7 @@ public function validateExposeForm($form, FormStateInterface $form_state) {
       form_error($form['expose']['identifier'], $form_state, t('This identifier is not allowed.'));
     }
 
-    if (!$this->view->display_handler->isIdentifierUnique($form_state['id'], $identifier)) {
+    if (!$this->view->display_handler->isIdentifierUnique($form_state->get('id'), $identifier)) {
       form_error($form['expose']['identifier'], $form_state, t('This identifier is used by another handler.'));
     }
   }
@@ -641,7 +645,7 @@ protected function buildGroupValidate($form, FormStateInterface $form_state) {
         form_error($form['group_info']['identifier'], $form_state, t('This identifier is not allowed.'));
       }
 
-      if (!$this->view->display_handler->isIdentifierUnique($form_state['id'], $identifier)) {
+      if (!$this->view->display_handler->isIdentifierUnique($form_state->get('id'), $identifier)) {
         form_error($form['group_info']['identifier'], $form_state, t('This identifier is used by another handler.'));
       }
     }
@@ -1090,12 +1094,14 @@ protected function buildExposedFiltersGroupForm(&$form, FormStateInterface $form
       'hidden' => TRUE,
       'limit' => 0,
     );
-    if (!empty($form_state['js settings']) && is_array($js)) {
-      $form_state['js settings'] = array_merge($form_state['js settings'], $js);
+    $js_settings = $form_state->get('js settings');
+    if ($js_settings && is_array($js)) {
+      $js_settings = array_merge($js_settings, $js);
     }
     else {
-      $form_state['js settings'] = $js;
+      $js_settings = $js;
     }
+    $form_state->set('js settings', $js_settings);
   }
 
   /**
@@ -1107,12 +1113,16 @@ public function addGroupForm($form, FormStateInterface $form_state) {
     // Add a new row.
     $item['group_info']['group_items'][] = array();
 
-    $form_state['view']->getExecutable()->setHandler($form_state['display_id'], $form_state['type'], $form_state['id'], $item);
+    $view = $form_state->get('view');
+    $display_id = $form_state->get('display_id');
+    $type = $form_state->get('type');
+    $id = $form_state->get('id');
+    $view->getExecutable()->setHandler($display_id, $type, $id, $item);
 
-    $form_state['view']->cacheSet();
-    $form_state['rerender'] = TRUE;
-    $form_state['rebuild'] = TRUE;
-    $form_state['force_build_group_options'] = TRUE;
+    $view->cacheSet();
+    $form_state->set('rerender', TRUE);
+    $form_state->setRebuild();
+    $form_state->get('force_build_group_options', TRUE);
   }
 
 
diff --git a/core/modules/views/src/Plugin/views/filter/InOperator.php b/core/modules/views/src/Plugin/views/filter/InOperator.php
index 623b44f..4d442b8 100644
--- a/core/modules/views/src/Plugin/views/filter/InOperator.php
+++ b/core/modules/views/src/Plugin/views/filter/InOperator.php
@@ -170,7 +170,8 @@ protected function valueForm(&$form, FormStateInterface $form_state) {
     $form['value'] = array();
     $options = array();
 
-    if (empty($form_state['exposed'])) {
+    $exposed = $form_state->get('exposed');
+    if (!$exposed) {
       // Add a select all option to the value form.
       $options = array('all' => t('Select all'));
     }
@@ -183,7 +184,7 @@ protected function valueForm(&$form, FormStateInterface $form_state) {
     if (!empty($form['operator'])) {
       $source = ':input[name="options[operator]"]';
     }
-    if (!empty($form_state['exposed'])) {
+    if ($exposed) {
       $identifier = $this->options['expose']['identifier'];
 
       if (empty($this->options['expose']['use_operator']) || empty($this->options['expose']['operator_id'])) {
@@ -228,13 +229,13 @@ protected function valueForm(&$form, FormStateInterface $form_state) {
         '#size' => count($options) > 8 ? 8 : count($options),
       );
       $user_input = $form_state->getUserInput();
-      if (!empty($form_state['exposed']) && !isset($user_input[$identifier])) {
+      if ($exposed && !isset($user_input[$identifier])) {
         $user_input[$identifier] = $default_value;
         $form_state->setUserInput($user_input);
       }
 
       if ($which == 'all') {
-        if (empty($form_state['exposed']) && (in_array($this->valueFormType, array('checkbox', 'checkboxes', 'radios', 'select')))) {
+        if (!$exposed && (in_array($this->valueFormType, ['checkbox', 'checkboxes', 'radios', 'select']))) {
           $form['value']['#prefix'] = '<div id="edit-options-value-wrapper">';
           $form['value']['#suffix'] = '</div>';
         }
diff --git a/core/modules/views/src/Plugin/views/filter/ManyToOne.php b/core/modules/views/src/Plugin/views/filter/ManyToOne.php
index cc8b448..7f1ca40 100644
--- a/core/modules/views/src/Plugin/views/filter/ManyToOne.php
+++ b/core/modules/views/src/Plugin/views/filter/ManyToOne.php
@@ -111,7 +111,7 @@ function operators() {
   protected function valueForm(&$form, FormStateInterface $form_state) {
     parent::valueForm($form, $form_state);
 
-    if (empty($form_state['exposed'])) {
+    if ($form_state->get('exposed')) {
       $this->helper->buildOptionsForm($form, $form_state);
     }
   }
diff --git a/core/modules/views/src/Plugin/views/filter/Numeric.php b/core/modules/views/src/Plugin/views/filter/Numeric.php
index 9837998..5579158 100644
--- a/core/modules/views/src/Plugin/views/filter/Numeric.php
+++ b/core/modules/views/src/Plugin/views/filter/Numeric.php
@@ -152,7 +152,7 @@ protected function valueForm(&$form, FormStateInterface $form_state) {
       $source = ':input[name="options[operator]"]';
     }
 
-    if (!empty($form_state['exposed'])) {
+    if ($exposed = $form_state->get('exposed')) {
       $identifier = $this->options['expose']['identifier'];
 
       if (empty($this->options['expose']['use_operator']) || empty($this->options['expose']['operator_id'])) {
@@ -168,7 +168,7 @@ protected function valueForm(&$form, FormStateInterface $form_state) {
     if ($which == 'all') {
       $form['value']['value'] = array(
         '#type' => 'textfield',
-        '#title' => empty($form_state['exposed']) ? t('Value') : '',
+        '#title' => !$exposed ? t('Value') : '',
         '#size' => 30,
         '#default_value' => $this->value['value'],
       );
@@ -178,7 +178,7 @@ protected function valueForm(&$form, FormStateInterface $form_state) {
           $source => array('value' => $operator),
         );
       }
-      if (!empty($form_state['exposed']) && !isset($user_input[$identifier]['value'])) {
+      if ($exposed && !isset($user_input[$identifier]['value'])) {
         $user_input[$identifier]['value'] = $this->value['value'];
         $form_state->setUserInput($user_input);
       }
@@ -188,11 +188,11 @@ protected function valueForm(&$form, FormStateInterface $form_state) {
       // the operator is locked.
       $form['value'] = array(
         '#type' => 'textfield',
-        '#title' => empty($form_state['exposed']) ? t('Value') : '',
+        '#title' => !$exposed ? t('Value') : '',
         '#size' => 30,
         '#default_value' => $this->value['value'],
       );
-      if (!empty($form_state['exposed']) && !isset($user_input[$identifier])) {
+      if ($exposed && !isset($user_input[$identifier])) {
         $user_input[$identifier] = $this->value['value'];
         $form_state->setUserInput($user_input);
       }
@@ -201,13 +201,13 @@ protected function valueForm(&$form, FormStateInterface $form_state) {
     if ($which == 'all' || $which == 'minmax') {
       $form['value']['min'] = array(
         '#type' => 'textfield',
-        '#title' => empty($form_state['exposed']) ? t('Min') : '',
+        '#title' => !$exposed ? t('Min') : '',
         '#size' => 30,
         '#default_value' => $this->value['min'],
       );
       $form['value']['max'] = array(
         '#type' => 'textfield',
-        '#title' => empty($form_state['exposed']) ? t('And max') : t('And'),
+        '#title' => !$exposed ? t('And max') : t('And'),
         '#size' => 30,
         '#default_value' => $this->value['max'],
       );
@@ -222,10 +222,10 @@ protected function valueForm(&$form, FormStateInterface $form_state) {
         $form['value']['min'] += $states;
         $form['value']['max'] += $states;
       }
-      if (!empty($form_state['exposed']) && !isset($user_input[$identifier]['min'])) {
+      if ($exposed && !isset($user_input[$identifier]['min'])) {
         $user_input[$identifier]['min'] = $this->value['min'];
       }
-      if (!empty($form_state['exposed']) && !isset($user_input[$identifier]['max'])) {
+      if ($exposed && !isset($user_input[$identifier]['max'])) {
         $user_input[$identifier]['max'] = $this->value['max'];
       }
 
diff --git a/core/modules/views/src/Plugin/views/filter/String.php b/core/modules/views/src/Plugin/views/filter/String.php
index 952d58d..a93c907 100644
--- a/core/modules/views/src/Plugin/views/filter/String.php
+++ b/core/modules/views/src/Plugin/views/filter/String.php
@@ -193,7 +193,7 @@ protected function valueForm(&$form, FormStateInterface $form_state) {
     if (!empty($form['operator'])) {
       $source = ':input[name="options[operator]"]';
     }
-    if (!empty($form_state['exposed'])) {
+    if ($exposed = $form_state->get('exposed')) {
       $identifier = $this->options['expose']['identifier'];
 
       if (empty($this->options['expose']['use_operator']) || empty($this->options['expose']['operator_id'])) {
@@ -213,7 +213,7 @@ protected function valueForm(&$form, FormStateInterface $form_state) {
         '#default_value' => $this->value,
       );
       $user_input = $form_state->getUserInput();
-      if (!empty($form_state['exposed']) && !isset($user_input[$identifier])) {
+      if ($exposed && !isset($user_input[$identifier])) {
         $user_input[$identifier] = $this->value;
         $form_state->setUserInput($user_input);
       }
diff --git a/core/modules/views/src/Plugin/views/row/RowPluginBase.php b/core/modules/views/src/Plugin/views/row/RowPluginBase.php
index 905f04e..459a768 100644
--- a/core/modules/views/src/Plugin/views/row/RowPluginBase.php
+++ b/core/modules/views/src/Plugin/views/row/RowPluginBase.php
@@ -82,7 +82,7 @@ protected function defineOptions() {
   public function buildOptionsForm(&$form, FormStateInterface $form_state) {
     parent::buildOptionsForm($form, $form_state);
     if (isset($this->base_table)) {
-      $executable = $form_state['view']->getExecutable();
+      $executable = $form_state->get('view')->getExecutable();
 
       // A whole bunch of code to figure out what relationships are valid for
       // this item.
diff --git a/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php b/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php
index bb63902..a989be7 100644
--- a/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php
+++ b/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php
@@ -741,7 +741,7 @@ protected function buildDisplayOptions($form, FormStateInterface $form_state) {
     }
 
     // Display: REST export.
-    if (!empty($form_state['values']['rest_export']['create'])) {
+    if (!$form_state->isValueEmpty(['rest_export', 'create'])) {
       $display_options['rest_export'] = $this->restExportDisplayOptions($form, $form_state);
     }
 
@@ -1117,7 +1117,7 @@ protected function blockDisplayOptions(array $form, FormStateInterface $form_sta
    */
   protected function restExportDisplayOptions(array $form, FormStateInterface $form_state) {
     $display_options = array();
-    $display_options['path'] = $form_state['values']['rest_export']['path'];
+    $display_options['path'] = $form_state->getValue(['rest_export', 'path']);
     $display_options['style'] = array('type' => 'serializer');
 
     return $display_options;
diff --git a/core/modules/views/src/Tests/Handler/AreaEntityTest.php b/core/modules/views/src/Tests/Handler/AreaEntityTest.php
index 9082352..af44b44 100644
--- a/core/modules/views/src/Tests/Handler/AreaEntityTest.php
+++ b/core/modules/views/src/Tests/Handler/AreaEntityTest.php
@@ -122,8 +122,8 @@ public function testEntityArea() {
 
     // Test the available view mode options.
     $form = array();
-    $form_state = new FormState();
-    $form_state['type'] = 'header';
+    $form_state = (new FormState())
+      ->set('type', 'header');
     $view->display_handler->getHandler('header', 'entity_entity_test')->buildOptionsForm($form, $form_state);
     $this->assertTrue(isset($form['view_mode']['#options']['test']), 'Ensure that the test view mode is available.');
     $this->assertTrue(isset($form['view_mode']['#options']['default']), 'Ensure that the default view mode is available.');
diff --git a/core/modules/views/src/Tests/Plugin/RowEntityTest.php b/core/modules/views/src/Tests/Plugin/RowEntityTest.php
index 649ba5f..3024b77 100644
--- a/core/modules/views/src/Tests/Plugin/RowEntityTest.php
+++ b/core/modules/views/src/Tests/Plugin/RowEntityTest.php
@@ -62,7 +62,7 @@ public function testEntityRow() {
     // Tests the available view mode options.
     $form = array();
     $form_state = new FormState();
-    $form_state['view'] = $view->storage;
+    $form_state->set('view', $view->storage);
     $view->rowPlugin->buildOptionsForm($form, $form_state);
 
     $this->assertTrue(isset($form['view_mode']['#options']['default']), 'Ensure that the default view mode is available');
diff --git a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/display/DisplayTest.php b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/display/DisplayTest.php
index b14d409..b995858 100644
--- a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/display/DisplayTest.php
+++ b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/display/DisplayTest.php
@@ -78,7 +78,7 @@ public function optionsSummary(&$categories, &$options) {
   public function buildOptionsForm(&$form, FormStateInterface $form_state) {
     parent::buildOptionsForm($form, $form_state);
 
-    switch ($form_state['section']) {
+    switch ($form_state->get('section')) {
       case 'test_option':
         $form['#title'] .= t('Test option');
         $form['test_option'] = array(
@@ -97,7 +97,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
   public function validateOptionsForm(&$form, FormStateInterface $form_state) {
     parent::validateOptionsForm($form, $form_state);
     \Drupal::logger('views')->notice($form_state->getValue('test_option'));
-    switch ($form_state['section']) {
+    switch ($form_state->get('section')) {
       case 'test_option':
         if (!trim($form_state->getValue('test_option'))) {
           form_error($form['test_option'], $form_state, t('You cannot have an empty option.'));
@@ -111,7 +111,7 @@ public function validateOptionsForm(&$form, FormStateInterface $form_state) {
    */
   public function submitOptionsForm(&$form, FormStateInterface $form_state) {
     parent::submitOptionsForm($form, $form_state);
-    switch ($form_state['section']) {
+    switch ($form_state->get('section')) {
       case 'test_option':
         $this->setOption('test_option', $form_state->getValue('test_option'));
         break;
diff --git a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/display_extender/DisplayExtenderTest.php b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/display_extender/DisplayExtenderTest.php
index 8c0061d..bb35b9e 100644
--- a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/display_extender/DisplayExtenderTest.php
+++ b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/display_extender/DisplayExtenderTest.php
@@ -63,7 +63,7 @@ public function optionsSummary(&$categories, &$options) {
    * Overrides Drupal\views\Plugin\views\display_extender\DisplayExtenderPluginBase::buildOptionsForm().
    */
   public function buildOptionsForm(&$form, FormStateInterface $form_state) {
-    switch ($form_state['section']) {
+    switch ($form_state->get('section')) {
       case 'test_extender_test_option':
         $form['#title'] .= t('Test option');
         $form['test_extender_test_option'] = array(
@@ -80,7 +80,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
    */
   public function submitOptionsForm(&$form, FormStateInterface $form_state) {
     parent::submitOptionsForm($form, $form_state);
-    switch ($form_state['section']) {
+    switch ($form_state->get('section')) {
       case 'test_extender_test_option':
         $this->displayHandler->setOption('test_extender_test_option', $form_state->getValue('test_extender_test_option'));
         break;
diff --git a/core/modules/views_ui/admin.inc b/core/modules/views_ui/admin.inc
index 3136f64..b8b758d 100644
--- a/core/modules/views_ui/admin.inc
+++ b/core/modules/views_ui/admin.inc
@@ -138,15 +138,13 @@ function views_ui_add_limited_validation($element, FormStateInterface $form_stat
 
   // If we are in the process of a form submission and this is the button that
   // was clicked, the form API workflow in form_builder() will have already
-  // copied it to $form_state['triggering_element'] before our #process
+  // copied it to $form_state->getTriggeringElement() before our #process
   // function is run. So we need to make the same modifications in $form_state
   // as we did to the element itself, to ensure that #limit_validation_errors
   // will actually be set in the correct place.
-  if (!empty($form_state['triggering_element'])) {
-    $clicked_button = &$form_state['triggering_element'];
-    if ($clicked_button['#name'] == $element['#name'] && $clicked_button['#value'] == $element['#value']) {
-      $clicked_button['#limit_validation_errors'] = $element['#limit_validation_errors'];
-    }
+  $clicked_button = &$form_state->getTriggeringElement();
+  if ($clicked_button && $clicked_button['#name'] == $element['#name'] && $clicked_button['#value'] == $element['#value']) {
+    $clicked_button['#limit_validation_errors'] = $element['#limit_validation_errors'];
   }
 
   return $element;
@@ -197,14 +195,14 @@ function views_ui_ajax_update_form($form, FormStateInterface $form_state) {
   // The region that needs to be updated was stored in a property of the
   // triggering element by views_ui_add_ajax_trigger(), so all we have to do is
   // retrieve that here.
-  return NestedArray::getValue($form, $form_state['triggering_element']['#views_ui_ajax_data']['refresh_parents']);
+  return NestedArray::getValue($form, $form_state->getTriggeringElement()['#views_ui_ajax_data']['refresh_parents']);
 }
 
 /**
  * Non-Javascript fallback for updating the add view form.
  */
 function views_ui_nojs_submit($form, FormStateInterface $form_state) {
-  $form_state['rebuild'] = TRUE;
+  $form_state->setRebuild();
 }
 
 /**
@@ -263,8 +261,8 @@ function views_ui_taxonomy_autocomplete_validate($element, FormStateInterface $f
  * the current display.
  */
 function views_ui_standard_display_dropdown(&$form, FormStateInterface $form_state, $section) {
-  $view = $form_state['view'];
-  $display_id = $form_state['display_id'];
+  $view = $form_state->get('view');
+  $display_id = $form_state->get('display_id');
   $executable = $view->getExecutable();
   $displays = $executable->displayHandlers;
   $current_display = $executable->display_handler;
@@ -326,16 +324,16 @@ function views_ui_standard_display_dropdown(&$form, FormStateInterface $form_sta
  * information about the form.
  */
 function views_ui_build_form_path(FormStateInterface $form_state) {
-  $ajax = empty($form_state['ajax']) ? 'nojs' : 'ajax';
-  $name = $form_state['view']->id();
+  $ajax = !$form_state->get('ajax') ? 'nojs' : 'ajax';
+  $name = $form_state->get('view')->id();
   $form_key = $form_state->get('form_key');
   $display_id = $form_state->get('display_id');
   $path = "admin/structure/views/$ajax/$form_key/$name/$display_id";
-  if (isset($form_state['type'])) {
-    $path .= '/' . $form_state['type'];
+  if ($type = $form_state->get('type')) {
+    $path .= '/' . $type;
   }
-  if (isset($form_state['id'])) {
-    $path .= '/' . $form_state['id'];
+  if ($id = $form_state->get('id')) {
+    $path .= '/' . $id;
   }
   return $path;
 }
@@ -357,9 +355,9 @@ function views_ui_build_form_path(FormStateInterface $form_state) {
  */
 function views_ui_form_button_was_clicked($element, FormStateInterface $form_state) {
   $user_input = $form_state->getUserInput();
-  $process_input = empty($element['#disabled']) && ($form_state['programmed'] || ($form_state['process_input'] && (!isset($element['#access']) || $element['#access'])));
-  if ($process_input && !isset($form_state['triggering_element']) && !empty($element['#is_button']) && isset($user_input[$element['#name']]) && isset($element['#values']) && in_array($user_input[$element['#name']], $element['#values'], TRUE)) {
-    $form_state['triggering_element'] = $element;
+  $process_input = empty($element['#disabled']) && ($form_state->isProgrammed() || ($form_state->isProcessingInput() && (!isset($element['#access']) || $element['#access'])));
+  if ($process_input && !$form_state->getTriggeringElement() && !empty($element['#is_button']) && isset($user_input[$element['#name']]) && isset($element['#values']) && in_array($user_input[$element['#name']], $element['#values'], TRUE)) {
+    $form_state->setTriggeringElement($element);
   }
   return $element;
 }
diff --git a/core/modules/views_ui/src/Form/Ajax/AddHandler.php b/core/modules/views_ui/src/Form/Ajax/AddHandler.php
index 4b69e93..afcfa43 100644
--- a/core/modules/views_ui/src/Form/Ajax/AddHandler.php
+++ b/core/modules/views_ui/src/Form/Ajax/AddHandler.php
@@ -50,9 +50,9 @@ public function getFormId() {
    * {@inheritdoc}
    */
   public function buildForm(array $form, FormStateInterface $form_state) {
-    $view = $form_state['view'];
-    $display_id = $form_state['display_id'];
-    $type = $form_state['type'];
+    $view = $form_state->get('view');
+    $display_id = $form_state->get('display_id');
+    $type = $form_state->get('type');
 
     $form = array(
       'options' => array(
@@ -81,7 +81,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
 
     // Figure out all the base tables allowed based upon what the relationships provide.
     $base_tables = $executable->getBaseTables();
-    $options = Views::viewsDataHelper()->fetchFields(array_keys($base_tables), $type, $display->useGroupBy(), $form_state['type']);
+    $options = Views::viewsDataHelper()->fetchFields(array_keys($base_tables), $type, $display->useGroupBy(), $form_state->get('type'));
 
     if (!empty($options)) {
       $form['override']['controls'] = array(
diff --git a/core/modules/views_ui/src/Form/Ajax/Analyze.php b/core/modules/views_ui/src/Form/Ajax/Analyze.php
index 1e0380d..95e126a 100644
--- a/core/modules/views_ui/src/Form/Ajax/Analyze.php
+++ b/core/modules/views_ui/src/Form/Ajax/Analyze.php
@@ -35,7 +35,7 @@ public function getFormId() {
    * {@inheritdoc}
    */
   public function buildForm(array $form, FormStateInterface $form_state) {
-    $view = $form_state['view'];
+    $view = $form_state->get('view');
 
     $form['#title'] = $this->t('View analysis');
     $form['#section'] = 'analyze';
@@ -50,7 +50,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     );
 
     // Inform the standard button function that we want an OK button.
-    $form_state['ok_button'] = TRUE;
+    $form_state->set('ok_button', TRUE);
     $view->getStandardButtons($form, $form_state, 'views_ui_analyze_view_form');
     return $form;
   }
@@ -60,7 +60,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'];
+    $view = $form_state->get('view');
     $form_state->setRedirectUrl($view->urlInfo('edit-form'));
   }
 
diff --git a/core/modules/views_ui/src/Form/Ajax/ConfigHandler.php b/core/modules/views_ui/src/Form/Ajax/ConfigHandler.php
index 02fb02f..90de6d9 100644
--- a/core/modules/views_ui/src/Form/Ajax/ConfigHandler.php
+++ b/core/modules/views_ui/src/Form/Ajax/ConfigHandler.php
@@ -52,10 +52,10 @@ public function getFormId() {
    * {@inheritdoc}
    */
   public function buildForm(array $form, FormStateInterface $form_state) {
-    $view = $form_state['view'];
-    $display_id = $form_state['display_id'];
-    $type = $form_state['type'];
-    $id = $form_state['id'];
+    $view = $form_state->get('view');
+    $display_id = $form_state->get('display_id');
+    $type = $form_state->get('type');
+    $id = $form_state->get('id');
 
     $form = array(
       'options' => array(
@@ -80,8 +80,9 @@ public function buildForm(array $form, FormStateInterface $form_state) {
         // If this item can come from the default display, show a dropdown
         // that lets the user choose which display the changes should apply to.
         if ($executable->display_handler->defaultableSections($types[$type]['plural'])) {
-          $form_state['section'] = $types[$type]['plural'];
-          views_ui_standard_display_dropdown($form, $form_state, $form_state['section']);
+          $section = $types[$type]['plural'];
+          $form_state->set('section', $section);
+          views_ui_standard_display_dropdown($form, $form_state, $section);
         }
 
         // A whole bunch of code to figure out what relationships are valid for
@@ -104,7 +105,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
           // If this relationship is valid for this type, add it to the list.
           $data = Views::viewsData()->get($relationship['table']);
           if (isset($data[$relationship['field']]['relationship']['base']) && $base = $data[$relationship['field']]['relationship']['base']) {
-            $base_fields = Views::viewsDataHelper()->fetchFields($base, $form_state['type'], $executable->display_handler->useGroupBy());
+            $base_fields = Views::viewsDataHelper()->fetchFields($base, $type, $executable->display_handler->useGroupBy());
             if (isset($base_fields[$item['table'] . '.' . $item['field']])) {
               $relationship_handler->init($executable, $executable->display_handler, $relationship);
               $relationship_options[$relationship['id']] = $relationship_handler->adminLabel();
@@ -115,7 +116,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
         if (!empty($relationship_options)) {
           // Make sure the existing relationship is even valid. If not, force
           // it to none.
-          $base_fields = Views::viewsDataHelper()->fetchFields($view->get('base_table'), $form_state['type'], $executable->display_handler->useGroupBy());
+          $base_fields = Views::viewsDataHelper()->fetchFields($view->get('base_table'), $type, $executable->display_handler->useGroupBy());
           if (isset($base_fields[$item['table'] . '.' . $item['field']])) {
             $relationship_options = array_merge(array('none' => $this->t('Do not use a relationship')), $relationship_options);
           }
@@ -159,13 +160,10 @@ public function buildForm(array $form, FormStateInterface $form_state) {
 
         // Get form from the handler.
         $handler->buildOptionsForm($form['options'], $form_state);
-        $form_state['handler'] = $handler;
+        $form_state->set('handler', $handler);
       }
 
-      $name = NULL;
-      if (isset($form_state['update_name'])) {
-        $name = $form_state['update_name'];
-      }
+      $name = $form_state->get('update_name');
 
       $view->getStandardButtons($form, $form_state, 'views_ui_config_item_form', $name);
       // Add a 'remove' button.
@@ -191,10 +189,10 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function validateForm(array &$form, FormStateInterface $form_state) {
-    $form_state['handler']->validateOptionsForm($form['options'], $form_state);
+    $form_state->get('handler')->validateOptionsForm($form['options'], $form_state);
 
     if ($form_state->getErrors()) {
-      $form_state['rerender'] = TRUE;
+      $form_state->set('rerender', TRUE);
     }
   }
 
@@ -202,20 +200,25 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
+    $view = $form_state->get('view');
+    $display_id = $form_state->get('display_id');
+    $id = $form_state->get('id');
+    $handler = $form_state->get('handler');
+
     // Run it through the handler's submit function.
-    $form_state['handler']->submitOptionsForm($form['options'], $form_state);
-    $item = $form_state['handler']->options;
+    $handler->submitOptionsForm($form['options'], $form_state);
+    $item = $handler->options;
     $types = ViewExecutable::getHandlerTypes();
 
     // For footer/header $handler_type is area but $type is footer/header.
     // For all other handle types it's the same.
-    $handler_type = $type = $form_state['type'];
+    $handler_type = $type = $form_state->get('type');
     if (!empty($types[$type]['type'])) {
       $handler_type = $types[$type]['type'];
     }
 
     $override = NULL;
-    $executable = $form_state['view']->getExecutable();
+    $executable = $view->getExecutable();
     if ($executable->display_handler->useGroupBy() && !empty($item['group_type'])) {
       if (empty($executable->query)) {
         $executable->initQuery();
@@ -233,7 +236,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
 
     // Add the incoming options to existing options because items using
     // the extra form may not have everything in the form here.
-    $options = $form_state->getValue('options') + $form_state['handler']->options;
+    $options = $form_state->getValue('options') + $handler->options;
 
     // This unpacks only options that are in the definition, ensuring random
     // extra stuff on the form is not sent through.
@@ -248,33 +251,37 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $handler->options['dependencies']['module'][] = $handler->definition['provider'];
 
     // Store the item back on the view
-    $executable->setHandler($form_state['display_id'], $form_state['type'], $form_state['id'], $handler->options);
+    $executable->setHandler($display_id, $type, $id, $handler->options);
 
     // Ensure any temporary options are removed.
-    if (isset($form_state['view']->temporary_options[$type][$form_state['id']])) {
-      unset($form_state['view']->temporary_options[$type][$form_state['id']]);
+    if (isset($view->temporary_options[$type][$id])) {
+      unset($view->temporary_options[$type][$id]);
     }
 
     // Write to cache
-    $form_state['view']->cacheSet();
+    $view->cacheSet();
   }
 
   /**
    * Submit handler for removing an item from a view
    */
   public function remove(&$form, FormStateInterface $form_state) {
+    $view = $form_state->get('view');
+    $display_id = $form_state->get('display_id');
+    $type = $form_state->get('type');
+    $id = $form_state->get('id');
     // Store the item back on the view
-    list($was_defaulted, $is_defaulted) = $form_state['view']->getOverrideValues($form, $form_state);
-    $executable = $form_state['view']->getExecutable();
+    list($was_defaulted, $is_defaulted) = $view->getOverrideValues($form, $form_state);
+    $executable = $view->getExecutable();
     // If the display selection was changed toggle the override value.
     if ($was_defaulted != $is_defaulted) {
-      $display = &$executable->displayHandlers->get($form_state['display_id']);
+      $display = &$executable->displayHandlers->get($display_id);
       $display->optionsOverride($form, $form_state);
     }
-    $executable->removeHandler($form_state['display_id'], $form_state['type'], $form_state['id']);
+    $executable->removeHandler($display_id, $type, $id);
 
     // Write to cache
-    $form_state['view']->cacheSet();
+    $view->cacheSet();
   }
 
 }
diff --git a/core/modules/views_ui/src/Form/Ajax/ConfigHandlerExtra.php b/core/modules/views_ui/src/Form/Ajax/ConfigHandlerExtra.php
index 17b5011..3cdaece 100644
--- a/core/modules/views_ui/src/Form/Ajax/ConfigHandlerExtra.php
+++ b/core/modules/views_ui/src/Form/Ajax/ConfigHandlerExtra.php
@@ -51,10 +51,10 @@ public function getFormId() {
    * {@inheritdoc}
    */
   public function buildForm(array $form, FormStateInterface $form_state) {
-    $view = $form_state['view'];
-    $display_id = $form_state['display_id'];
-    $type = $form_state['type'];
-    $id = $form_state['id'];
+    $view = $form_state->get('view');
+    $display_id = $form_state->get('display_id');
+    $type = $form_state->get('type');
+    $id = $form_state->get('id');
 
     $form = array(
       'options' => array(
@@ -82,7 +82,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
 
         // Get form from the handler.
         $handler->buildExtraOptionsForm($form['options'], $form_state);
-        $form_state['handler'] = $handler;
+        $form_state->set('handler', $handler);
       }
 
       $view->getStandardButtons($form, $form_state, 'views_ui_config_item_extra_form');
@@ -94,16 +94,18 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function validateForm(array &$form, FormStateInterface $form_state) {
-    $form_state['handler']->validateExtraOptionsForm($form['options'], $form_state);
+    $form_state->get('handler')->validateExtraOptionsForm($form['options'], $form_state);
   }
 
   /**
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
+    $view = $form_state->get('view');
+    $handler = $form_state->get('handler');
     // Run it through the handler's submit function.
-    $form_state['handler']->submitExtraOptionsForm($form['options'], $form_state);
-    $item = $form_state['handler']->options;
+    $handler->submitExtraOptionsForm($form['options'], $form_state);
+    $item = $handler->options;
 
     // Store the data we're given.
     foreach ($form_state->getValue('options') as $key => $value) {
@@ -111,10 +113,10 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     }
 
     // Store the item back on the view
-    $form_state['view']->getExecutable()->setHandler($form_state['display_id'], $form_state['type'], $form_state['id'], $item);
+    $view->getExecutable()->setHandler($form_state->get('display_id'), $form_state->get('type'), $form_state->get('id'), $item);
 
     // Write to cache
-    $form_state['view']->cacheSet();
+    $view->cacheSet();
   }
 
 }
diff --git a/core/modules/views_ui/src/Form/Ajax/ConfigHandlerGroup.php b/core/modules/views_ui/src/Form/Ajax/ConfigHandlerGroup.php
index fba13ea..3cc63f5 100644
--- a/core/modules/views_ui/src/Form/Ajax/ConfigHandlerGroup.php
+++ b/core/modules/views_ui/src/Form/Ajax/ConfigHandlerGroup.php
@@ -52,10 +52,10 @@ public function getFormId() {
    * {@inheritdoc}
    */
   public function buildForm(array $form, FormStateInterface $form_state) {
-    $view = $form_state['view'];
-    $display_id = $form_state['display_id'];
-    $type = $form_state['type'];
-    $id = $form_state['id'];
+    $view = $form_state->get('view');
+    $display_id = $form_state->get('display_id');
+    $type = $form_state->get('type');
+    $id = $form_state->get('id');
 
     $form = array(
       'options' => array(
@@ -85,7 +85,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
         $form['#title'] = $this->t('Configure aggregation settings for @type %item', array('@type' => $types[$type]['lstitle'], '%item' => $handler->adminLabel()));
 
         $handler->buildGroupByForm($form['options'], $form_state);
-        $form_state['handler'] = $handler;
+        $form_state->set('handler', $handler);
       }
 
       $view->getStandardButtons($form, $form_state, 'views_ui_config_item_group_form');
@@ -97,20 +97,21 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $item = &$form_state['handler']->options;
-    $type = $form_state['type'];
+    $view = $form_state->get('view');
+    $item = &$form_state->get('handler')->options;
+    $type = $form_state->get('type');
 
     $handler = Views::handlerManager($type)->getHandler($item);
-    $executable = $form_state['view']->getExecutable();
+    $executable = $view->getExecutable();
     $handler->init($executable, $executable->display_handler, $item);
 
     $handler->submitGroupByForm($form, $form_state);
 
     // Store the item back on the view
-    $executable->setHandler($form_state['display_id'], $form_state['type'], $form_state['id'], $item);
+    $executable->setHandler($form_state->get('display_id'), $form_state->get('type'), $form_state->get('id'), $item);
 
     // Write to cache
-    $form_state['view']->cacheSet();
+    $view->cacheSet();
   }
 
 }
diff --git a/core/modules/views_ui/src/Form/Ajax/Display.php b/core/modules/views_ui/src/Form/Ajax/Display.php
index 7ac9832..307fda4 100644
--- a/core/modules/views_ui/src/Form/Ajax/Display.php
+++ b/core/modules/views_ui/src/Form/Ajax/Display.php
@@ -32,12 +32,12 @@ public function getFormKey() {
   /**
    * {@inheritdoc}
    *
-   * @todo Remove this and switch all usage of $form_state['section'] to
-   *   $form_state['type'].
+   * @todo Remove this and switch all usage of $form_state->get('section') to
+   *   $form_state->get('type').
    */
   public function getFormState(ViewStorageInterface $view, $display_id, $js) {
     $form_state = parent::getFormState($view, $display_id, $js);
-    $form_state['section'] = $this->type;
+    $form_state->set('section', $this->type);
     return $form_state;
   }
 
@@ -60,8 +60,8 @@ public function getFormId() {
    * {@inheritdoc}
    */
   public function buildForm(array $form, FormStateInterface $form_state) {
-    $view = $form_state['view'];
-    $display_id = $form_state['display_id'];
+    $view = $form_state->get('view');
+    $display_id = $form_state->get('display_id');
 
     $executable = $view->getExecutable();
     $executable->setDisplay($display_id);
@@ -84,11 +84,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       unset($form['options']['override']);
     }
 
-    $name = NULL;
-    if (isset($form_state['update_name'])) {
-      $name = $form_state['update_name'];
-    }
-
+    $name = $form_state->get('update_name');
     $view->getStandardButtons($form, $form_state, 'views_ui_edit_display_form', $name);
     return $form;
   }
@@ -97,10 +93,12 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function validateForm(array &$form, FormStateInterface $form_state) {
-    $form_state['view']->getExecutable()->displayHandlers->get($form_state['display_id'])->validateOptionsForm($form['options'], $form_state);
+    $view = $form_state->get('view');
+    $display_id = $form_state->get('display_id');
+    $view->getExecutable()->displayHandlers->get($display_id)->validateOptionsForm($form['options'], $form_state);
 
     if ($form_state->getErrors()) {
-      $form_state['rerender'] = TRUE;
+      $form_state->set('rerender', TRUE);
     }
   }
 
@@ -108,9 +106,11 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $form_state['view']->getExecutable()->displayHandlers->get($form_state['display_id'])->submitOptionsForm($form['options'], $form_state);
+    $view = $form_state->get('view');
+    $display_id = $form_state->get('display_id');
+    $view->getExecutable()->displayHandlers->get($display_id)->submitOptionsForm($form['options'], $form_state);
 
-    $form_state['view']->cacheSet();
+    $view->cacheSet();
   }
 
 }
diff --git a/core/modules/views_ui/src/Form/Ajax/EditDetails.php b/core/modules/views_ui/src/Form/Ajax/EditDetails.php
index 2a085a0..4d373db 100644
--- a/core/modules/views_ui/src/Form/Ajax/EditDetails.php
+++ b/core/modules/views_ui/src/Form/Ajax/EditDetails.php
@@ -34,7 +34,7 @@ public function getFormId() {
    * {@inheritdoc}
    */
   public function buildForm(array $form, FormStateInterface $form_state) {
-    $view = $form_state['view'];
+    $view = $form_state->get('view');
 
     $form['#title'] = $this->t('Name and description');
     $form['#section'] = 'details';
@@ -75,7 +75,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $view = $form_state['view'];
+    $view = $form_state->get('view');
     foreach ($form_state->getValues() as $key => $value) {
       // Only save values onto the view if they're actual view properties
       // (as opposed to 'op' or 'form_build_id').
@@ -84,11 +84,11 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       }
     }
     $bases = Views::viewsData()->fetchBaseTables();
-    $form_state['#page_title'] = $view->label();
-
+    $page_title = $view->label();
     if (isset($bases[$view->get('base_table')])) {
-      $form_state['#page_title'] .= ' (' . $bases[$view->get('base_table')]['title'] . ')';
+      $page_title .= ' (' . $bases[$view->get('base_table')]['title'] . ')';
     }
+    $form_state->set('#page_title', $page_title);
 
     $view->cacheSet();
   }
diff --git a/core/modules/views_ui/src/Form/Ajax/Rearrange.php b/core/modules/views_ui/src/Form/Ajax/Rearrange.php
index 72b4395..25cf3f1 100644
--- a/core/modules/views_ui/src/Form/Ajax/Rearrange.php
+++ b/core/modules/views_ui/src/Form/Ajax/Rearrange.php
@@ -49,9 +49,9 @@ public function getFormId() {
    * {@inheritdoc}
    */
   public function buildForm(array $form, FormStateInterface $form_state) {
-    $view = $form_state['view'];
-    $display_id = $form_state['display_id'];
-    $type = $form_state['type'];
+    $view = $form_state->get('view');
+    $display_id = $form_state->get('display_id');
+    $type = $form_state->get('type');
 
     $types = ViewExecutable::getHandlerTypes();
     $executable = $view->getExecutable();
@@ -61,8 +61,9 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     $form['#section'] = $display_id . 'rearrange-item';
 
     if ($display->defaultableSections($types[$type]['plural'])) {
-      $form_state['section'] = $types[$type]['plural'];
-      views_ui_standard_display_dropdown($form, $form_state, $form_state['section']);
+      $section = $types[$type]['plural'];
+      $form_state->set('section', $section);
+      views_ui_standard_display_dropdown($form, $form_state, $section);
     }
 
     $count = 0;
@@ -136,10 +137,14 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $types = ViewExecutable::getHandlerTypes();
-    $display = &$form_state['view']->getExecutable()->displayHandlers->get($form_state['display_id']);
+    $view = $form_state->get('view');
+    $display_id = $form_state->get('display_id');
+    $type = $form_state->get('type');
 
-    $old_fields = $display->getOption($types[$form_state['type']]['plural']);
+    $types = ViewExecutable::getHandlerTypes();
+    $display = &$view->getExecutable()->displayHandlers->get($display_id);
+
+    $old_fields = $display->getOption($types[$type]['plural']);
     $new_fields = $order = array();
 
     // Make an array with the weights
@@ -158,10 +163,10 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     foreach (array_keys($order) as $field) {
       $new_fields[$field] = $old_fields[$field];
     }
-    $display->setOption($types[$form_state['type']]['plural'], $new_fields);
+    $display->setOption($types[$type]['plural'], $new_fields);
 
     // Store in cache
-    $form_state['view']->cacheSet();
+    $view->cacheSet();
   }
 
 }
diff --git a/core/modules/views_ui/src/Form/Ajax/RearrangeFilter.php b/core/modules/views_ui/src/Form/Ajax/RearrangeFilter.php
index eb77664..58f869a 100644
--- a/core/modules/views_ui/src/Form/Ajax/RearrangeFilter.php
+++ b/core/modules/views_ui/src/Form/Ajax/RearrangeFilter.php
@@ -35,8 +35,8 @@ public function getFormId() {
    * {@inheritdoc}
    */
   public function buildForm(array $form, FormStateInterface $form_state) {
-    $view = $form_state['view'];
-    $display_id = $form_state['display_id'];
+    $view = $form_state->get('view');
+    $display_id = $form_state->get('display_id');
     $type = 'filter';
 
     $types = ViewExecutable::getHandlerTypes();
@@ -50,8 +50,9 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     $form['#section'] = $display_id . 'rearrange-item';
 
     if ($display->defaultableSections($types[$type]['plural'])) {
-      $form_state['section'] = $types[$type]['plural'];
-      views_ui_standard_display_dropdown($form, $form_state, $form_state['section']);
+      $section = $types[$type]['plural'];
+      $form_state->set('section', $section);
+      views_ui_standard_display_dropdown($form, $form_state, $section);
     }
 
     if (!empty($view->form_cache)) {
@@ -216,11 +217,12 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
     $types = ViewExecutable::getHandlerTypes();
-    $display = &$form_state['view']->getExecutable()->displayHandlers->get($form_state['display_id']);
+    $view = $form_state->get('view');
+    $display = &$view->getExecutable()->displayHandlers->get($form_state->get('display_id'));
     $remember_groups = array();
 
-    if (!empty($form_state['view']->form_cache)) {
-      $old_fields = $form_state['view']->form_cache['handlers'];
+    if (!empty($view->form_cache)) {
+      $old_fields = $view->form_cache['handlers'];
     }
     else {
       $old_fields = $display->getOption($types['filter']['plural']);
@@ -256,15 +258,16 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
 
     // If the #group property is set on the clicked button, that means we are
     // either adding or removing a group, not actually updating the filters.
-    if (!empty($form_state['clicked_button']['#group'])) {
-      if ($form_state['clicked_button']['#group'] == 'add') {
+    $clicked_button = $form_state->get('clicked_button');
+    if (!empty($clicked_button['#group'])) {
+      if ($clicked_button['#group'] == 'add') {
         // Add a new group
         $groups['groups'][] = 'AND';
       }
       else {
         // Renumber groups above the removed one down.
         foreach (array_keys($groups['groups']) as $group_id) {
-          if ($group_id >= $form_state['clicked_button']['#group']) {
+          if ($group_id >= $clicked_button['#group']) {
             $old_group = $group_id + 1;
             if (isset($groups['groups'][$old_group])) {
               $groups['groups'][$group_id] = $groups['groups'][$old_group];
@@ -283,14 +286,14 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       }
       // Update our cache with values so that cancel still works the way
       // people expect.
-      $form_state['view']->form_cache = array(
+      $view->form_cache = [
         'key' => 'rearrange-filter',
         'groups' => $groups,
         'handlers' => $new_fields,
-      );
+      ];
 
       // Return to this form except on actual Update.
-      $form_state['view']->addFormToStack('rearrange-filter', $form_state['display_id'], 'filter');
+      $view->addFormToStack('rearrange-filter', $form_state->get('display_id'), 'filter');
     }
     else {
       // The actual update button was clicked. Remove the empty groups, and
@@ -308,13 +311,13 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       // Write the changed handler values.
       $display->setOption($types['filter']['plural'], $new_fields);
       $display->setOption('filter_groups', $groups);
-      if (isset($form_state['view']->form_cache)) {
-        unset($form_state['view']->form_cache);
+      if (isset($view->form_cache)) {
+        unset($view->form_cache);
       }
     }
 
     // Store in cache.
-    $form_state['view']->cacheSet();
+    $view->cacheSet();
   }
 
   /**
diff --git a/core/modules/views_ui/src/Form/Ajax/ReorderDisplays.php b/core/modules/views_ui/src/Form/Ajax/ReorderDisplays.php
index ba797b0..173202c 100644
--- a/core/modules/views_ui/src/Form/Ajax/ReorderDisplays.php
+++ b/core/modules/views_ui/src/Form/Ajax/ReorderDisplays.php
@@ -34,8 +34,8 @@ public function getFormId() {
    */
   public function buildForm(array $form, FormStateInterface $form_state) {
     /** @var $view \Drupal\views\ViewStorageInterface */
-    $view = $form_state['view'];
-    $display_id = $form_state['display_id'];
+    $view = $form_state->get('view');
+    $display_id = $form_state->get('display_id');
 
     $form['#title'] = $this->t('Reorder displays');
     $form['#section'] = 'reorder';
@@ -151,7 +151,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'];
+    $view = $form_state->get('view');
     $order = array();
 
     $user_input = $form_state->getUserInput();
diff --git a/core/modules/views_ui/src/Form/Ajax/ViewsFormBase.php b/core/modules/views_ui/src/Form/Ajax/ViewsFormBase.php
index d9d9d63..9ab629c 100644
--- a/core/modules/views_ui/src/Form/Ajax/ViewsFormBase.php
+++ b/core/modules/views_ui/src/Form/Ajax/ViewsFormBase.php
@@ -83,8 +83,8 @@ public function getFormState(ViewStorageInterface $view, $display_id, $js) {
    */
   public function getForm(ViewStorageInterface $view, $display_id, $js) {
     $form_state = $this->getFormState($view, $display_id, $js);
-    $view = $form_state['view'];
-    $key = $form_state['form_key'];
+    $view = $form_state->get('view');
+    $key = $form_state->get('form_key');
 
     // @todo Remove the need for this.
     \Drupal::moduleHandler()->loadInclude('views_ui', 'inc', 'admin');
@@ -99,7 +99,7 @@ public function getForm(ViewStorageInterface $view, $display_id, $js) {
     // it off; if it isn't, the user clicked somewhere else and the stack is
     // now irrelevant.
     if (!empty($view->stack)) {
-      $identifier = implode('-', array_filter(array($key, $view->id(), $display_id, $form_state['type'], $form_state['id'])));
+      $identifier = implode('-', array_filter([$key, $view->id(), $display_id, $form_state->get('type'), $form_state->get('id')]));
       // Retrieve the first form from the stack without changing the integer keys,
       // as they're being used for the "2 of 3" progress indicator.
       reset($view->stack);
@@ -126,11 +126,11 @@ public function getForm(ViewStorageInterface $view, $display_id, $js) {
     // before rendering the second time.
     $drupal_add_js_original = _drupal_add_js();
     $drupal_add_js = &drupal_static('_drupal_add_js');
-    $form_class = get_class($form_state['build_info']['callback_object']);
+    $form_class = get_class($form_state->getFormObject());
     $response = views_ajax_form_wrapper($form_class, $form_state);
 
     // If the form has not been submitted, or was not set for rerendering, stop.
-    if (!$form_state['submitted'] || !empty($form_state['rerender'])) {
+    if (!$form_state->isSubmitted() || $form_state->get('rerender')) {
       return $response;
     }
 
@@ -143,18 +143,18 @@ public function getForm(ViewStorageInterface $view, $display_id, $js) {
       // Build the new form state for the next form in the stack.
       $reflection = new \ReflectionClass($view::$forms[$top[1]]);
       /** @var $form_state \Drupal\Core\Form\FormStateInterface */
-      $form_state = $reflection->newInstanceArgs(array_slice($top, 3, 2))->getFormState($view, $top[2], $form_state['ajax']);
-      $form_class = get_class($form_state['build_info']['callback_object']);
+      $form_state = $reflection->newInstanceArgs(array_slice($top, 3, 2))->getFormState($view, $top[2], $form_state->get('ajax'));
+      $form_class = get_class($form_state->getFormObject());
 
       $form_state->setUserInput(array());
       $form_path = views_ui_build_form_path($form_state);
-      if (!$form_state['ajax']) {
+      if (!$form_state->get('ajax')) {
         return new RedirectResponse(url($form_path, array('absolute' => TRUE)));
       }
-      $form_state['path'] = $form_path;
+      $form_state->set('path', $form_path);
       $response = views_ajax_form_wrapper($form_class, $form_state);
     }
-    elseif (!$form_state['ajax']) {
+    elseif (!$form_state->get('ajax')) {
       // if nothing on the stack, non-js forms just go back to the main view editor.
       $display_id = $form_state->get('display_id');
       return new RedirectResponse(url("admin/structure/views/view/{$view->id()}/edit/$display_id", array('absolute' => TRUE)));
@@ -164,8 +164,8 @@ public function getForm(ViewStorageInterface $view, $display_id, $js) {
       $response->addCommand(new CloseModalDialogCommand());
       $response->addCommand(new Ajax\ShowButtonsCommand(!empty($view->changed)));
       $response->addCommand(new Ajax\TriggerPreviewCommand());
-      if (!empty($form_state['#page_title'])) {
-        $response->addCommand(new Ajax\ReplaceTitleCommand($form_state['#page_title']));
+      if ($page_title = $form_state->get('#page_title')) {
+        $response->addCommand(new Ajax\ReplaceTitleCommand($page_title));
       }
     }
     // If this form was for view-wide changes, there's no need to regenerate
diff --git a/core/modules/views_ui/src/ViewAddForm.php b/core/modules/views_ui/src/ViewAddForm.php
index b2070d6..84bb713 100644
--- a/core/modules/views_ui/src/ViewAddForm.php
+++ b/core/modules/views_ui/src/ViewAddForm.php
@@ -166,9 +166,9 @@ protected function actions(array $form, FormStateInterface $form_state) {
   public function validate(array $form, FormStateInterface $form_state) {
     $wizard_type = $form_state->getValue(array('show', 'wizard_key'));
     $wizard_instance = $this->wizardManager->createInstance($wizard_type);
-    $form_state['wizard'] = $wizard_instance->getPluginDefinition();
-    $form_state['wizard_instance'] = $wizard_instance;
-    $errors = $form_state['wizard_instance']->validateView($form, $form_state);
+    $form_state->set('wizard', $wizard_instance->getPluginDefinition());
+    $form_state->set('wizard_instance', $wizard_instance);
+    $errors = $wizard_instance->validateView($form, $form_state);
 
     foreach ($errors as $display_errors) {
       foreach ($display_errors as $name => $message) {
@@ -183,7 +183,7 @@ public function validate(array $form, FormStateInterface $form_state) {
   public function submitForm(array &$form, FormStateInterface $form_state) {
     try {
       /** @var $wizard \Drupal\views\Plugin\views\wizard\WizardInterface */
-      $wizard = $form_state['wizard_instance'];
+      $wizard = $form_state->get('wizard_instance');
       $this->entity = $wizard->createView($form, $form_state);
     }
     // @todo Figure out whether it really makes sense to throw and catch exceptions on the wizard.
diff --git a/core/modules/views_ui/src/ViewEditForm.php b/core/modules/views_ui/src/ViewEditForm.php
index 77bf3de..eda64cc 100644
--- a/core/modules/views_ui/src/ViewEditForm.php
+++ b/core/modules/views_ui/src/ViewEditForm.php
@@ -82,15 +82,15 @@ public static function create(ContainerInterface $container) {
   public function form(array $form, FormStateInterface $form_state) {
     $view = $this->entity;
     $display_id = $this->displayID;
-    // Do not allow the form to be cached, because $form_state['view'] can become
+    // Do not allow the form to be cached, because $form_state->get('view') can become
     // stale between page requests.
     // See views_ui_ajax_get_form() for how this affects #ajax.
     // @todo To remove this and allow the form to be cacheable:
-    //   - Change $form_state['view'] to $form_state['temporary']['view'].
-    //   - Add a #process function to initialize $form_state['temporary']['view']
+    //   - Change $form_state->get('view') to $form_state->getTemporary()['view'].
+    //   - Add a #process function to initialize $form_state->getTemporary()['view']
     //     on cached form submissions.
     //   - Use \Drupal\Core\Form\FormStateInterface::loadInclude().
-    $form_state['no_cache'] = TRUE;
+    $form_state->disableCache();
 
     if ($display_id) {
       if (!$view->getExecutable()->setDisplay($display_id)) {
@@ -177,7 +177,7 @@ public function form(array $form, FormStateInterface $form_state) {
 
     // The rest requires a display to be selected.
     if ($display_id) {
-      $form_state['display_id'] = $display_id;
+      $form_state->set('display_id', $display_id);
 
       // The part of the page where editing will take place.
       $form['displays']['settings'] = array(
@@ -581,7 +581,7 @@ public function getDisplayDetails($view, $display) {
   public function submitDisplayUndoDelete($form, FormStateInterface $form_state) {
     $view = $this->entity;
     // Create the new display
-    $id = $form_state['display_id'];
+    $id = $form_state->get('display_id');
     $displays = $view->get('display');
     $displays[$id]['deleted'] = FALSE;
     $view->set('display', $displays);
@@ -601,7 +601,7 @@ public function submitDisplayUndoDelete($form, FormStateInterface $form_state) {
    */
   public function submitDisplayEnable($form, FormStateInterface $form_state) {
     $view = $this->entity;
-    $id = $form_state['display_id'];
+    $id = $form_state->get('display_id');
     // setOption doesn't work because this would might affect upper displays
     $view->getExecutable()->displayHandlers->get($id)->setOption('enabled', TRUE);
 
@@ -620,7 +620,7 @@ public function submitDisplayEnable($form, FormStateInterface $form_state) {
    */
   public function submitDisplayDisable($form, FormStateInterface $form_state) {
     $view = $this->entity;
-    $id = $form_state['display_id'];
+    $id = $form_state->get('display_id');
     $view->getExecutable()->displayHandlers->get($id)->setOption('enabled', FALSE);
 
     // Store in cache
@@ -638,7 +638,7 @@ public function submitDisplayDisable($form, FormStateInterface $form_state) {
    */
   public function submitDisplayDelete($form, FormStateInterface $form_state) {
     $view = $this->entity;
-    $display_id = $form_state['display_id'];
+    $display_id = $form_state->get('display_id');
 
     // Mark the display for deletion.
     $displays = $view->get('display');
@@ -772,7 +772,7 @@ public function renderDisplayTop(ViewUI $view) {
    * Submit handler for form buttons that do not complete a form workflow.
    *
    * The Edit View form is a multistep form workflow, but with state managed by
-   * the TempStore rather than $form_state['rebuild']. Without this
+   * the TempStore rather than $form_state->setRebuild(). Without this
    * submit handler, buttons that add or remove displays would redirect to the
    * destination parameter (e.g., when the Edit View form is linked to from a
    * contextual link). This handler can be added to buttons whose form submission
@@ -837,7 +837,7 @@ public function submitDisplayDuplicate($form, FormStateInterface $form_state) {
   public function submitDisplayAdd($form, FormStateInterface $form_state) {
     $view = $this->entity;
     // Create the new display.
-    $parents = $form_state['triggering_element']['#parents'];
+    $parents = $form_state->getTriggeringElement()['#parents'];
     $display_type = array_pop($parents);
     $display = $view->getExecutable()->newDisplay($display_type);
     $display_id = $display->display['id'];
@@ -861,7 +861,7 @@ public function submitDuplicateDisplayAsType($form, FormStateInterface $form_sta
     $display_id = $this->displayID;
 
     // Create the new display.
-    $parents = $form_state['triggering_element']['#parents'];
+    $parents = $form_state->getTriggeringElement()['#parents'];
     $display_type = array_pop($parents);
     $display = $view->getExecutable()->newDisplay($display_type);
     $new_display_id = $display->display['id'];
diff --git a/core/modules/views_ui/src/ViewPreviewForm.php b/core/modules/views_ui/src/ViewPreviewForm.php
index 9ba3b99..f132b64 100644
--- a/core/modules/views_ui/src/ViewPreviewForm.php
+++ b/core/modules/views_ui/src/ViewPreviewForm.php
@@ -58,7 +58,7 @@ public function form(array $form, FormStateInterface $form_state) {
     $seen_ids_init = &drupal_static('drupal_html_id:init');
     $seen_ids_init = array();
 
-    $form_state['no_cache'] = TRUE;
+    $form_state->disableCache();
 
     $form['controls']['#attributes'] = array('class' => array('clearfix'));
 
@@ -84,7 +84,7 @@ public function form(array $form, FormStateInterface $form_state) {
     }
 
     $user_input = $form_state->getUserInput();
-    if (!empty($form_state['show_preview']) || !empty($user_input['js'])) {
+    if ($form_state->get('show_preview') || !empty($user_input['js'])) {
       $form['preview'] = array(
         '#weight' => 110,
         '#theme_wrappers' => array('container'),
@@ -135,9 +135,11 @@ public function submitPreview($form, FormStateInterface $form_state) {
     if (!$new_view = $this->tempStore->get($view->id())) {
       $new_view = new ViewUI($view);
     }
-    $form_state['build_info']['args'][0] = $new_view;
-    $form_state['show_preview'] = TRUE;
-    $form_state['rebuild'] = TRUE;
+    $build_info = $form_state->getBuildInfo();
+    $build_info['args'][0] = $new_view;
+    $form_state->setBuildInfo($build_info);
+    $form_state->set('show_preview', TRUE);
+    $form_state->setRebuild();
   }
 
 }
diff --git a/core/modules/views_ui/src/ViewUI.php b/core/modules/views_ui/src/ViewUI.php
index 51e16b2..203374c 100644
--- a/core/modules/views_ui/src/ViewUI.php
+++ b/core/modules/views_ui/src/ViewUI.php
@@ -250,9 +250,10 @@ public function standardSubmit($form, FormStateInterface $form_state) {
 
     // Based on the user's choice in the display dropdown, determine which display
     // these changes apply to.
+    $display_id = $form_state->get('display_id');
     if ($revert) {
       // If it's revert just change the override and return.
-      $display = &$this->executable->displayHandlers->get($form_state['display_id']);
+      $display = &$this->executable->displayHandlers->get($display_id);
       $display->optionsOverride($form, $form_state);
 
       // Don't execute the normal submit handling but still store the changed view into cache.
@@ -266,7 +267,7 @@ public function standardSubmit($form, FormStateInterface $form_state) {
     elseif ($was_defaulted && !$is_defaulted) {
       // We were using the default display's values, but we're now overriding
       // the default display and saving values specific to this display.
-      $display = &$this->executable->displayHandlers->get($form_state['display_id']);
+      $display = &$this->executable->displayHandlers->get($display_id);
       // optionsOverride toggles the override of this section.
       $display->optionsOverride($form, $form_state);
       $display->submitOptionsForm($form, $form_state);
@@ -276,22 +277,14 @@ public function standardSubmit($form, FormStateInterface $form_state) {
       // to go back to the default display.
       // Overwrite the default display with the current form values, and make
       // the current display use the new default values.
-      $display = &$this->executable->displayHandlers->get($form_state['display_id']);
+      $display = &$this->executable->displayHandlers->get($display_id);
       // optionsOverride toggles the override of this section.
       $display->optionsOverride($form, $form_state);
       $display->submitOptionsForm($form, $form_state);
     }
 
-    $submit_handler = $form['#form_id'] . '_submit';
-    if (isset($form_state['build_info']['callback_object'])) {
-      $submit_handler = array($form_state['build_info']['callback_object'], 'submitForm');
-    }
-    if (is_callable($submit_handler)) {
-      // The submit handler might be a function or a method on the
-      // callback_object. Additional note that we have to pass the parameters
-      // by reference, as php 5.4 requires us to do that.
-      call_user_func_array($submit_handler, array(&$form, &$form_state));
-    }
+    $submit_handler = [$form_state->getFormObject(), 'submitForm'];
+    call_user_func_array($submit_handler, [&$form, $form_state]);
   }
 
   /**
@@ -330,11 +323,11 @@ public function getStandardButtons(&$form, FormStateInterface $form_state, $form
     // Views provides its own custom handling of AJAX form submissions. Usually
     // this happens at the same path, but custom paths may be specified in
     // $form_state.
-    $form_path = empty($form_state['path']) ? current_path() : $form_state['path'];
+    $form_path = $form_state->get('path') ?: current_path();
 
     // Forms that are purely informational set an ok_button flag, so we know not
     // to create an "Apply" button for them.
-    if (empty($form_state['ok_button'])) {
+    if (!$form_state->get('ok_button')) {
       $form['actions']['submit'] = array(
         '#type' => 'submit',
         '#value' => $name,
@@ -364,19 +357,14 @@ public function getStandardButtons(&$form, FormStateInterface $form_state, $form
         $form['actions']['submit']['#process'] = array_merge(array('views_ui_form_button_was_clicked'), element_info_property($form['actions']['submit']['#type'], '#process', array()));
       }
       // If a validation handler exists for the form, assign it to this button.
-      if (isset($form_state['build_info']['callback_object'])) {
-        $form['actions']['submit']['#validate'][] = array($form_state['build_info']['callback_object'], 'validateForm');
-      }
-      if (function_exists($form_id . '_validate')) {
-        $form['actions']['submit']['#validate'][] = $form_id . '_validate';
-      }
+      $form['actions']['submit']['#validate'][] = [$form_state->getFormObject(), 'validateForm'];
     }
 
     // Create a "Cancel" button. For purely informational forms, label it "OK".
     $cancel_submit = function_exists($form_id . '_cancel') ? $form_id . '_cancel' : array($this, 'standardCancel');
     $form['actions']['cancel'] = array(
       '#type' => 'submit',
-      '#value' => empty($form_state['ok_button']) ? t('Cancel') : t('Ok'),
+      '#value' => !$form_state->get('ok_button') ? t('Cancel') : t('Ok'),
       '#submit' => array($cancel_submit),
       '#validate' => array(),
       '#ajax' => array(
@@ -388,10 +376,10 @@ public function getStandardButtons(&$form, FormStateInterface $form_state, $form
     // Compatibility, to be removed later: // TODO: When is "later"?
     // We used to set these items on the form, but now we want them on the $form_state:
     if (isset($form['#title'])) {
-      $form_state['title'] = $form['#title'];
+      $form_state->set('title', $form['#title']);
     }
     if (isset($form['#section'])) {
-      $form_state['#section'] = $form['#section'];
+      $form_state->set('#section', $form['#section']);
     }
     // Finally, we never want these cached -- our object cache does that for us.
     $form['#no_cache'] = TRUE;
@@ -413,7 +401,7 @@ public function getOverrideValues($form, FormStateInterface $form_state) {
       if ($was_defaulted !== $is_defaulted && isset($form['#section'])) {
         // We're changing which display these values apply to.
         // Update the #section so it knows what to mark changed.
-        $form['#section'] = str_replace('default-', $form_state['display_id'] . '-', $form['#section']);
+        $form['#section'] = str_replace('default-', $form_state->get('display_id') . '-', $form['#section']);
       }
     }
     else {
@@ -477,16 +465,17 @@ public function addFormToStack($key, $display_id, $type, $id = NULL, $top = FALS
    * Submit handler for adding new item(s) to a view.
    */
   public function submitItemAdd($form, FormStateInterface $form_state) {
-    $type = $form_state['type'];
+    $type = $form_state->get('type');
     $types = ViewExecutable::getHandlerTypes();
     $section = $types[$type]['plural'];
+    $display_id = $form_state->get('display_id');
 
     // Handle the override select.
     list($was_defaulted, $is_defaulted) = $this->getOverrideValues($form, $form_state);
     if ($was_defaulted && !$is_defaulted) {
       // We were using the default display's values, but we're now overriding
       // the default display and saving values specific to this display.
-      $display = &$this->executable->displayHandlers->get($form_state['display_id']);
+      $display = &$this->executable->displayHandlers->get($display_id);
       // setOverride toggles the override of this section.
       $display->setOverride($section);
     }
@@ -495,7 +484,7 @@ public function submitItemAdd($form, FormStateInterface $form_state) {
       // to go back to the default display.
       // Overwrite the default display with the current form values, and make
       // the current display use the new default values.
-      $display = &$this->executable->displayHandlers->get($form_state['display_id']);
+      $display = &$this->executable->displayHandlers->get($display_id);
       // optionsOverride toggles the override of this section.
       $display->setOverride($section);
     }
@@ -508,7 +497,7 @@ public function submitItemAdd($form, FormStateInterface $form_state) {
         if ($cut = strpos($field, '$')) {
           $field = substr($field, 0, $cut);
         }
-        $id = $this->executable->addHandler($form_state['display_id'], $type, $table, $field);
+        $id = $this->executable->addHandler($display_id, $type, $table, $field);
 
         // check to see if we have group by settings
         $key = $type;
@@ -522,15 +511,15 @@ public function submitItemAdd($form, FormStateInterface $form_state) {
         );
         $handler = Views::handlerManager($key)->getHandler($item);
         if ($this->executable->displayHandlers->get('default')->useGroupBy() && $handler->usesGroupBy()) {
-          $this->addFormToStack('handler-group', $form_state['display_id'], $type, $id);
+          $this->addFormToStack('handler-group', $display_id, $type, $id);
         }
 
         // check to see if this type has settings, if so add the settings form first
         if ($handler && $handler->hasExtraOptions()) {
-          $this->addFormToStack('handler-extra', $form_state['display_id'], $type, $id);
+          $this->addFormToStack('handler-extra', $display_id, $type, $id);
         }
         // Then add the form to the stack
-        $this->addFormToStack('handler', $form_state['display_id'], $type, $id);
+        $this->addFormToStack('handler', $display_id, $type, $id);
       }
     }
 
