diff --git a/core/includes/form.inc b/core/includes/form.inc
index 1d6b0be..f939e51 100644
--- a/core/includes/form.inc
+++ b/core/includes/form.inc
@@ -735,34 +735,11 @@ function form_set_value($element, $value, &$form_state) {
  *
  * @return
  *   An array with all hierarchical elements flattened to a single array.
+ *
+ * @deprecated as of Drupal 8.0. Use \Drupal::formBuilder()->flattenOptions()
  */
 function form_options_flatten($array) {
-  // Always reset static var when first entering the recursion.
-  drupal_static_reset('_form_options_flatten');
-  return _form_options_flatten($array);
-}
-
-/**
- * Iterates over an array and returns a flat array with duplicate keys removed.
- *
- * This function also handles cases where objects are passed as array values.
- */
-function _form_options_flatten($array) {
-  $return = &drupal_static(__FUNCTION__);
-
-  foreach ($array as $key => $value) {
-    if (is_object($value)) {
-      _form_options_flatten($value->option);
-    }
-    elseif (is_array($value)) {
-      _form_options_flatten($value);
-    }
-    else {
-      $return[$key] = 1;
-    }
-  }
-
-  return $return;
+  return \Drupal::formBuilder()->flattenOptions($array);
 }
 
 /**
diff --git a/core/lib/Drupal/Core/Form/FormBuilder.php b/core/lib/Drupal/Core/Form/FormBuilder.php
index 881c9c2..617fc7f 100644
--- a/core/lib/Drupal/Core/Form/FormBuilder.php
+++ b/core/lib/Drupal/Core/Form/FormBuilder.php
@@ -125,6 +125,13 @@ class FormBuilder implements FormBuilderInterface {
   protected $validatedForms = array();
 
   /**
+   * An array of options used for recursive flattening.
+   *
+   * @var array
+   */
+  protected $flattenedOptions = array();
+
+  /**
    * Constructs a new FormBuilder.
    *
    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
@@ -1005,7 +1012,7 @@ protected function doValidateForm(&$elements, &$form_state, $form_id = NULL) {
 
         if (isset($elements['#options']) && isset($elements['#value'])) {
           if ($elements['#type'] == 'select') {
-            $options = form_options_flatten($elements['#options']);
+            $options = $this->flattenOptions($elements['#options']);
           }
           else {
             $options = $elements['#options'];
@@ -1649,6 +1656,37 @@ public function setValue($element, $value, &$form_state) {
   }
 
   /**
+   * {@inheritdoc}
+   */
+  public function flattenOptions(array $array) {
+    $this->flattenedOptions = array();
+    $this->doFlattenOptions($array);
+    return $this->flattenedOptions;
+  }
+
+  /**
+   * Iterates over an array building a flat array with duplicate keys removed.
+   *
+   * This function also handles cases where objects are passed as array values.
+   *
+   * @param array $array
+   *   The form options array to process.
+   */
+  protected function doFlattenOptions(array $array) {
+    foreach ($array as $key => $value) {
+      if (is_object($value)) {
+        $this->doFlattenOptions($value->option);
+      }
+      elseif (is_array($value)) {
+        $this->doFlattenOptions($value);
+      }
+      else {
+        $this->flattenedOptions[$key] = 1;
+      }
+    }
+  }
+
+  /**
    * Triggers kernel.response and sends a form response.
    *
    * @param \Symfony\Component\HttpFoundation\Response $response
diff --git a/core/lib/Drupal/Core/Form/FormBuilderInterface.php b/core/lib/Drupal/Core/Form/FormBuilderInterface.php
index aa09c41..60a85bb 100644
--- a/core/lib/Drupal/Core/Form/FormBuilderInterface.php
+++ b/core/lib/Drupal/Core/Form/FormBuilderInterface.php
@@ -757,6 +757,21 @@ public function doBuildForm($form_id, &$element, &$form_state);
   public function setValue($element, $value, &$form_state);
 
   /**
+   * Allows PHP array processing of multiple select options with the same value.
+   *
+   * Used for form select elements which need to validate HTML option groups
+   * and multiple options which may return the same value. Associative PHP
+   * arrays cannot handle these structures, since they share a common key.
+   *
+   * @param array $array
+   *   The form options array to process.
+   *
+   * @return array
+   *   An array with all hierarchical elements flattened to a single array.
+   */
+  public function flattenOptions(array $array);
+
+  /**
    * Sets the request object to use.
    *
    * @param \Symfony\Component\HttpFoundation\Request $request
diff --git a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
index f64abb7..208a6ce 100644
--- a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
+++ b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
@@ -415,6 +415,20 @@ public function testSubmitForm() {
 
     $form_state = array();
     $form_state['values']['test'] = $this->randomName();
+    $form_state['values']['options'] = array('foo');
+    $this->formBuilder->submitForm($form_arg, $form_state);
+    $errors = $this->formBuilder->getErrors();
+    $this->assertNull($errors);
+
+    $form_state = array();
+    $form_state['values']['test'] = $this->randomName();
+    $form_state['values']['options'] = array('foo', 'baz');
+    $this->formBuilder->submitForm($form_arg, $form_state);
+    $errors = $this->formBuilder->getErrors();
+    $this->assertNotEmpty($errors['options']);
+
+    $form_state = array();
+    $form_state['values']['test'] = $this->randomName();
     $form_state['values']['options'] = $this->randomName();
     $form_state['values']['op'] = 'Submit';
     $this->formBuilder->submitForm($form_arg, $form_state);
@@ -423,6 +437,43 @@ public function testSubmitForm() {
   }
 
   /**
+   * Tests the flattenOptions() method.
+   *
+   * @dataProvider providerTestFlattenOptions
+   */
+  public function testFlattenOptions($options) {
+    $expected_form = test_form_id();
+    $expected_form['select']['#required'] = TRUE;
+    $expected_form['select']['#options'] = $options;
+
+    $form_arg = $this->getMock('Drupal\Core\Form\FormInterface');
+    $form_arg->expects($this->any())
+      ->method('buildForm')
+      ->will($this->returnValue($expected_form));
+
+    $form_state = array();
+    $form_state['values']['select'] = 'foo';
+    $this->formBuilder->submitForm($form_arg, $form_state);
+    $errors = $this->formBuilder->getErrors();
+    $this->assertNull($errors);
+  }
+
+  /**
+   * Provides test data for the flattenOptions() method.
+   *
+   * @return array
+   */
+  public function providerTestFlattenOptions() {
+    $object = new \stdClass();
+    $object->option = array('foo' => 'foo');
+    return array(
+      array(array('foo' => 'foo')),
+      array(array(array('foo' => 'foo'))),
+      array(array($object)),
+    );
+  }
+
+  /**
    * Tests the getCache() method.
    */
   public function testGetCache() {
@@ -555,6 +606,11 @@ protected function getElementInfo($type) {
     $types['value'] = array(
       '#input' => TRUE,
     );
+    $types['select'] = array(
+      '#input' => TRUE,
+      '#multiple' => FALSE,
+      '#empty_value' => '',
+    );
     $types['radios'] = array(
       '#input' => TRUE,
     );
@@ -658,6 +714,13 @@ function test_form_id() {
       '#type' => 'textfield',
       '#title' => 'Test',
     );
+    $form['select'] = array(
+      '#type' => 'select',
+      '#options' => array(
+        'foo' => 'foo',
+        'bar' => 'bar',
+      ),
+    );
     $form['options'] = array(
       '#type' => 'radios',
       '#options' => array(
