diff --git a/core/includes/common.inc b/core/includes/common.inc
index c9913a2..92c8c77 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -6604,9 +6604,6 @@ function drupal_common_theme() {
     'install_page' => array(
       'variables' => array('content' => NULL),
     ),
-    'task_list' => array(
-      'variables' => array('items' => NULL, 'active' => NULL),
-    ),
     'authorize_message' => array(
       'variables' => array('message' => NULL, 'success' => TRUE),
     ),
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 3b69ce3..130ebd2 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -720,7 +720,7 @@ function install_tasks($install_state) {
  * Returns a list of tasks that should be displayed to the end user.
  *
  * The output of this function is a list suitable for sending to
- * theme_task_list().
+ * theme_item_list__tasks().
  *
  * @param $install_state
  *   An array of information about the current installation state.
@@ -729,7 +729,8 @@ function install_tasks($install_state) {
  *   A list of tasks, with keys equal to the machine-readable task name and
  *   values equal to the name that should be displayed.
  *
- * @see theme_task_list()
+ * @see template_preprocess_item_list()
+ * @see theme_item_list()
  */
 function install_tasks_to_display($install_state) {
   $displayed_tasks = array();
@@ -810,7 +811,12 @@ function install_display_output($output, $install_state) {
     // Let the theming function know when every step of the installation has
     // been completed.
     $active_task = $install_state['installation_finished'] ? NULL : $install_state['active_task'];
-    drupal_add_region_content('sidebar_first', theme('task_list', array('items' => install_tasks_to_display($install_state), 'active' => $active_task)));
+    drupal_add_region_content('sidebar_first', theme('item_list__tasks', array(
+      'items' => install_tasks_to_display($install_state),
+      'theme_context' => array(
+        'active_task' => $active_task,
+      ),
+    )));
   }
   print theme('install_page', array('content' => $output));
   exit;
diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 2d1d375..be301bc 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -890,6 +890,19 @@ function theme($hook, $variables = array()) {
     $hook = $candidate;
   }
 
+  // Initialize a predefined theme variable to be used in cpecial preprocess
+  // functions to pass additional data to common theme functions.
+  if (isset($variables['theme_context'])) {
+    $theme_context = $variables['theme_context'];
+  }
+  elseif (isset($variables['#theme']) && isset($variables['#theme_context'])) {
+    $theme_context = $variables['#theme_context'];
+  }
+  else {
+    $theme_context = array();
+  }
+  $theme_context['original_hook'] = $hook;
+
   // If there's no implementation, check for more generic fallbacks. If there's
   // still no implementation, log an error and return an empty string.
   if (!isset($hooks[$hook])) {
@@ -948,6 +961,8 @@ function theme($hook, $variables = array()) {
   elseif (!empty($info['render element'])) {
     $variables += array($info['render element'] => array());
   }
+  // Provide the originally passed in theme conetxt data to process functions.
+  $variables['theme_context'] = $theme_context;
 
   // Invoke the variable processors, if any. The processors may specify
   // alternate suggestions for which hook's template/function to use. If the
@@ -2083,6 +2098,31 @@ function theme_item_list($variables) {
   return $output;
 }
 
+// @todo template_preprocess_item_list__tasks() does not work (yet).
+function template_preprocess_item_list(&$variables) {
+  if ($variables['theme_context']['original_hook'] === 'item_list__tasks') {
+    $variables['type'] = 'ol';
+    $variables['attributes']['class'][] = 'task-list';
+    $t = get_t();
+    $active = isset($variables['theme_context']['active_task']) ? $variables['theme_context']['active_task'] : key($variables['items']);
+    $done = isset($variables['items'][$active]);
+    foreach ($variables['items'] as $key => &$item) {
+      if (!is_array($item)) {
+        $item = array('data' => $item);
+      }
+      if ($key === $active) {
+        $item['class'][] = 'active';
+        $item['data'] .= '<span class="element-invisible">(' . $t('active') . ')</span>';
+        $done = FALSE;
+      }
+      elseif ($done) {
+        $item['class'][] = 'done';
+        $item['data'] .= '<span class="element-invisible">(' . $t('done') . ')</span>';
+      }
+    }
+  }
+}
+
 /**
  * Returns HTML for a "more help" link.
  *
diff --git a/core/includes/theme.maintenance.inc b/core/includes/theme.maintenance.inc
index 4b3e80c..c0e9d7f 100644
--- a/core/includes/theme.maintenance.inc
+++ b/core/includes/theme.maintenance.inc
@@ -96,45 +96,6 @@ function _theme_load_offline_registry($theme, $base_theme = NULL, $theme_engine
 }
 
 /**
- * Returns HTML for a list of maintenance tasks to perform.
- *
- * @param $variables
- *   An associative array containing:
- *   - items: An associative array of maintenance tasks.
- *   - active: The key for the currently active maintenance task.
- *
- * @ingroup themeable
- */
-function theme_task_list($variables) {
-  $t = get_t();
-  $items = $variables['items'];
-  $active = $variables['active'];
-
-  $done = isset($items[$active]) || $active == NULL;
-  $output = '<h2 class="element-invisible">Installation tasks</h2>';
-  $output .= '<ol class="task-list">';
-
-  foreach ($items as $k => $item) {
-    if ($active == $k) {
-      $class = 'active';
-      $status = '(' . $t('active') . ')';
-      $done = FALSE;
-    }
-    else {
-      $class = $done ? 'done' : '';
-      $status = $done ? '(' . $t('done') . ')' : '';
-    }
-    $output .= '<li';
-    $output .= ($class ? ' class="' . $class . '"' : '') . '>';
-    $output .= $item;
-    $output .= ($status ? '<span class="element-invisible">' . $status . '</span>' : '');
-    $output .= '</li>';
-  }
-  $output .= '</ol>';
-  return $output;
-}
-
-/**
  * Returns HTML for the installation page.
  *
  * Note: this function is not themeable.
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 7add837..f409a5f 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -2578,6 +2578,21 @@ function node_page_default() {
       '#suffix' => '</div>',
     );
   }
+  $build['tasks'] = array(
+    '#theme' => 'item_list__tasks',
+    '#title' => t('Installation tasks'),
+    '#items' => array(
+      'foo' => 'Fool me',
+      'bar' => 'Bar me',
+      'baz' => 'Buzz me',
+    ),
+    '#theme_context' => array(
+      'active_task' => 'bar',
+    ),
+    '#attached' => array(
+      'css' => array(drupal_get_path('module', 'system') . '/system.maintenance.css'),
+    ),
+  );
   return $build;
 }
 
diff --git a/core/update.php b/core/update.php
index b8a726d..890f26a 100644
--- a/core/update.php
+++ b/core/update.php
@@ -325,7 +325,12 @@ function update_task_list($active = NULL) {
     'finished' => 'Review log',
   );
 
-  drupal_add_region_content('sidebar_first', theme('task_list', array('items' => $tasks, 'active' => $active)));
+  drupal_add_region_content('sidebar_first', theme('item_list__tasks', array(
+    'items' => $tasks,
+    'theme_context' => array(
+      'active_task' => $active,
+    ),
+  )));
 }
 
 /**
