Index: wp-admin/widgets.php
===================================================================
--- wp-admin/widgets.php	(revision 18555)
+++ wp-admin/widgets.php	(working copy)
@@ -62,73 +62,6 @@
 if ( empty( $sidebars_widgets ) )
 	$sidebars_widgets = wp_get_widget_defaults();
 
-// look for "lost" widgets, this has to run at least on each theme change
-function retrieve_widgets() {
-	global $wp_registered_widget_updates, $wp_registered_sidebars, $sidebars_widgets, $wp_registered_widgets;
-
-	$_sidebars_widgets = array();
-	$sidebars = array_keys($wp_registered_sidebars);
-
-	unset( $sidebars_widgets['array_version'] );
-
-	$old = array_keys($sidebars_widgets);
-	sort($old);
-	sort($sidebars);
-
-	if ( $old == $sidebars )
-		return;
-
-	// Move the known-good ones first
-	foreach ( $sidebars as $id ) {
-		if ( array_key_exists( $id, $sidebars_widgets ) ) {
-			$_sidebars_widgets[$id] = $sidebars_widgets[$id];
-			unset($sidebars_widgets[$id], $sidebars[$id]);
-		}
-	}
-
-	// if new theme has less sidebars than the old theme
-	if ( !empty($sidebars_widgets) ) {
-		foreach ( $sidebars_widgets as $lost => $val ) {
-			if ( is_array($val) )
-				$_sidebars_widgets['wp_inactive_widgets'] = array_merge( (array) $_sidebars_widgets['wp_inactive_widgets'], $val );
-		}
-	}
-
-	// discard invalid, theme-specific widgets from sidebars
-	$shown_widgets = array();
-	foreach ( $_sidebars_widgets as $sidebar => $widgets ) {
-		if ( !is_array($widgets) )
-			continue;
-
-		$_widgets = array();
-		foreach ( $widgets as $widget ) {
-			if ( isset($wp_registered_widgets[$widget]) )
-				$_widgets[] = $widget;
-		}
-		$_sidebars_widgets[$sidebar] = $_widgets;
-		$shown_widgets = array_merge($shown_widgets, $_widgets);
-	}
-
-	$sidebars_widgets = $_sidebars_widgets;
-	unset($_sidebars_widgets, $_widgets);
-
-	// find hidden/lost multi-widget instances
-	$lost_widgets = array();
-	foreach ( $wp_registered_widgets as $key => $val ) {
-		if ( in_array($key, $shown_widgets, true) )
-			continue;
-
-		$number = preg_replace('/.+?-([0-9]+)$/', '$1', $key);
-
-		if ( 2 > (int) $number )
-			continue;
-
-		$lost_widgets[] = $key;
-	}
-
-	$sidebars_widgets['wp_inactive_widgets'] = array_merge($lost_widgets, (array) $sidebars_widgets['wp_inactive_widgets']);
-	wp_set_sidebars_widgets($sidebars_widgets);
-}
 retrieve_widgets();
 
 if ( count($wp_registered_sidebars) == 1 ) {
Index: wp-includes/default-filters.php
===================================================================
--- wp-includes/default-filters.php	(revision 18555)
+++ wp-includes/default-filters.php	(working copy)
@@ -215,6 +215,7 @@
 add_action( 'wp_footer',           'wp_print_footer_scripts'              );
 add_action( 'wp_head',             'wp_shortlink_wp_head',          10, 0 );
 add_action( 'template_redirect',   'wp_shortlink_header',           11, 0 );
+add_action( 'init',                'check_theme_switched',          99    );
 
 if ( isset( $_GET['replytocom'] ) )
     add_filter( 'pre_option_blog_public', '__return_zero' );
Index: wp-includes/theme.php
===================================================================
--- wp-includes/theme.php	(revision 18555)
+++ wp-includes/theme.php	(working copy)
@@ -1260,7 +1260,8 @@
 		$default_theme_mods = (array) get_option( "mods_$theme" );
 		add_option( "theme_mods_$stylesheet", $default_theme_mods );
 	}
-	do_action('switch_theme', $theme);
+	update_option( 'theme_switched', 'true' );
+	do_action( 'switch_theme', $theme );
 }
 
 /**
Index: wp-includes/widgets.php
===================================================================
--- wp-includes/widgets.php	(revision 18555)
+++ wp-includes/widgets.php	(working copy)
@@ -1055,30 +1055,7 @@
 				unset($_sidebars_widgets);
 
 			case 2 :
-				$sidebars = array_keys( $wp_registered_sidebars );
-				if ( !empty( $sidebars ) ) {
-					// Move the known-good ones first
-					foreach ( (array) $sidebars as $id ) {
-						if ( array_key_exists( $id, $sidebars_widgets ) ) {
-							$_sidebars_widgets[$id] = $sidebars_widgets[$id];
-							unset($sidebars_widgets[$id], $sidebars[$id]);
-						}
-					}
-
-					// move the rest to wp_inactive_widgets
-					if ( !isset($_sidebars_widgets['wp_inactive_widgets']) )
-						$_sidebars_widgets['wp_inactive_widgets'] = array();
-
-					if ( !empty($sidebars_widgets) ) {
-						foreach ( $sidebars_widgets as $lost => $val ) {
-							if ( is_array($val) )
-								$_sidebars_widgets['wp_inactive_widgets'] = array_merge( (array) $_sidebars_widgets['wp_inactive_widgets'], $val );
-						}
-					}
-
-					$sidebars_widgets = $_sidebars_widgets;
-					unset($_sidebars_widgets);
-				}
+				$sidebars_widgets = retrieve_widgets();
 		}
 	}
 
@@ -1215,3 +1192,80 @@
 function _get_widget_id_base($id) {
 	return preg_replace( '/-[0-9]+$/', '', $id );
 }
+
+function check_theme_switched() {
+	if ( get_option( 'theme_switched' ) ) {
+		retrieve_widgets();
+		update_option( 'theme_switched', false );
+	}
+}
+// look for "lost" widgets, this has to run at least on each theme change
+function retrieve_widgets() {
+	global $wp_registered_widget_updates, $wp_registered_sidebars, $sidebars_widgets, $wp_registered_widgets;
+
+	if ( ! is_array( $sidebars_widgets ) )
+		$sidebars_widgets = wp_get_sidebars_widgets();
+
+	$sidebars = array_keys($wp_registered_sidebars);
+
+	unset( $sidebars_widgets['array_version'] );
+
+	$old = array_keys($sidebars_widgets);
+	sort($old);
+	sort($sidebars);
+
+	if ( $old == $sidebars )
+		return;
+
+
+	$_sidebars_widgets = array(
+		'wp_inactive_widgets' => $sidebars_widgets['wp_inactive_widgets']
+	);
+	unset( $sidebars_widgets['wp_inactive_widgets'] );
+	foreach ( $wp_registered_sidebars as $id => $settings ) {
+		if ( empty( $first_id ) )
+			$first_id = $id;
+		if ( ! empty( $sidebars_widgets ) )
+			$_sidebars_widgets[$id] = array_shift( $sidebars_widgets );
+	}
+	if ( ! empty( $sidebars_widgets ) ){
+		foreach( $sidebars_widgets as $leftover_sidebar )
+			$_sidebars_widgets[$first_id] = array_merge( (array) $_sidebars_widgets[$first_id], $leftover_sidebar );
+	}
+
+	// discard invalid, theme-specific widgets from sidebars
+	$shown_widgets = array();
+	foreach ( $_sidebars_widgets as $sidebar => $widgets ) {
+		if ( !is_array($widgets) )
+			continue;
+
+		$_widgets = array();
+		foreach ( $widgets as $widget ) {
+			if ( isset($wp_registered_widgets[$widget]) )
+				$_widgets[] = $widget;
+		}
+		$_sidebars_widgets[$sidebar] = $_widgets;
+		$shown_widgets = array_merge($shown_widgets, $_widgets);
+	}
+
+	$sidebars_widgets = $_sidebars_widgets;
+	unset($_sidebars_widgets, $_widgets);
+
+	// find hidden/lost multi-widget instances
+	$lost_widgets = array();
+	foreach ( $wp_registered_widgets as $key => $val ) {
+		if ( in_array($key, $shown_widgets, true) )
+			continue;
+
+		$number = preg_replace('/.+?-([0-9]+)$/', '$1', $key);
+
+		if ( 2 > (int) $number )
+			continue;
+
+		$lost_widgets[] = $key;
+	}
+
+	$sidebars_widgets['wp_inactive_widgets'] = array_merge($lost_widgets, (array) $sidebars_widgets['wp_inactive_widgets']);
+	wp_set_sidebars_widgets($sidebars_widgets);
+	return $sidebars_widgets;
+}
