diff --git a/core/lib/Drupal/Core/Form/FormState.php b/core/lib/Drupal/Core/Form/FormState.php
index 9cb0b0d..5faaff0 100644
--- a/core/lib/Drupal/Core/Form/FormState.php
+++ b/core/lib/Drupal/Core/Form/FormState.php
@@ -967,7 +967,12 @@ public function setUserInput(array $user_input) {
    * {@inheritdoc}
    */
   public function &getValues() {
-    return $this->values;
+    end($this->values);
+    $value = &$this->values[key($this->values)];
+    if (is_null($value)) {
+      $value = [];
+    }
+    return $value;
   }
 
   /**
@@ -986,7 +991,8 @@ public function &getValue($key, $default = NULL) {
    * {@inheritdoc}
    */
   public function setValues(array $values) {
-    $this->values = $values;
+    $existing_values = &$this->getValues();
+    $existing_values = $values;
     return $this;
   }
 
@@ -1009,6 +1015,21 @@ public function unsetValue($key) {
   /**
    * {@inheritdoc}
    */
+  public function pushValues(array $values) {
+    $this->values[] = $values;
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function popValues() {
+    return array_pop($this->values);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function hasValue($key) {
     $exists = NULL;
     $value = NestedArray::getValue($this->getValues(), (array) $key, $exists);
diff --git a/core/lib/Drupal/Core/Form/FormStateInterface.php b/core/lib/Drupal/Core/Form/FormStateInterface.php
index fd46f70..724b28b 100644
--- a/core/lib/Drupal/Core/Form/FormStateInterface.php
+++ b/core/lib/Drupal/Core/Form/FormStateInterface.php
@@ -346,6 +346,18 @@ public function setValue($key, $value);
   public function unsetValue($key);
 
   /**
+   * @param array $values
+   *
+   * @return $this
+   */
+  public function pushValues(array $values);
+
+  /**
+   * @return array
+   */
+  public function popValues();
+
+  /**
    * Determines if a specific key is present in the submitted form values.
    *
    * @param string|array $key
diff --git a/core/modules/block/src/BlockForm.php b/core/modules/block/src/BlockForm.php
index 8c13bbb..b1bda1f 100644
--- a/core/modules/block/src/BlockForm.php
+++ b/core/modules/block/src/BlockForm.php
@@ -285,11 +285,11 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
 
     // The Block Entity form puts all block plugin form elements in the
     // settings form element, so just pass that to the block for validation.
-    $settings = (new FormState())->setValues($form_state->getValue('settings'));
+    $form_state->pushValues($form_state->getValue('settings'));
     // Call the plugin validate handler.
-    $this->entity->getPlugin()->validateConfigurationForm($form, $settings);
+    $this->entity->getPlugin()->validateConfigurationForm($form, $form_state);
+    $form_state->popValues();
     // Update the original form values.
-    $form_state->setValue('settings', $settings->getValues());
     $this->validateVisibility($form, $form_state);
   }
 
@@ -312,12 +312,11 @@ protected function validateVisibility(array $form, FormStateInterface $form_stat
       }
 
       // Allow the condition to validate the form.
-      $condition = $form_state->get(['conditions', $condition_id]);
-      $condition_values = (new FormState())
-        ->setValues($values);
-      $condition->validateConfigurationForm($form, $condition_values);
-      // Update the original form values.
-      $form_state->setValue(['visibility', $condition_id], $condition_values->getValues());
+      $form_state->pushValues($values);
+      $form_state
+        ->get(['conditions', $condition_id])
+        ->validateConfigurationForm($form, $form_state);
+      $form_state->popValues();
     }
   }
 
@@ -330,21 +329,19 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $entity = $this->entity;
     // The Block Entity form puts all block plugin form elements in the
     // settings form element, so just pass that to the block for submission.
-    // @todo Find a way to avoid this manipulation.
-    $settings = (new FormState())->setValues($form_state->getValue('settings'));
-
+    $form_state->pushValues($form_state->getValue('settings'));
     // Call the plugin submit handler.
-    $entity->getPlugin()->submitConfigurationForm($form, $settings);
-    // Update the original form values.
-    $form_state->setValue('settings', $settings->getValues());
+    $entity->getPlugin()->submitConfigurationForm($form, $form_state);
+    $form_state->popValues();
 
     // Submit visibility condition settings.
     foreach ($form_state->getValue('visibility') as $condition_id => $values) {
       // Allow the condition to submit the form.
+      $form_state->pushValues($values);
       $condition = $form_state->get(['conditions', $condition_id]);
-      $condition_values = (new FormState())
-        ->setValues($values);
-      $condition->submitConfigurationForm($form, $condition_values);
+      $condition->submitConfigurationForm($form, $form_state);
+      $form_state->popValues();
+
       if ($condition instanceof ContextAwarePluginInterface) {
         $context_mapping = isset($values['context_mapping']) ? $values['context_mapping'] : [];
         $condition->setContextMapping($context_mapping);
diff --git a/core/modules/image/src/Form/ImageEffectFormBase.php b/core/modules/image/src/Form/ImageEffectFormBase.php
index 7b7f25b..06ee18e 100644
--- a/core/modules/image/src/Form/ImageEffectFormBase.php
+++ b/core/modules/image/src/Form/ImageEffectFormBase.php
@@ -31,7 +31,7 @@
   /**
    * The image effect.
    *
-   * @var \Drupal\image\ImageEffectInterface
+   * @var \Drupal\image\ImageEffectInterface|\Drupal\image\ConfigurableImageEffectInterface
    */
   protected $imageEffect;
 
@@ -108,10 +108,9 @@ public function buildForm(array $form, FormStateInterface $form_state, ImageStyl
   public function validateForm(array &$form, FormStateInterface $form_state) {
     // The image effect configuration is stored in the 'data' key in the form,
     // pass that through for validation.
-    $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->getValues());
+    $form_state->pushValues($form_state->getValue('data'));
+    $this->imageEffect->validateConfigurationForm($form, $form_state);
+    $form_state->popValues();
   }
 
   /**
@@ -122,10 +121,9 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
 
     // The image effect configuration is stored in the 'data' key in the form,
     // pass that through for submission.
-    $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->getValues());
+    $form_state->pushValues($form_state->getValue('data'));
+    $this->imageEffect->submitConfigurationForm($form, $form_state);
+    $form_state->popValues();
 
     $this->imageEffect->setWeight($form_state->getValue('weight'));
     if (!$this->imageEffect->getUuid()) {
