Index: wp-admin/includes/schema.php
===================================================================
--- wp-admin/includes/schema.php	(revision 8968)
+++ wp-admin/includes/schema.php	(working copy)
@@ -456,6 +456,7 @@
 
 	if ( !empty( $role ) ) {
 		$role->add_cap( 'install_plugins' );
+		$role->add_cap( 'update_themes' );
 	}
 }
 
Index: wp-admin/includes/update.php
===================================================================
--- wp-admin/includes/update.php	(revision 8968)
+++ wp-admin/includes/update.php	(working copy)
@@ -170,7 +170,7 @@
 	// Copy new version of plugin into place.
 	$result = copy_dir($working_dir, $plugins_dir);
 	if ( is_wp_error($result) ) {
-		//$wp_filesystem->delete($working_dir, true); //TODO: Uncomment? This DOES mean that the new files are available in the upgrade folder if it fails.
+		$wp_filesystem->delete($working_dir, true);
 		return $result;
 	}
 
@@ -193,6 +193,127 @@
 	return  $folder . '/' . $pluginfiles[0];
 }
 
+function wp_update_theme($theme, $feedback = '') {
+	global $wp_filesystem;
+
+	if ( !empty($feedback) )
+		add_filter('update_feedback', $feedback);
+
+	// Is an update available?
+	$current = get_option( 'update_themes' );
+	if ( !isset( $current->response[ $theme ] ) )
+		return new WP_Error('up_to_date', __('The theme is at the latest version.'));
+
+	$r = $current->response[ $theme ];
+	
+	$themes = get_themes();
+	foreach ( (array) $themes as $this_theme ) {
+		if ( $this_theme['Stylesheet'] == $theme ) {
+			$theme_directory = preg_replace('!^/themes/!i', '', $this_theme['Stylesheet Dir']);
+			break;
+		}
+	}
+	unset($themes);
+
+	if ( empty($theme_directory) )
+		return new WP_Error('theme_non_existant', __('Theme does not exist.'));
+
+	// Is a filesystem accessor setup?
+	if ( ! $wp_filesystem || ! is_object($wp_filesystem) )
+		WP_Filesystem();
+
+	if ( ! is_object($wp_filesystem) )
+		return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
+
+	if ( $wp_filesystem->errors->get_error_code() )
+		return new WP_Error('fs_error', __('Filesystem error'), $wp_filesystem->errors);
+
+	//Get the base plugin folder
+	$themes_dir = $wp_filesystem->wp_themes_dir();
+	if ( empty($themes_dir) )
+		return new WP_Error('fs_no_themes_dir', __('Unable to locate WordPress Theme directory.'));
+
+	//And the same for the Content directory.
+	$content_dir = $wp_filesystem->wp_content_dir();
+	if( empty($content_dir) )
+		return new WP_Error('fs_no_content_dir', __('Unable to locate WordPress Content directory (wp-content).'));
+
+	$themes_dir = trailingslashit( $themes_dir );
+	$content_dir = trailingslashit( $content_dir );
+
+	if ( empty($r->package) )
+		return new WP_Error('no_package', __('Upgrade package not available.'));
+
+	// Download the package
+	apply_filters('update_feedback', sprintf(__('Downloading update from %s'), $r['package']));
+	$download_file = download_url($r['package']);
+
+	if ( is_wp_error($download_file) )
+		return new WP_Error('download_failed', __('Download failed.'), $download_file->get_error_message());
+
+	$working_dir = $content_dir . 'upgrade/' . basename($theme_directory);
+
+	// Clean up working directory
+	if ( $wp_filesystem->is_dir($working_dir) )
+		$wp_filesystem->delete($working_dir, true);
+
+	apply_filters('update_feedback', __('Unpacking the update'));
+	// Unzip package to working directory
+	$result = unzip_file($download_file, $working_dir);
+
+	// Once extracted, delete the package
+	unlink($download_file);
+
+	if ( is_wp_error($result) ) {
+		$wp_filesystem->delete($working_dir, true);
+		return $result;
+	}
+
+	//TODO: Is theme currently active? If so, set default theme
+	/*
+	if ( is_plugin_active($plugin) ) {
+		//Deactivate the plugin silently, Prevent deactivation hooks from running.
+		apply_filters('update_feedback', __('Deactivating the plugin'));
+		deactivate_plugins($plugin, true);
+	}*/
+
+	// Remove the existing plugin.
+	apply_filters('update_feedback', __('Removing the old version of the theme'));
+	$deleted = $wp_filesystem->delete($themes_dir . $theme_directory, true);
+
+	if ( ! $deleted ) {
+		$wp_filesystem->delete($working_dir, true);
+		return new WP_Error('delete_failed', __('Could not remove the old plugin'));
+	}
+
+	apply_filters('update_feedback', __('Installing the latest version'));
+	// Copy new version of plugin into place.
+	$result = copy_dir($working_dir, $themes_dir);
+	if ( is_wp_error($result) ) {
+		$wp_filesystem->delete($working_dir, true);
+		return $result;
+	}
+
+	//Get a list of the directories in the working directory before we delete it, We need to know the new folder for the plugin
+	//$filelist = array_keys( $wp_filesystem->dirlist($working_dir) );
+
+	// Remove working directory
+	$wp_filesystem->delete($working_dir, true);
+
+	// Force refresh of plugin update information
+	delete_option('update_themes');
+
+	/*if( empty($filelist) )
+		return false; //We couldnt find any files in the working dir, therefor no plugin installed? Failsafe backup.
+
+	$folder = $filelist[0];
+	$plugin = get_plugins('/' . $folder); //Ensure to pass with leading slash
+	$pluginfiles = array_keys($plugin); //Assume the requested plugin is the first in the list
+
+	return  $folder . '/' . $pluginfiles[0];*/
+}
+
+
 function wp_update_core($feedback = '') {
 	global $wp_filesystem;
 
Index: wp-admin/includes/upgrade.php
===================================================================
--- wp-admin/includes/upgrade.php	(revision 8968)
+++ wp-admin/includes/upgrade.php	(working copy)
@@ -210,7 +210,7 @@
 	if ( $wp_current_db_version < 8201 )
 		upgrade_260();
 
-	if ( $wp_current_db_version < 8921 )
+	if ( $wp_current_db_version < 8980 )
 		upgrade_270();
 
 	maybe_disable_automattic_widgets();
@@ -766,7 +766,7 @@
 function upgrade_270() {
 	global $wpdb, $wp_current_db_version;
 
-	if ( $wp_current_db_version < 8530 )
+	if ( $wp_current_db_version < 8980 )
 		populate_roles_270();
 
 	// Update post_date for unpublished posts with empty timestamp
Index: wp-admin/themes.php
===================================================================
--- wp-admin/themes.php	(revision 8968)
+++ wp-admin/themes.php	(working copy)
@@ -59,6 +59,32 @@
 
 $themes = array_slice( $themes, $start, $per_page );
 
+function theme_update_available( $theme ) {
+	static $themes_update;
+	if ( !isset($themes_update) )
+		$themes_update = get_option('update_themes');
+
+	if ( isset($theme->stylesheet) )
+		$stylesheet = $theme->stylesheet;
+	elseif ( isset($theme['Stylesheet']) )
+		$stylesheet = $theme['Stylesheet'];
+	else
+		return false; //No valid info passed.
+
+	if ( isset($themes_update->response[ $stylesheet ]) ) {
+		$update = $themes_update->response[ $stylesheet ];
+		$details_url = add_query_arg(array('TB_iframe' => 'true', 'width' => 1024, 'height' => 800), $update['url']); //Theme browser inside WP? replace this, Also, theme preview JS will override this on the available list.
+		$update_url = wp_nonce_url('update.php?action=upgrade-theme&amp;theme=' . urlencode($stylesheet), 'upgrade-theme_' . $stylesheet);
+
+		if ( ! current_user_can('update_themes') )
+			printf( __('<p>There is a new version of %1$s available. <a href="%2$s" class="thickbox" title="%1$s">View version %3$s Details</a>.</p>'), $ct->name, $details_url, $update['new_version']);
+		else if ( empty($update->package) )
+			printf( __('<p>There is a new version of %1$s available. <a href="%2$s" class="thickbox" title="%1$s">View version %3$s Details</a> <em>automatic upgrade unavailable for this theme</em>.</p>'), $ct->name, $details_url, $update['new_version']);
+		else
+			printf( __('<p>There is a new version of %1$s available. <a href="%2$s" class="thickbox" title="%1$s">View version %3$s Details</a> or <a href="%4$s">upgrade automatically</a>.</p>'), $ct->name, $details_url, $update['new_version'], $update_url );
+	}
+}
+
 ?>
 
 <div class="wrap">
@@ -77,6 +103,8 @@
 <?php if ( $ct->tags ) : ?>
 <p><?php _e('Tags:'); ?> <?php echo join(', ', $ct->tags); ?></p>
 <?php endif; ?>
+<?php theme_update_available($ct); ?>
+
 </div>
 
 <h2><?php _e('Available Themes'); ?></h2>
@@ -141,8 +169,9 @@
 		<p><?php echo $description; ?></p>
 <?php if ( $tags ) : ?>
 		<p><?php _e('Tags:'); ?> <?php echo join(', ', $tags); ?></p>
+<?php endif; ?>
+		<?php theme_update_available( $themes[$theme_name] ); ?>
 		<noscript><p class="themeactions"><a href="<?php echo $preview_link; ?>" title="<?php echo $preview_text; ?>"><?php _e('Preview'); ?></a> <a href="<?php echo $activate_link; ?>" title="<?php echo $activate_text; ?>"><?php _e('Activate'); ?></a></p></noscript>
-<?php endif; ?>
 		<div style="display:none;"><a class="previewlink" href="<?php echo $preview_link; ?>"><?php echo $preview_text; ?></a> <a class="activatelink" href="<?php echo $activate_link; ?>"><?php echo $activate_text; ?></a></div>
 <?php endif; // end if not empty theme_name ?>
 	</td>
Index: wp-admin/update.php
===================================================================
--- wp-admin/update.php	(revision 8968)
+++ wp-admin/update.php	(working copy)
@@ -62,6 +62,57 @@
 }
 
 /**
+ * Theme upgrade display.
+ *
+ * @since 2.5
+ *
+ * @param string $plugin Plugin
+ */
+function do_theme_upgrade($theme) {
+	global $wp_filesystem;
+
+	$url = wp_nonce_url('update.php?action=upgrade-theme&theme=' . urlencode($theme), 'upgrade-plugin_' . urlencode($theme));
+	if ( false === ($credentials = request_filesystem_credentials($url)) )
+		return;
+
+	if ( ! WP_Filesystem($credentials) ) {
+		$error = true;
+		if ( is_object($wp_filesystem) && $wp_filesystem->errors->get_error_code() )
+			$error = $wp_filesystem->errors;
+		request_filesystem_credentials($url, '', $error); //Failed to connect, Error and request again
+		return;
+	}
+
+	echo '<div class="wrap">';
+	echo '<h2>' . __('Upgrade Theme') . '</h2>';
+	if ( $wp_filesystem->errors->get_error_code() ) {
+		foreach ( $wp_filesystem->errors->get_error_messages() as $message )
+			show_message($message);
+		echo '</div>';
+		return;
+	}
+
+	//TODO: Is theme currently active?
+	$was_current = false; //is_plugin_active($plugin); //Check now, It'll be deactivated by the next line if it is
+
+	$result = wp_update_theme($theme, 'show_message');
+
+	if ( is_wp_error($result) ) {
+		show_message($result);
+		show_message( __('Installation Failed') );
+	} else {
+		//Result is the new plugin file relative to WP_PLUGIN_DIR
+		show_message( __('Theme upgraded successfully') );
+		if( $result && $was_current ){
+			show_message(__('Setting theme as Current'));
+			//TODO: Actually set it as active again.
+			//echo '<iframe style="border:0" width="100%" height="170px" src="' . wp_nonce_url('update.php?action=activate-plugin&plugin=' . $result, 'activate-plugin_' . $result) .'"></iframe>';
+		}
+	}
+	echo '</div>';
+}
+
+/**
  * Display upgrade WordPress for downloading latest or upgrading automatically form.
  *
  * @since 2.7
@@ -144,15 +195,17 @@
 
 if ( isset($_GET['action']) ) {
 	$plugin = isset($_GET['plugin']) ? trim($_GET['plugin']) : '';
-
-	if ( 'upgrade-plugin' == $_GET['action'] ) {
+	$theme = isset($_REQUEST['theme']) ? urldecode($_REQUEST['theme']) : '';
+	$action = isset($_GET['action']) ? $_GET['action'] : '';
+	
+	if ( 'upgrade-plugin' == $action ) {
 		check_admin_referer('upgrade-plugin_' . $plugin);
 		$title = __('Upgrade Plugin');
 		$parent_file = 'plugins.php';
 		require_once('admin-header.php');
 		do_plugin_upgrade($plugin);
 		include('admin-footer.php');
-	} elseif ('activate-plugin' == $_GET['action'] ) {
+	} elseif ('activate-plugin' == $action ) {
 		check_admin_referer('activate-plugin_' . $plugin);
 		if( ! isset($_GET['failure']) && ! isset($_GET['success']) ) {
 			wp_redirect( 'update.php?action=activate-plugin&failure=true&plugin=' . $plugin . '&_wpnonce=' . $_GET['_wpnonce'] );
@@ -182,19 +235,26 @@
 			include(WP_PLUGIN_DIR . '/' . $plugin);
 		}
 		echo "</body></html>";
-	} elseif ( 'upgrade-core' == $_GET['action'] ) {
+	} elseif ( 'upgrade-core' == $action ) {
 		$title = __('Upgrade WordPress');
 		$parent_file = 'index.php';
 		require_once('admin-header.php');
 		core_upgrade_preamble();
 		include('admin-footer.php');
-	} elseif ( 'do-core-upgrade' ) {
+	} elseif ( 'do-core-upgrade' == $action ) {
 		check_admin_referer('upgrade-core');
 		$title = __('Upgrade WordPress');
 		$parent_file = 'index.php';
 		require_once('admin-header.php');
 		do_core_upgrade();
 		include('admin-footer.php');
+	} elseif ( 'upgrade-theme' == $action ) {	
+		check_admin_referer('upgrade-theme_' . $theme);
+		$title = __('Upgrade Theme');
+		$parent_file = 'themes.php';
+		require_once('admin-header.php');
+		do_theme_upgrade($theme);
+		include('admin-footer.php');
 	}
 }
 
Index: wp-includes/version.php
===================================================================
--- wp-includes/version.php	(revision 8968)
+++ wp-includes/version.php	(working copy)
@@ -15,6 +15,6 @@
  *
  * @global int $wp_db_version
  */
-$wp_db_version = 8921;
+$wp_db_version = 8980;
 
 ?>

