Index: modules/field/field.form.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/field.form.inc,v
retrieving revision 1.4
diff -u -r1.4 field.form.inc
--- modules/field/field.form.inc	18 Feb 2009 14:28:22 -0000	1.4
+++ modules/field/field.form.inc	10 Mar 2009 01:54:58 -0000
@@ -244,7 +244,7 @@
         $items[] = &$element[$key];
       }
     }
-    usort($items, '_field_sort_items_value_helper');
+    drupal_sort_array($items, '_weight,#value');
 
     // Add the items as table rows.
     foreach ($items as $key => $item) {
Index: modules/field/field.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/field.module,v
retrieving revision 1.5
diff -u -r1.5 field.module
--- modules/field/field.module	8 Mar 2009 04:25:04 -0000	1.5
+++ modules/field/field.module	10 Mar 2009 01:54:58 -0000
@@ -255,7 +255,7 @@
  */
 function _field_sort_items($field, $items) {
   if (($field['cardinality'] > 1 || $field['cardinality'] == FIELD_CARDINALITY_UNLIMITED) && isset($items[0]['_weight'])) {
-    usort($items, '_field_sort_items_helper');
+    drupal_sort_array($items, '_weight');
     foreach ($items as $delta => $item) {
       if (is_array($items[$delta])) {
         unset($items[$delta]['_weight']);
@@ -266,31 +266,6 @@
 }
 
 /**
- * Sort function for items order.
- * (copied form element_sort(), which acts on #weight keys)
- */
-function _field_sort_items_helper($a, $b) {
-  $a_weight = (is_array($a) && isset($a['_weight'])) ? $a['_weight'] : 0;
-  $b_weight = (is_array($b) && isset($b['_weight'])) ? $b['_weight'] : 0;
-  if ($a_weight == $b_weight) {
-    return 0;
-  }
-  return ($a_weight < $b_weight) ? -1 : 1;
-}
-
-/**
- * Same as above, using ['_weight']['#value']
- */
-function _field_sort_items_value_helper($a, $b) {
-  $a_weight = (is_array($a) && isset($a['_weight']['#value'])) ? $a['_weight']['#value'] : 0;
-  $b_weight = (is_array($b) && isset($b['_weight']['#value'])) ? $b['_weight']['#value'] : 0;
-  if ($a_weight == $b_weight) {
-    return 0;
-  }
-  return ($a_weight < $b_weight) ? -1 : 1;
-}
-
-/**
  * Registry of available build modes.
  * TODO : move into hook_fieldable_info() ?
  */
@@ -597,4 +572,4 @@
 
 /**
  * @} End of "defgroup field"
- */
\ No newline at end of file
+ */
Index: modules/simpletest/tests/common.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/common.test,v
retrieving revision 1.30
diff -u -r1.30 common.test
--- modules/simpletest/tests/common.test	28 Feb 2009 07:36:06 -0000	1.30
+++ modules/simpletest/tests/common.test	10 Mar 2009 01:54:58 -0000
@@ -580,6 +580,77 @@
   }
 }
 
+/**
+ * Tests for drupal_sort_array().
+ */
+class DrupalSortArrayUnitTestCase extends DrupalWebTestCase {
+  function getInfo() {
+    return array(
+      'name' => t('Array Sorting'),
+      'description' => t('Performs unit tests on drupal_sort_array().'),
+      'group' => t('System'),
+    );
+  }
+
+  /**
+   * Test sorting by weight with a one deep sort.
+   */
+  function testOneDeepKey() {
+    // Build an array with '#weight' set for each element.
+    $elements = array(
+      'fourth' => array(
+        '#weight' => 20,
+      ),
+      'third' => array(
+        '#weight' => 10,
+      ),
+      'second' => array(
+        '#not_weight' => 30,
+      ),
+      'first' => array(
+        '#weight' => -10,
+      ),
+    );
+
+    $sorted_elements = $elements;
+    drupal_sort_array($sorted_elements, '#weight');
+    $this->assertIdentical(array_reverse($elements, TRUE), $sorted_elements, t('One-deep array sorted correctly.'));
+  }
+
+  /**
+   * Test sorting by weight with a two deep sort.
+   */
+  function testTwoDeepKey() {
+    // Build an array with ['weight']['#value'] set for each element.
+    $elements = array(
+      'third' => array(
+        'weight' => array(
+          '#value' => 10,
+        ),
+      ),
+      'second' => array(
+        'weight' => array(
+          '#not_value' => 20,
+        ),
+      ),
+      'first' => array(
+        'weight' => array(
+          '#value' => -10,
+        ),
+      ),
+    );
+
+    // Copy each element in the array by reference to test that
+    // drupal_sort_array() does not modify the elements.
+    $sorted_elements = array();
+    foreach ($elements as $key => &$element) {
+      $sorted_elements[$key] = $element;
+    }
+
+    drupal_sort_array($sorted_elements, 'weight,#value');
+    $this->assertIdentical(array_reverse($elements, TRUE), $sorted_elements, t('Two-deep array sorted correctly.'));
+  }
+}
 
 /**
  * Tests Drupal error and exception handlers.
Index: modules/user/user.pages.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.pages.inc,v
retrieving revision 1.30
diff -u -r1.30 user.pages.inc
--- modules/user/user.pages.inc	26 Feb 2009 07:30:29 -0000	1.30
+++ modules/user/user.pages.inc	10 Mar 2009 01:54:58 -0000
@@ -167,7 +167,7 @@
 function template_preprocess_user_profile(&$variables) {
   $variables['profile'] = array();
   // Sort sections by weight
-  uasort($variables['account']->content, 'element_sort');
+  drupal_sort_array($variables['account']->content, '#weight');
   // Provide keyed variables so themers can print each section independently.
   foreach (element_children($variables['account']->content) as $key) {
     $variables['profile'][$key] = drupal_render($variables['account']->content[$key]);
Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.870
diff -u -r1.870 common.inc
--- includes/common.inc	28 Feb 2009 07:36:06 -0000	1.870
+++ includes/common.inc	10 Mar 2009 01:54:58 -0000
@@ -2583,7 +2583,7 @@
   $embed_suffix = "\n//--><!]]>\n";
 
   // Sort the JavaScript by weight so that it appears in the correct order.
-  uasort($items, 'drupal_sort_weight');
+  drupal_sort_array($items, 'weight');
 
   // Loop through the JavaScript to construct the rendered output.
   foreach ($items as $item) {
@@ -3401,15 +3401,31 @@
 }
 
 /**
- * Function used by uasort to sort structured arrays by weight.
+ * Generic sorting mechanism for arrays.
+ *
+ * @param $array
+ *   The array to sort.
+ * @param $key
+ *   The index to retrieve. Child keys are passed by comma-seperated values ('item,#weight').
  */
-function element_sort($a, $b) {
-  $a_weight = (is_array($a) && isset($a['#weight'])) ? $a['#weight'] : 0;
-  $b_weight = (is_array($b) && isset($b['#weight'])) ? $b['#weight'] : 0;
-  if ($a_weight == $b_weight) {
-    return 0;
+function drupal_sort_array(&$array, $key) {
+  static $sort_functions = array();
+
+  if (!isset($sort_functions[$key])) {
+    $sort_functions[$key] = create_function('$a,$b', '
+      $keys = explode(",","'.$key.'");
+      $a_weight = $a;
+      $b_weight = $b;
+      foreach ($keys as $key) {
+        $a_weight = is_array($a_weight) && isset($a_weight[$key]) ? $a_weight[$key] : 0;
+        $b_weight = is_array($b_weight) && isset($b_weight[$key]) ? $b_weight[$key] : 0;
+      }
+      if ($a_weight == $b_weight) {
+        return 0;
+      }
+      return ($a_weight < $b_weight) ? -1 : 1;');
   }
-  return ($a_weight < $b_weight) ? -1 : 1;
+  return uasort($array, $sort_functions[$key]);
 }
 
 /**
@@ -3510,7 +3526,7 @@
   }
   // Sort the children if necessary.
   if ($sort && $sortable) {
-    uasort($children, 'element_sort');
+    drupal_sort_array($children, '#weight');
     // Put the sorted children back into $elements in the correct order, to
     // preserve sorting if the same element is passed through
     // element_children() twice.
Index: modules/upload/upload.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/upload/upload.module,v
retrieving revision 1.229
diff -u -r1.229 upload.module
--- modules/upload/upload.module	8 Mar 2009 04:25:07 -0000	1.229
+++ modules/upload/upload.module	10 Mar 2009 01:54:58 -0000
@@ -207,7 +207,7 @@
         $microweight += 0.001;
       }
     }
-    uasort($form_state['values']['files'], 'element_sort');
+    drupal_sort_array($form_state['values']['files'], '#weight');
   }
 }
 
