diff --git a/includes/common.inc b/includes/common.inc
index c1dc6f8f24fbbe74da6c5ec3db749d552d77cd26..7b97fe67d19fe56c5e2980b5457bd7b011c33200 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -3493,11 +3493,19 @@ function element_children(&$elements, $sort = FALSE) {
       }
     }
   }
-  // Sort the element if necessary.
+  // Sort the children if necessary.
   if ($sort && $sortable) {
     uasort($children, 'element_sort');
+    // Put the sorted children back into $elements in the correct order, to
+    // preserve sorting if the same element is passed through
+    // element_children() twice.
+    foreach ($children as $key => $child) {
+      unset($elements[$key]);
+      $elements[$key] = $child;
+    }
+    $elements['#sorted'] = TRUE;
   }
-  $elements['#sorted'] = TRUE;
+
   return array_keys($children);
 }
 
diff --git a/modules/simpletest/tests/common.test b/modules/simpletest/tests/common.test
index 209b4503d16b8e00dd5b144ecb95cfd777970042..3aa248e6baea98b94f277cdb801847cc149d5baf 100644
--- a/modules/simpletest/tests/common.test
+++ b/modules/simpletest/tests/common.test
@@ -542,7 +542,15 @@ class DrupalRenderUnitTestCase extends DrupalWebTestCase {
     // Confirm that the $elements array has '#sorted' set to TRUE.
     $this->assertTrue($elements['#sorted'], t("'#sorted' => TRUE was added to the array"));
 
-    // Now the same array structure, but with #sorted set to TRUE.
+    // Pass $elements through element_children() and ensure it remains
+    // sorted in the correct order. drupal_render() will return an empty string
+    // if used on the same array in the same request.
+    $children = element_children($elements);
+    $this->assertTrue(array_shift($children) == 'first', t('Child found in the correct order.'));
+    $this->assertTrue(array_shift($children) == 'second', t('Child found in the correct order.'));
+
+
+    // The same array structure again, but with #sorted set to TRUE.
     $elements = array(
       'second' => array(
         '#weight' => 10,