Index: wp-admin/themes.php
===================================================================
--- wp-admin/themes.php	(revision 10194)
+++ wp-admin/themes.php	(working copy)
@@ -12,9 +12,13 @@
 if ( isset($_GET['action']) ) {
 	check_admin_referer('switch-theme_' . $_GET['template']);
 
-	if ('activate' == $_GET['action']) {
-		switch_theme($_GET['template'], $_GET['stylesheet']);
+	if ( 'activate' == $_GET['action'] ) {
+		wp_redirect( add_query_arg('action', 'theme_activation') );
+		switch_theme($_GET['template'], $_GET['stylesheet']); //Also runs the deactivation functions.
+		exit;
+	} else if ( 'theme_activation' == $_GET['action'] ) {
 		wp_redirect('themes.php?activated=true');
+		run_theme_activation_hook($_GET['template'], $_GET['stylesheet']);
 		exit;
 	}
 }
Index: wp-includes/theme.php
===================================================================
--- wp-includes/theme.php	(revision 10194)
+++ wp-includes/theme.php	(working copy)
@@ -914,6 +914,8 @@
 /**
  * Switches current theme to new template and stylesheet names.
  *
+ * Also runs the theme Deactivation hooks, See run_theme_deactivation_hook()
+ *
  * @since unknown
  * @uses do_action() Calls 'switch_theme' action on updated theme display name.
  *
@@ -921,14 +923,84 @@
  * @param string $stylesheet Stylesheet name.
  */
 function switch_theme($template, $stylesheet) {
+
+	$current_template = get_template();
+	$current_stylsheet = get_stylesheet();
+
 	update_option('template', $template);
 	update_option('stylesheet', $stylesheet);
 	delete_option('current_theme');
 	$theme = get_current_theme();
+
+	run_theme_deactivation_hook($current_template, $current_stylesheet);
+
 	do_action('switch_theme', $theme);
 }
 
 /**
+ * Runs the activation hooks for a newly activated theme
+ *
+ * @since unknown
+ * @uses do_action() Calls 'activate_theme-{theme-slug}' action on template and stylesheet
+ *
+ * @param string $template Template name
+ * @param string $stylesheet Stylesheet name
+ */
+function run_theme_activation_hook($template, $stylesheet) {
+	if ( $stylesheet != $template )
+		do_action('activate_theme-' . $stylesheet);
+	do_action('activate_theme-' . $template);
+}
+
+/**
+ * Runs the deactivation hooks for a disabled theme
+ *
+ * @since unknown
+ * @uses do_action() Calls 'activate_theme-{theme-slug}' action on template and stylesheet
+ *
+ * @param string $template Template name
+ * @param string $stylesheet Stylesheet name
+ */
+function run_theme_deactivation_hook($template, $stylesheet) {
+	if ( $template != $stylesheet )		
+		do_action('deactivate_theme-' . $stylesheet);
+	do_action('deactivate_theme-' . $template);
+}
+
+/**
+ * Set the activation hook for a theme.
+ *
+ * Warning: Must be called from a file directly within the themes root folder, not a subdir
+ *
+ * @since 2.7
+ *
+ * @param string $file Filename of a file inside the themes folder
+ * @param string $function The Activation callback
+ */
+function register_theme_activation_hook($file, $function) {
+	$file = str_replace('\\', '/', $file); //Win32 => unix
+	$theme = preg_replace('|^.*/|', '', dirname($file)); //greedy replace until final folder remainss
+	
+	add_action('activate_theme-' . $theme, $function);
+}
+
+/**
+ * Set the deactivation hook for a theme.
+ *
+ * Warning: Must be called from a file directly within the themes root folder, not a subdir
+ *
+ * @since 2.7
+ *
+ * @param string $file Filename of a file inside the themes folder
+ * @param string $function The Activation callback
+ */
+function register_theme_deactivation_hook($file, $function) {
+	$file = str_replace('\\', '/', $file); //Win32 => unix
+	$theme = preg_replace('|^.*/|', '', dirname($file)); //greedy replace until final folder remainss
+	add_action('deactivate_theme-' . $theme, $function);
+}
+
+/**
  * Checks that current theme files 'index.php' and 'style.css' exists.
  *
  * Does not check the 'default' theme. The 'default' theme should always exist

