Index: wp-includes/admin-bar.php
===================================================================
--- wp-includes/admin-bar.php	(revision 21416)
+++ wp-includes/admin-bar.php	(working copy)
@@ -344,8 +344,8 @@
 	$blue_wp_logo_url = includes_url('images/wpmini-blue.png');
 
 	foreach ( (array) $wp_admin_bar->user->blogs as $blog ) {
-		// @todo Replace with some favicon lookup.
-		//$blavatar = '<img src="' . esc_url( blavatar_url( blavatar_domain( $blog->siteurl ), 'img', 16, $blue_wp_logo_url ) ) . '" alt="Blavatar" width="16" height="16" />';
+		switch_to_blog( $blog->userblog_id );
+
 		$blavatar = '<img src="' . esc_url($blue_wp_logo_url) . '" alt="' . esc_attr__( 'Blavatar' ) . '" width="16" height="16" class="blavatar"/>';
 
 		$blogname = empty( $blog->blogname ) ? $blog->domain : $blog->blogname;
@@ -355,28 +355,28 @@
 			'parent'    => 'my-sites-list',
 			'id'        => $menu_id,
 			'title'     => $blavatar . $blogname,
-			'href'      => get_admin_url( $blog->userblog_id ),
+			'href'      => admin_url(),
 		) );
 
 		$wp_admin_bar->add_menu( array(
 			'parent' => $menu_id,
 			'id'     => $menu_id . '-d',
 			'title'  => __( 'Dashboard' ),
-			'href'   => get_admin_url( $blog->userblog_id ),
+			'href'   => admin_url(),
 		) );
 
-		if ( current_user_can_for_blog( $blog->userblog_id, 'edit_posts' ) ) {
+		if ( current_user_can( 'edit_posts' ) ) {
 			$wp_admin_bar->add_menu( array(
 				'parent' => $menu_id,
 				'id'     => $menu_id . '-n',
 				'title'  => __( 'New Post' ),
-				'href'   => get_admin_url( $blog->userblog_id, 'post-new.php' ),
+				'href'   => admin_url( 'post-new.php' ),
 			) );
 			$wp_admin_bar->add_menu( array(
 				'parent' => $menu_id,
 				'id'     => $menu_id . '-c',
 				'title'  => __( 'Manage Comments' ),
-				'href'   => get_admin_url( $blog->userblog_id, 'edit-comments.php' ),
+				'href'   => admin_url( 'edit-comments.php' ),
 			) );
 		}
 
@@ -384,8 +384,10 @@
 			'parent' => $menu_id,
 			'id'     => $menu_id . '-v',
 			'title'  => __( 'Visit Site' ),
-			'href'   => get_home_url( $blog->userblog_id, '/' ),
+			'href'   => home_url( '/' ),
 		) );
+
+		restore_current_blog();
 	}
 }
 
Index: wp-includes/ms-blogs.php
===================================================================
--- wp-includes/ms-blogs.php	(revision 21416)
+++ wp-includes/ms-blogs.php	(working copy)
@@ -325,72 +325,61 @@
  * @since MU
  *
  * @param int $new_blog The id of the blog you want to switch to. Default: current blog
- * @param bool $validate Whether to check if $new_blog exists before proceeding
+ * @param bool $deprecated Depecreated argument
  * @return bool	True on success, False if the validation failed
  */
-function switch_to_blog( $new_blog, $validate = false ) {
-	global $wpdb, $table_prefix, $blog_id, $switched, $switched_stack, $wp_roles, $wp_object_cache;
+function switch_to_blog( $new_blog, $deprecated = null ) {
+	global $wpdb, $wp_roles;
 
-	if ( empty($new_blog) )
-		$new_blog = $blog_id;
+	if ( empty( $new_blog ) )
+		$new_blog = $GLOBALS['blog_id'];
 
-	if ( $validate && ! get_blog_details( $new_blog ) )
-		return false;
+	$GLOBALS['_wp_switched_stack'][] = $GLOBALS['blog_id'];
 
-	if ( empty($switched_stack) )
-		$switched_stack = array();
-
-	$switched_stack[] = $blog_id;
-
 	/* If we're switching to the same blog id that we're on,
 	* set the right vars, do the associated actions, but skip
 	* the extra unnecessary work */
-	if ( $blog_id == $new_blog ) {
-		do_action( 'switch_blog', $blog_id, $blog_id );
-		$switched = true;
+	if ( $new_blog == $GLOBALS['blog_id'] ) {
+		do_action( 'switch_blog', $new_blog, $new_blog );
+		$GLOBALS['_wp_switched'] = true;
 		return true;
 	}
 
-	$wpdb->set_blog_id($new_blog);
-	$table_prefix = $wpdb->prefix;
-	$prev_blog_id = $blog_id;
-	$blog_id = $new_blog;
+	$wpdb->set_blog_id( $new_blog );
+	$GLOBALS['table_prefix'] = $wpdb->prefix;
+	$prev_blog_id = $GLOBALS['blog_id'];
+	$GLOBALS['blog_id'] = $new_blog;
 
-	if ( is_object( $wp_roles ) ) {
-		$wpdb->suppress_errors();
-		if ( method_exists( $wp_roles ,'_init' ) )
-			$wp_roles->_init();
-		elseif ( method_exists( $wp_roles, '__construct' ) )
-			$wp_roles->__construct();
-		$wpdb->suppress_errors( false );
-	}
-
-	if ( did_action('init') ) {
+	if ( did_action( 'init' ) ) {
+		$wp_roles->reinit();
 		$current_user = wp_get_current_user();
-		if ( is_object( $current_user ) )
-			$current_user->for_blog( $blog_id );
+		$current_user->for_blog( $new_blog );
 	}
 
 	if ( function_exists( 'wp_cache_switch_to_blog' ) ) {
-		wp_cache_switch_to_blog( $blog_id );
+		wp_cache_switch_to_blog( $new_blog );
 	} else {
+		global $wp_object_cache;
+
 		if ( is_object( $wp_object_cache ) && isset( $wp_object_cache->global_groups ) )
 			$global_groups = $wp_object_cache->global_groups;
 		else
 			$global_groups = false;
 	
 		wp_cache_init();
-		if ( function_exists('wp_cache_add_global_groups') ) {
+
+		if ( function_exists( 'wp_cache_add_global_groups' ) ) {
 			if ( is_array( $global_groups ) )
 				wp_cache_add_global_groups( $global_groups );
 			else
 				wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts' ) );
-			wp_cache_add_non_persistent_groups(array( 'comment', 'counts', 'plugins' ));
+			wp_cache_add_non_persistent_groups( array( 'comment', 'counts', 'plugins' ) );
 		}
 	}
 
-	do_action('switch_blog', $blog_id, $prev_blog_id);
-	$switched = true;
+	do_action( 'switch_blog', $new_blog, $prev_blog_id );
+	$GLOBALS['_wp_switched'] = true;
+
 	return true;
 }
 
@@ -403,64 +392,57 @@
  * @return bool True on success, False if we're already on the current blog
  */
 function restore_current_blog() {
-	global $table_prefix, $wpdb, $blog_id, $switched, $switched_stack, $wp_roles, $wp_object_cache;
+	global $wpdb, $wp_roles;
 
-	if ( !$switched )
+	if ( ! $GLOBALS['_wp_switched'] )
 		return false;
 
-	if ( !is_array( $switched_stack ) )
-		return false;
+	$blog = array_pop( $GLOBALS['_wp_switched_stack'] );
 
-	$blog = array_pop( $switched_stack );
-	if ( $blog_id == $blog ) {
+	if ( $GLOBALS['blog_id'] == $blog ) {
 		do_action( 'switch_blog', $blog, $blog );
-		/* If we still have items in the switched stack, consider ourselves still 'switched' */
-		$switched = ( is_array( $switched_stack ) && count( $switched_stack ) > 0 );
+		// If we still have items in the switched stack, consider ourselves still 'switched'
+		$GLOBALS['_wp_switched'] = ! empty( $GLOBALS['_wp_switched_stack'] );
 		return true;
 	}
 
-	$wpdb->set_blog_id($blog);
-	$prev_blog_id = $blog_id;
-	$blog_id = $blog;
-	$table_prefix = $wpdb->prefix;
+	$wpdb->set_blog_id( $blog );
+	$prev_blog_id = $GLOBALS['blog_id'];
+	$GLOBALS['blog_id'] = $blog;
+	$GLOBALS['table_prefix'] = $wpdb->prefix;
 
-	if ( is_object( $wp_roles ) ) {
-		$wpdb->suppress_errors();
-		if ( method_exists( $wp_roles ,'_init' ) )
-			$wp_roles->_init();
-		elseif ( method_exists( $wp_roles, '__construct' ) )
-			$wp_roles->__construct();
-		$wpdb->suppress_errors( false );
-	}
-
-	if ( did_action('init') ) {
+	if ( did_action( 'init' ) ) {
+		$wp_roles->reinit();
 		$current_user = wp_get_current_user();
-		if ( is_object( $current_user ) )
-			$current_user->for_blog( $blog_id );
+		$current_user->for_blog( $blog );
 	}
 
 	if ( function_exists( 'wp_cache_switch_to_blog' ) ) {
-		wp_cache_switch_to_blog( $blog_id );
+		wp_cache_switch_to_blog( $blog );
 	} else {
+		global $wp_object_cache;
+
 		if ( is_object( $wp_object_cache ) && isset( $wp_object_cache->global_groups ) )
 			$global_groups = $wp_object_cache->global_groups;
 		else
 			$global_groups = false;
 	
 		wp_cache_init();
-		if ( function_exists('wp_cache_add_global_groups') ) {
+
+		if ( function_exists( 'wp_cache_add_global_groups' ) ) {
 			if ( is_array( $global_groups ) )
 				wp_cache_add_global_groups( $global_groups );
 			else
 				wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts' ) );
-			wp_cache_add_non_persistent_groups(array( 'comment', 'counts', 'plugins' ));
+			wp_cache_add_non_persistent_groups( array( 'comment', 'counts', 'plugins' ) );
 		}
 	}
 
-	do_action('switch_blog', $blog_id, $prev_blog_id);
+	do_action( 'switch_blog', $blog, $prev_blog_id );
 
-	/* If we still have items in the switched stack, consider ourselves still 'switched' */
-	$switched = ( is_array( $switched_stack ) && count( $switched_stack ) > 0 );
+	// If we still have items in the switched stack, consider ourselves still 'switched'
+	$GLOBALS['_wp_switched'] = ! empty( $GLOBALS['_wp_switched_stack'] );
+
 	return true;
 }
 
Index: wp-includes/capabilities.php
===================================================================
--- wp-includes/capabilities.php	(revision 21416)
+++ wp-includes/capabilities.php	(working copy)
@@ -108,13 +108,43 @@
 
 		$this->role_objects = array();
 		$this->role_names =  array();
-		foreach ( (array) $this->roles as $role => $data ) {
+		foreach ( array_keys( $this->roles ) as $role ) {
 			$this->role_objects[$role] = new WP_Role( $role, $this->roles[$role]['capabilities'] );
 			$this->role_names[$role] = $this->roles[$role]['name'];
 		}
 	}
 
 	/**
+	 * Reinitialize the object
+	 *
+	 * Recreates the role objects. This is typically called only by switch_to_blog()
+	 * after switching wpdb to a new blog ID.
+	 *
+	 * @since 3.5.0
+	 * @access public
+	 */
+	function reinit() {
+		// There is no need to reinit if using the wp_user_roles global.
+		if ( ! $this->use_db )
+			return;
+
+		global $wpdb, $wp_user_roles;
+
+		// Duplicated from _init() to avoid an extra function call.
+		$this->role_key = $wpdb->prefix . 'user_roles';
+		$this->roles = get_option( $this->role_key );
+		if ( empty( $this->roles ) )
+			return;
+
+		$this->role_objects = array();
+		$this->role_names =  array();
+		foreach ( array_keys( $this->roles ) as $role ) {
+			$this->role_objects[$role] = new WP_Role( $role, $this->roles[$role]['capabilities'] );
+			$this->role_names[$role] = $this->roles[$role]['name'];
+		}
+	}
+
+	/**
 	 * Add role name with capabilities to list.
 	 *
 	 * Updates the list of roles, if the role doesn't already exist.
@@ -233,8 +263,7 @@
 	 * @param string $role Role name to look up.
 	 * @return bool
 	 */
-	function is_role( $role )
-	{
+	function is_role( $role ) {
 		return isset( $this->role_names[$role] );
 	}
 }
@@ -1231,21 +1260,21 @@
  * @return bool
  */
 function current_user_can_for_blog( $blog_id, $capability ) {
+	switch_to_blog( $blog_id );
+
 	$current_user = wp_get_current_user();
 
 	if ( empty( $current_user ) )
 		return false;
 
-	// Create new object to avoid stomping the global current_user.
-	$user = new WP_User( $current_user->ID );
-
-	// Set the blog id. @todo add blog id arg to WP_User constructor?
-	$user->for_blog( $blog_id );
-
 	$args = array_slice( func_get_args(), 2 );
 	$args = array_merge( array( $capability ), $args );
 
-	return call_user_func_array( array( &$user, 'has_cap' ), $args );
+	$can = call_user_func_array( array( $current_user, 'has_cap' ), $args );
+
+	restore_current_blog();
+
+	return $can;
 }
 
 /**
Index: wp-includes/ms-settings.php
===================================================================
--- wp-includes/ms-settings.php	(revision 21416)
+++ wp-includes/ms-settings.php	(working copy)
@@ -126,6 +126,8 @@
 $wpdb->set_prefix( $table_prefix, false ); // $table_prefix can be set in sunrise.php
 $wpdb->set_blog_id( $current_blog->blog_id, $current_blog->site_id );
 $table_prefix = $wpdb->get_blog_prefix();
+$_wp_switched_stack = array();
+$_wp_switched = false;
 
 // need to init cache again after blog_id is set
 wp_start_object_cache();
Index: wp-settings.php
===================================================================
--- wp-settings.php	(revision 21416)
+++ wp-settings.php	(working copy)
@@ -252,6 +252,13 @@
  */
 $GLOBALS['wp_widget_factory'] = new WP_Widget_Factory();
 
+/**
+ * WordPress User Roles
+ * @global object $wp_roles
+ * @since 2.0.0
+ */
+$GLOBALS['wp_roles'] = new WP_Roles();
+
 do_action( 'setup_theme' );
 
 // Define the template related constants.
