diff --git a/includes/theme.inc b/includes/theme.inc
index ff54d6e..86b9771 100644
--- a/includes/theme.inc
+++ b/includes/theme.inc
@@ -1246,10 +1246,82 @@ function path_to_theme() {
  *   The functions found, suitable for returning from hook_theme;
  */
 function drupal_find_theme_functions($cache, $prefixes) {
-  $implementations = array();
+  $implementations_grouped = array();
+
   $functions = get_defined_functions();
+  $theme_functions = preg_grep('/^(' . implode(')|(', $prefixes) . ')_/', $functions['user']);
+  $regular_pattern_functions = preg_grep('/__/', $theme_functions);
+
+  $weights = array_flip(array_keys($cache));
+
+  if (count($prefixes) === 1) {
+    $prefix = reset($prefixes);
+    foreach ($regular_pattern_functions as $function) {
+      $pos = 0;
+      while (FALSE !== $pos = strpos($function, '__', $pos + 1)) {
+        $prefix_and_hook = substr($function, 0, $pos);
+        $hook = substr($prefix_and_hook, strlen($prefix) + 1);
+        if (!array_key_exists($hook, $cache)) {
+          continue;
+        }
+        $info = $cache[$hook];
+        if (isset($info['pattern']) && !empty($info['pattern']) && $hook . '__' !== $info['pattern']) {
+          continue;
+        }
+        $weight = $weights[$hook];
+        $arg_name = isset($info['variables']) ? 'variables' : 'render element';
+        $new_hook = substr($function, strlen($prefix) + 1);
+        $implementations_grouped[$weight][$new_hook] = array(
+          'function' => $function,
+          $arg_name => $info[$arg_name],
+          'base hook' => $hook,
+        );
+      }
+    }
+  }
+  else {
+    foreach ($regular_pattern_functions as $function) {
+      $pos = 0;
+      while (FALSE !== $pos = strpos($function, '__', $pos + 1)) {
+        $prefix_and_hook = substr($function, 0, $pos);
+        foreach ($prefixes as $prefix) {
+          if (0 !== strpos($function, $prefix . '_')) {
+            continue;
+          }
+          $hook = substr($prefix_and_hook, strlen($prefix) + 1);
+          if (!array_key_exists($hook, $cache)) {
+            continue;
+          }
+          $info = $cache[$hook];
+          if (isset($info['pattern']) && !empty($info['pattern']) && $hook . '__' !== $info['pattern']) {
+            continue;
+          }
+          $weight = $weights[$hook];
+          $arg_name = isset($info['variables']) ? 'variables' : 'render element';
+          $new_hook = substr($function, strlen($prefix) + 1);
+          $implementations_grouped[$weight][$new_hook] = array(
+            'function' => $function,
+            $arg_name => $info[$arg_name],
+            'base hook' => $hook,
+          );
+        }
+      }
+    }
+  }
 
   foreach ($cache as $hook => $info) {
+    if (!isset($info['pattern'])) {
+      continue;
+    }
+    $pattern = $info['pattern'];
+    if ($hook . '__' === $pattern || empty($pattern)) {
+      continue;
+    }
+    $theme_pattern_functions = preg_grep('/_' . $pattern . '/', $theme_functions);
+    if (array() === $theme_pattern_functions) {
+      continue;
+    }
+    $arg_name = isset($info['variables']) ? 'variables' : 'render element';
     foreach ($prefixes as $prefix) {
       // Find theme functions that implement possible "suggestion" variants of
       // registered theme hooks and add those as new registered theme hooks.
@@ -1262,14 +1334,13 @@ function drupal_find_theme_functions($cache, $prefixes) {
       // refers to a base hook, not to another suggestion, and all suggestions
       // are found using the base hook's pattern, not a pattern from an
       // intermediary suggestion.
-      $pattern = isset($info['pattern']) ? $info['pattern'] : ($hook . '__');
-      if (!isset($info['base hook']) && !empty($pattern)) {
-        $matches = preg_grep('/^' . $prefix . '_' . $pattern . '/', $functions['user']);
+      if (NULL !== $pattern && !isset($info['base hook'])) {
+        $matches = preg_grep('/^' . $prefix . '_' . $pattern . '/', $theme_pattern_functions);
         if ($matches) {
+          $weight = $weights[$hook];
           foreach ($matches as $match) {
             $new_hook = substr($match, strlen($prefix) + 1);
-            $arg_name = isset($info['variables']) ? 'variables' : 'render element';
-            $implementations[$new_hook] = array(
+            $implementations_grouped[$weight][$new_hook] = array(
               'function' => $match,
               $arg_name => $info[$arg_name],
               'base hook' => $hook,
@@ -1277,17 +1348,52 @@ function drupal_find_theme_functions($cache, $prefixes) {
           }
         }
       }
-      // Find theme functions that implement registered theme hooks and include
-      // that in what is returned so that the registry knows that the theme has
-      // this implementation.
-      if (function_exists($prefix . '_' . $hook)) {
-        $implementations[$hook] = array(
-          'function' => $prefix . '_' . $hook,
+    }
+  }
+
+  // Find theme functions that implement registered theme hooks and include
+  // that in what is returned so that the registry knows that the theme has
+  // this implementation.
+  if (count($prefixes) === 1) {
+    $prefix = reset($prefixes);
+    foreach ($theme_functions as $function) {
+      $hook = substr($function, strlen($prefix) + 1);
+      if (!array_key_exists($hook, $cache)) {
+        continue;
+      }
+      $weight = $weights[$hook];
+      $implementations_grouped[$weight][$hook] = array(
+        'function' => $function,
+      );
+    }
+  }
+  else {
+    foreach ($theme_functions as $function) {
+      foreach ($prefixes as $prefix) {
+        if (0 !== strpos($function, $prefix . '_')) {
+          continue;
+        }
+        $hook = substr($function, strlen($prefix) + 1);
+        if (!array_key_exists($hook, $cache)) {
+          continue;
+        }
+        $weight = $weights[$hook];
+        $implementations_grouped[$weight][$hook] = array(
+          'function' => $function,
         );
       }
     }
   }
 
+  ksort($implementations_grouped);
+
+  $implementations = array();
+  foreach ($implementations_grouped as $weight => $weight_implementations) {
+    foreach ($weight_implementations as $hook => $implementation) {
+      $implementations[$hook] = $implementation;
+    }
+  }
+
   return $implementations;
 }
 
