Index: wp-admin/includes/theme-install.php
===================================================================
--- wp-admin/includes/theme-install.php	(revision 14982)
+++ wp-admin/includes/theme-install.php	(working copy)
@@ -57,8 +57,10 @@
 			$res = new WP_Error('themes_api_failed', __('An Unexpected HTTP Error occured during the API request.</p> <p><a href="?" onclick="document.location.reload(); return false;">Try again</a>'), $request->get_error_message() );
 		} else {
 			$res = unserialize($request['body']);
-			if ( ! $res )
-			$res = new WP_Error('themes_api_failed', __('An unknown error occured'), $request['body']);
+			if ( false === $res )
+				$res = new WP_Error('themes_api_failed', __('An unknown error occured'), $request['body']);
+			elseif ( null === $res )
+				$res = new WP_Error('themes_theme_404', __('The requested Theme could not be found in the WordPress Themes Directory.'));
 		}
 	}
 	//var_dump(array($args, $res));
@@ -340,20 +342,6 @@
 </div>
 </div>
 <?php }
-	/*
-	 object(stdClass)[59]
-	 public 'name' => string 'Magazine Basic' (length=14)
-	 public 'slug' => string 'magazine-basic' (length=14)
-	 public 'version' => string '1.1' (length=3)
-	 public 'author' => string 'tinkerpriest' (length=12)
-	 public 'preview_url' => string 'http://wp-themes.com/?magazine-basic' (length=36)
-	 public 'screenshot_url' => string 'http://wp-themes.com/wp-content/themes/magazine-basic/screenshot.png' (length=68)
-	 public 'rating' => float 80
-	 public 'num_ratings' => int 1
-	 public 'homepage' => string 'http://wordpress.org/extend/themes/magazine-basic' (length=49)
-	 public 'description' => string 'A basic magazine style layout with a fully customizable layout through a backend interface. Designed by <a href="http://bavotasan.com">c.bavota</a> of <a href="http://tinkerpriestmedia.com">Tinker Priest Media</a>.' (length=214)
-	 public 'download_link' => string 'http://wordpress.org/extend/themes/download/magazine-basic.1.1.zip' (length=66)
-	 */
 }
 
 /**
Index: wp-admin/themes.php
===================================================================
--- wp-admin/themes.php	(revision 14984)
+++ wp-admin/themes.php	(working copy)
@@ -257,6 +257,7 @@
 	<tr>
 		<th><?php _e('Name'); ?></th>
 		<th><?php _e('Description'); ?></th>
+		<th><?php _e('Actions'); ?></th>
 	</tr>
 <?php
 	$theme = '';
@@ -267,12 +268,25 @@
 	foreach ($theme_names as $theme_name) {
 		$title = $broken_themes[$theme_name]['Title'];
 		$description = $broken_themes[$theme_name]['Description'];
+		$stylesheet = $broken_themes[$theme_name]['Name'];
+		$missing_parent = (isset($broken_themes[$theme_name]['error']) && 'no_parent' == $broken_themes[$theme_name]['error']) ? $broken_themes[$theme_name]['parent'] : false;
 
+		$actions = array();
+		if ( current_user_can('delete_themes') )
+			$actions['delete'] = '<a class="submitdelete deletion" href="' . wp_nonce_url("themes.php?action=delete&amp;template=$stylesheet", 'delete-theme_' . $stylesheet) . '" onclick="' . "return confirm('" . esc_js(sprintf( __("You are about to delete this theme '%s'\n  'Cancel' to stop, 'OK' to delete."), $theme_name )) . "');" . '">' . __('Delete') . '</a>';
+
+		if ( current_user_can('install_themes') && !empty($missing_parent) )
+			$actions['install'] = '<a href="' . admin_url('theme-install.php?tab=theme-information&amp;theme=' . urlencode($missing_parent) . '&amp;TB_iframe=true&amp;tbWidth=500&amp;tbHeight=385') . '" class="thickbox thickbox-preview">' . __('Install Parent Theme') . '</a>';
+
+		$actions = apply_filters('broken_theme_action_links', $actions, $broken_themes[$theme_name]);
+		$actions = implode ( ' | ', $actions );
+
 		$theme = ('class="alternate"' == $theme) ? '' : 'class="alternate"';
 		echo "
 		<tr $theme>
 			 <td>$title</td>
 			 <td>$description</td>
+			 <td style='white-space:nowrap;'>$actions</td>
 		</tr>";
 	}
 ?>
