diff --git a/core/lib/Drupal/Core/Form/FormBuilder.php b/core/lib/Drupal/Core/Form/FormBuilder.php
index 6a81eb0..45a1cc6 100644
--- a/core/lib/Drupal/Core/Form/FormBuilder.php
+++ b/core/lib/Drupal/Core/Form/FormBuilder.php
@@ -190,9 +190,12 @@ public function getForm($form_arg) {
   /**
    * {@inheritdoc}
    */
-  public function buildForm($form_id, &$form_state) {
+  public function buildForm($form_id, array &$form_state) {
     // Ensure some defaults; if already set they will not be overridden.
-    $form_state += $this->getFormStateDefaults();
+    $form_state = NestedArray::mergeDeep($this->getFormStateDefaults(), $form_state);
+
+    // Ensure the form ID is prepared.
+    $form_id = $this->getFormId($form_id, $form_state);
 
     if (!isset($form_state['input'])) {
       $form_state['input'] = $form_state['method'] == 'get' ? $_GET : $_POST;
diff --git a/core/lib/Drupal/Core/Form/FormBuilderInterface.php b/core/lib/Drupal/Core/Form/FormBuilderInterface.php
index bbe355a..b655523 100644
--- a/core/lib/Drupal/Core/Form/FormBuilderInterface.php
+++ b/core/lib/Drupal/Core/Form/FormBuilderInterface.php
@@ -73,7 +73,7 @@ public function getForm($form_arg);
    *   can implement hook_forms(), which maps different $form_id values to the
    *   proper form constructor function. Examples may be found in node_forms(),
    *   and search_forms().
-   * @param $form_state
+   * @param array $form_state
    *   An array which stores information about the form. This is passed as a
    *   reference so that the caller can use it to examine what in the form
    *   changed when the form submission process is complete. Furthermore, it may
@@ -229,7 +229,7 @@ public function getForm($form_arg);
    *
    * @see self::redirectForm()
    */
-  public function buildForm($form_id, &$form_state);
+  public function buildForm($form_id, array &$form_state);
 
   /**
    * Retrieves default values for the $form_state array.
diff --git a/core/modules/views/lib/Drupal/views/ExposedFormCache.php b/core/modules/views/lib/Drupal/views/ExposedFormCache.php
new file mode 100644
index 0000000..30b4a60
--- /dev/null
+++ b/core/modules/views/lib/Drupal/views/ExposedFormCache.php
@@ -0,0 +1,67 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\views\ExposedFormCache.
+ */
+
+namespace Drupal\views;
+
+/**
+ * Caches exposed forms, as they are heavy to generate.
+ *
+ * @see \Drupal\views\Form\ViewsExposedForm
+ */
+class ExposedFormCache {
+
+  /**
+   * Stores the exposed form data.
+   *
+   * @var array
+   */
+  protected $cache = array();
+
+  /**
+   * Save the Views exposed form for later use.
+   *
+   * @param string $view_id
+   *   The views ID.
+   * @param string $display_id
+   *   The current view display name.
+   * @param array $form_output
+   *   The form structure. Only needed when inserting the value.
+   */
+  public function setForm($view_id, $display_id, array $form_output) {
+    // Save the form output.
+    $views_exposed[$view_id][$display_id] = $form_output;
+  }
+
+  /**
+   * Retrieves the views exposed form from cache.
+   *
+   * @param string $view_id
+   *   The views ID.
+   * @param string $display_id
+   *   The current view display name.
+   *
+   * @return array|bool
+   *   The form structure, if any, otherwise FALSE.
+   */
+  public function getForm($view_id, $display_id) {
+    // Return the form output, if any.
+    if (empty($this->cache[$view_id][$display_id])) {
+      return FALSE;
+    }
+    else {
+      return $this->cache[$view_id][$display_id];
+    }
+  }
+
+  /**
+   * Rests the form cache.
+   */
+  public function reset() {
+    $this->cache = array();
+  }
+
+}
diff --git a/core/modules/views/lib/Drupal/views/Form/ViewsExposedForm.php b/core/modules/views/lib/Drupal/views/Form/ViewsExposedForm.php
new file mode 100644
index 0000000..dad447b
--- /dev/null
+++ b/core/modules/views/lib/Drupal/views/Form/ViewsExposedForm.php
@@ -0,0 +1,173 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\views\Form\ViewsExposedForm.
+ */
+
+namespace Drupal\views\Form;
+
+use Drupal\Component\Utility\String;
+use Drupal\Core\Form\FormBase;
+use Drupal\views\ExposedFormCache;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Provides the views exposed form.
+ */
+class ViewsExposedForm extends FormBase {
+
+  /**
+   * The exposed form cache.
+   *
+   * @var \Drupal\views\ExposedFormCache
+   */
+  protected $exposedFormCache;
+
+  /**
+   * Constructs a new ViewsExposedForm
+   *
+   * @param \Drupal\views\ExposedFormCache $exposed_form_cache
+   *   The exposed form cache.
+   */
+  public function __construct(ExposedFormCache $exposed_form_cache) {
+    $this->exposedFormCache = $exposed_form_cache;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static($container->get('views.exposed_form_cache'));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormId() {
+    return 'views_exposed_form';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, array &$form_state) {
+    // Don't show the form when batch operations are in progress.
+    if ($batch = batch_get() && isset($batch['current_set'])) {
+      return array(
+        // Set the theme callback to be nothing to avoid errors in template_preprocess_views_exposed_form().
+        '#theme' => '',
+      );
+    }
+
+    // Make sure that we validate because this form might be submitted
+    // multiple times per page.
+    $form_state['must_validate'] = TRUE;
+    /** @var \Drupal\views\ViewExecutable $view */
+    $view = $form_state['view'];
+    $display = &$form_state['display'];
+
+    $form_state['input'] = $view->getExposedInput();
+
+    // Let form plugins know this is for exposed widgets.
+    $form_state['exposed'] = TRUE;
+    // Check if the form was already created
+    if ($cache = $this->exposedFormCache->getForm($view->storage->id(), $view->current_display)) {
+      return $cache;
+    }
+
+    $form['#info'] = array();
+
+    // Go through each handler and let it generate its exposed widget.
+    foreach ($view->display_handler->handlers as $type => $value) {
+      /** @var \Drupal\views\Plugin\views\HandlerBase $handler */
+      foreach ($view->$type as $id => $handler) {
+        if ($handler->canExpose() && $handler->isExposed()) {
+          // Grouped exposed filters have their own forms.
+          // Instead of render the standard exposed form, a new Select or
+          // Radio form field is rendered with the available groups.
+          // When an user choose an option the selected value is split
+          // into the operator and value that the item represents.
+          if ($handler->isAGroup()) {
+            $handler->groupForm($form, $form_state);
+            $id = $handler->options['group_info']['identifier'];
+          }
+          else {
+            $handler->buildExposedForm($form, $form_state);
+          }
+          if ($info = $handler->exposedInfo()) {
+            $form['#info']["$type-$id"] = $info;
+          }
+        }
+      }
+    }
+
+    $form['actions'] = array(
+      '#type' => 'actions'
+    );
+    $form['actions']['submit'] = array(
+      // Prevent from showing up in $_GET.
+      '#name' => '',
+      '#type' => 'submit',
+      '#value' => $this->t('Apply'),
+      '#id' => drupal_html_id('edit-submit-' . $view->storage->id()),
+    );
+
+    $form['#action'] = url($view->display_handler->getUrl());
+    $form['#theme'] = $view->buildThemeFunctions('views_exposed_form');
+    $form['#id'] = drupal_clean_css_identifier('views_exposed_form-' . String::checkPlain($view->storage->id()) . '-' . String::checkPlain($display['id']));
+    // $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->exposedFormAlter($form, $form_state);
+
+    // Save the form.
+    $this->exposedFormCache->setForm($view->storage->id(), $view->current_display, $form);
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateForm(array &$form, array &$form_state) {
+    foreach (array('field', 'filter') as $type) {
+      /** @var \Drupal\views\Plugin\views\HandlerBase[] $handlers */
+      $handlers = &$form_state['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->exposedFormValidate($form, $form_state);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, array &$form_state) {
+    foreach (array('field', 'filter') as $type) {
+      /** @var \Drupal\views\Plugin\views\HandlerBase[] $handlers */
+      $handlers = &$form_state['view']->$type;
+      foreach ($handlers as $key => $info) {
+        $handlers[$key]->submitExposed($form, $form_state);
+      }
+    }
+    $form_state['view']->exposed_data = $form_state['values'];
+    $form_state['view']->exposed_raw_input = array();
+
+    $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->exposedFormSubmit($form, $form_state, $exclude);
+
+    foreach ($form_state['values'] as $key => $value) {
+      if (!in_array($key, $exclude)) {
+        $form_state['view']->exposed_raw_input[$key] = $value;
+      }
+    }
+  }
+
+}
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/exposed_form/ExposedFormPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/exposed_form/ExposedFormPluginBase.php
index bcab59d..784d926 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/exposed_form/ExposedFormPluginBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/exposed_form/ExposedFormPluginBase.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\views\Plugin\views\exposed_form;
 
+use Drupal\views\Form\ViewsExposedForm;
 use Drupal\views\ViewExecutable;
 use Drupal\views\Plugin\views\display\DisplayPluginBase;
 use Drupal\views\Plugin\views\PluginBase;
@@ -138,7 +139,7 @@ public function renderExposedForm($block = FALSE) {
     }
 
     $form_state['exposed_form_plugin'] = $this;
-    $form = drupal_build_form('views_exposed_form', $form_state);
+    $form = \Drupal::formBuilder()->buildForm('\Drupal\views\Form\ViewsExposedForm', $form_state);
 
     if (!$this->view->display_handler->displaysExposed() || (!$block && $this->view->display_handler->getOption('exposed_block'))) {
       return array();
diff --git a/core/modules/views/lib/Drupal/views/Tests/Handler/FilterStringTest.php b/core/modules/views/lib/Drupal/views/Tests/Handler/FilterStringTest.php
index efb19f7..cb444c9 100644
--- a/core/modules/views/lib/Drupal/views/Tests/Handler/FilterStringTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/Handler/FilterStringTest.php
@@ -86,7 +86,7 @@ protected function getBasicPageView() {
 
     // In order to test exposed filters, we have to disable
     // the exposed forms cache.
-    drupal_static_reset('views_exposed_form_cache');
+    \Drupal::service('views.exposed_form_cache')->reset();
 
     $view->newDisplay('page', 'Page', 'page_1');
     return $view;
diff --git a/core/modules/views/views.module b/core/modules/views/views.module
index 8445804..f5201de 100644
--- a/core/modules/views/views.module
+++ b/core/modules/views/views.module
@@ -1044,83 +1044,6 @@ function views_pre_render_views_form_views_form($element) {
 }
 
 /**
- * Form builder for the exposed widgets form.
- *
- * Be sure that $display is a reference.
- */
-function views_exposed_form($form, &$form_state) {
-  // Don't show the form when batch operations are in progress.
-  if ($batch = batch_get() && isset($batch['current_set'])) {
-    return array(
-      // Set the theme callback to be nothing to avoid errors in template_preprocess_views_exposed_form().
-      '#theme' => '',
-    );
-  }
-
-  // Make sure that we validate because this form might be submitted
-  // multiple times per page.
-  $form_state['must_validate'] = TRUE;
-  $view = $form_state['view'];
-  $display = &$form_state['display'];
-
-  $form_state['input'] = $view->getExposedInput();
-
-  // Let form plugins know this is for exposed widgets.
-  $form_state['exposed'] = TRUE;
-  // Check if the form was already created
-  if ($cache = views_exposed_form_cache($view->storage->id(), $view->current_display)) {
-    return $cache;
-  }
-
-  $form['#info'] = array();
-
-  // Go through each handler and let it generate its exposed widget.
-  foreach ($view->display_handler->handlers as $type => $value) {
-    foreach ($view->$type as $id => $handler) {
-      if ($handler->canExpose() && $handler->isExposed()) {
-        // Grouped exposed filters have their own forms.
-        // Instead of render the standard exposed form, a new Select or
-        // Radio form field is rendered with the available groups.
-        // When an user choose an option the selected value is split
-        // into the operator and value that the item represents.
-        if ($handler->isAGroup()) {
-          $handler->groupForm($form, $form_state);
-          $id = $handler->options['group_info']['identifier'];
-        }
-        else {
-          $handler->buildExposedForm($form, $form_state);
-        }
-        if ($info = $handler->exposedInfo()) {
-          $form['#info']["$type-$id"] = $info;
-        }
-      }
-    }
-  }
-
-  $form['actions'] = array('#type' => 'actions');
-  $form['actions']['submit'] = array(
-    // Prevent from showing up in $_GET.
-    '#name' => '',
-    '#type' => 'submit',
-    '#value' => t('Apply'),
-    '#id' => drupal_html_id('edit-submit-' . $view->storage->id()),
-  );
-
-  $form['#action'] = url($view->display_handler->getUrl());
-  $form['#theme'] = $view->buildThemeFunctions('views_exposed_form');
-  $form['#id'] = drupal_clean_css_identifier('views_exposed_form-' . check_plain($view->storage->id()) . '-' . check_plain($display['id']));
-//  $form['#attributes']['class'] = array('views-exposed-form');
-
-  $exposed_form_plugin = $form_state['exposed_form_plugin'];
-  $exposed_form_plugin->exposedFormAlter($form, $form_state);
-
-  // Save the form
-  views_exposed_form_cache($view->storage->id(), $view->current_display, $form);
-
-  return $form;
-}
-
-/**
  * Implement hook_form_alter for the exposed form.
  *
  * Since the exposed form is a GET form, we don't want it to send a wide
@@ -1133,71 +1056,6 @@ function views_form_views_exposed_form_alter(&$form, &$form_state) {
 }
 
 /**
- * Validate handler for exposed filters
- */
-function views_exposed_form_validate(&$form, &$form_state) {
-  foreach (array('field', 'filter') as $type) {
-    $handlers = &$form_state['view']->$type;
-    foreach ($handlers as $key => $handler) {
-      $handlers[$key]->validateExposed($form, $form_state);
-    }
-  }
-  $exposed_form_plugin = $form_state['exposed_form_plugin'];
-  $exposed_form_plugin->exposedFormValidate($form, $form_state);
-}
-
-/**
- * Submit handler for exposed filters
- */
-function views_exposed_form_submit(&$form, &$form_state) {
-  foreach (array('field', 'filter') as $type) {
-    $handlers = &$form_state['view']->$type;
-    foreach ($handlers as $key => $info) {
-      $handlers[$key]->submitExposed($form, $form_state);
-    }
-  }
-  $form_state['view']->exposed_data = $form_state['values'];
-  $form_state['view']->exposed_raw_input = array();
-
-  $exclude = array('submit', 'form_build_id', 'form_id', 'form_token', 'exposed_form_plugin', '', 'reset');
-  $exposed_form_plugin = $form_state['exposed_form_plugin'];
-  $exposed_form_plugin->exposedFormSubmit($form, $form_state, $exclude);
-
-  foreach ($form_state['values'] as $key => $value) {
-    if (!in_array($key, $exclude)) {
-      $form_state['view']->exposed_raw_input[$key] = $value;
-    }
-  }
-}
-
-/**
- * Save the Views exposed form for later use.
- *
- * @param $views_name
- *   String. The views name.
- * @param $display_name
- *   String. The current view display name.
- * @param $form_output
- *   Array (optional). The form structure. Only needed when inserting the value.
- * @return
- *   Array. The form structure, if any. Otherwise, return FALSE.
- */
-function views_exposed_form_cache($views_name, $display_name, $form_output = NULL) {
-  // When running tests for exposed filters, this cache should
-  // be cleared between each test.
-  $views_exposed = &drupal_static(__FUNCTION__);
-
-  // Save the form output
-  if (!empty($form_output)) {
-    $views_exposed[$views_name][$display_name] = $form_output;
-    return;
-  }
-
-  // Return the form output, if any
-  return empty($views_exposed[$views_name][$display_name]) ? FALSE : $views_exposed[$views_name][$display_name];
-}
-
-/**
  * Implements hook_query_TAG_alter().
  *
  * This is the hook_query_alter() for queries tagged by Views and is used to
diff --git a/core/modules/views/views.services.yml b/core/modules/views/views.services.yml
index 201780b..91ecf0a 100644
--- a/core/modules/views/views.services.yml
+++ b/core/modules/views/views.services.yml
@@ -91,3 +91,5 @@ services:
     class: Drupal\views\ViewsAccessCheck
     tags:
       - { name: 'access_check' }
+  views.exposed_form_cache:
+    class: Drupal\views\ExposedFormCache
diff --git a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
index 2374046..6ce61e1 100644
--- a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
+++ b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
@@ -25,7 +25,7 @@ class FormBuilderTest extends UnitTestCase {
   /**
    * The form builder being tested.
    *
-   * @var \Drupal\Core\Form\FormBuilderInterface
+   * @var \Drupal\Core\Form\FormBuilder
    */
   protected $formBuilder;
 
@@ -354,6 +354,48 @@ public function testGetFormWithObject() {
   }
 
   /**
+   * Tests the getForm() method with a class name based form ID.
+   */
+  public function testgetFormWithClassString() {
+    $form_id = '\Drupal\Tests\Core\Form\TestForm';
+    $object = new TestForm();
+    $form = array();
+    $form_state = array();
+    $expected_form = $object->buildForm($form, $form_state);
+
+    $form = $this->formBuilder->getForm($form_id);
+    $this->assertFormElement($expected_form, $form, 'test');
+    $this->assertSame('test_form', $form['#id']);
+  }
+
+  /**
+   * Tests the buildForm() method with a string based form ID.
+   */
+  public function testBuildFormWithString() {
+    $form_id = 'test_form_id';
+    $expected_form = $form_id();
+
+    $form = $this->formBuilder->getForm($form_id);
+    $this->assertFormElement($expected_form, $form, 'test');
+    $this->assertSame($form_id, $form['#id']);
+  }
+
+  /**
+   * Tests the buildForm() method with a class name based form ID.
+   */
+  public function testBuildFormWithClassString() {
+    $form_id = '\Drupal\Tests\Core\Form\TestForm';
+    $object = new TestForm();
+    $form = array();
+    $form_state = array();
+    $expected_form = $object->buildForm($form, $form_state);
+
+    $form = $this->formBuilder->buildForm($form_id, $form_state);
+    $this->assertFormElement($expected_form, $form, 'test');
+    $this->assertSame('test_form', $form['#id']);
+  }
+
+  /**
    * Tests the buildForm() method with a form object.
    */
   public function testBuildFormWithObject() {
@@ -363,7 +405,6 @@ public function testBuildFormWithObject() {
     $form_arg = $this->getMockForm(NULL, $expected_form);
 
     $form_state['build_info']['callback_object'] = $form_arg;
-    $form_state['build_info']['args'] = array();
 
     $form = $this->formBuilder->buildForm($form_id, $form_state);
     $this->assertFormElement($expected_form, $form, 'test');
@@ -388,8 +429,7 @@ public function testBuildFormWithHookForms() {
         ),
       )));
 
-    $form_state['build_info']['args'] = array();
-
+    $form_state = array();
     $form = $this->formBuilder->buildForm($form_id, $form_state);
     $this->assertFormElement($expected_form, $form, 'test');
     $this->assertSame($form_id, $form_state['build_info']['form_id']);
@@ -410,7 +450,6 @@ public function testRebuildForm() {
     // Do an initial build of the form and track the build ID.
     $form_state = array();
     $form_state['build_info']['callback_object'] = $form_arg;
-    $form_state['build_info']['args'] = array();
     $form = $this->formBuilder->buildForm($form_id, $form_state);
     $original_build_id = $form['#build_id'];
 
@@ -615,15 +654,23 @@ public function providerTestGetError() {
   public function testGetCache() {
     $form_id = 'test_form_id';
     $expected_form = $form_id();
+    $expected_form['#token'] = FALSE;
 
-    // FormBuilder::buildForm() will be called 3 times, but the form object will
-    // only be called twice due to caching.
-    $form_arg = $this->getMockForm(NULL, $expected_form, 2);
+    // FormBuilder::buildForm() will be called twice, but the form object will
+    // only be called once due to caching.
+    $form_arg = $this->getMockForm(NULL, $expected_form, 1);
 
-    // The CSRF token and the user authentication are checked each time.
-    $this->csrfToken->expects($this->exactly(3))
+    // The CSRF token is checked each time.
+    $this->csrfToken->expects($this->exactly(2))
       ->method('get')
       ->will($this->returnValue('csrf_token'));
+    // The CSRF token is validated only when retrieving from the cache.
+    $this->csrfToken->expects($this->once())
+      ->method('validate')
+      ->with('csrf_token')
+      ->will($this->returnValue(TRUE));
+    // The user is checked for authentication once for the form building and
+    // twice for each cache set.
     $this->account->expects($this->exactly(3))
       ->method('isAuthenticated')
       ->will($this->returnValue(TRUE));
@@ -631,36 +678,30 @@ public function testGetCache() {
     // Do an initial build of the form and track the build ID.
     $form_state = array();
     $form_state['build_info']['callback_object'] = $form_arg;
-    $form_state['build_info']['args'] = array();
     $form_state['build_info']['files'] = array(array('module' => 'node', 'type' => 'pages.inc'));
     $form_state['cache'] = TRUE;
     $form = $this->formBuilder->buildForm($form_id, $form_state);
 
-    // Rebuild the form, this time setting it up to be cached.
-    $form_state['rebuild'] = TRUE;
-    $form_state['rebuild_info']['copy']['#build_id'] = TRUE;
-    $form_state['input']['form_token'] = $form['#token'];
-    $form_state['input']['form_id'] = $form_id;
-    $form_state['input']['form_build_id'] = $form['#build_id'];
-    $form = $this->formBuilder->buildForm($form_id, $form_state);
-
     $cached_form = $form;
     $cached_form['#cache_token'] = 'csrf_token';
     // The form cache, form_state cache, and CSRF token validation will only be
     // called on the cached form.
     $this->formCache->expects($this->once())
+      ->method('setWithExpire');
+    $this->formCache->expects($this->once())
       ->method('get')
       ->will($this->returnValue($cached_form));
     $this->formStateCache->expects($this->once())
       ->method('get')
       ->will($this->returnValue($form_state));
-    $this->csrfToken->expects($this->once())
-      ->method('validate')
-      ->will($this->returnValue(TRUE));
 
     // The final form build will not trigger any actual form building, but will
     // use the form cache.
+    $form_state['input']['form_id'] = $form_id;
+    $form_state['input']['form_build_id'] = $form['#build_id'];
     $this->formBuilder->buildForm($form_id, $form_state);
+    $errors = $this->formBuilder->getErrors($form_state);
+    $this->assertEmpty($errors);
   }
 
   /**
@@ -682,7 +723,6 @@ public function testSendResponse() {
     // Do an initial build of the form and track the build ID.
     $form_state = array();
     $form_state['build_info']['callback_object'] = $form_arg;
-    $form_state['build_info']['args'] = array();
     $this->formBuilder->buildForm($form_id, $form_state);
   }
 
@@ -855,7 +895,9 @@ public function getFormId() {
     return 'test_form';
   }
 
-  public function buildForm(array $form, array &$form_state) { }
+  public function buildForm(array $form, array &$form_state) {
+    return test_form_id();
+  }
   public function validateForm(array &$form, array &$form_state) { }
   public function submitForm(array &$form, array &$form_state) { }
 }
