Index: wp-admin/includes/screen.php
===================================================================
--- wp-admin/includes/screen.php	(revision 21945)
+++ wp-admin/includes/screen.php	(working copy)
@@ -237,6 +237,15 @@
 	/**
 	 * The unique ID of the screen.
 	 *
+	 * @since 3.5.0
+	 * @var string
+	 * @access public
+	 */
+	public $guid = '';
+
+	/**
+	 * The somewhat unique ID of the screen.
+	 *
 	 * @since 3.3.0
 	 * @var string
 	 * @access public
@@ -391,6 +400,68 @@
 		if ( is_a( $hook_name, 'WP_Screen' ) )
 			return $hook_name;
 
+		if ( false !== strpos( $hook_name, ':' ) )
+			$_screen = WP_Screen::get_from_guid( $hook_name );
+		else
+			$_screen = WP_Screen::get_from_hook( $hook_name );
+
+		if ( isset( self::$_registry[ $_screen->id ] ) ) {
+			$screen = self::$_registry[ $_screen->id ];
+			if ( $screen === get_current_screen() )
+				return $screen;
+			unset( $_screen->id );
+		} else {
+			$screen = new WP_Screen();
+		}
+
+		foreach ( get_object_vars( $_screen ) as $property => $value ) {
+			$screen->$property = $value;
+		}
+
+		self::$_registry[ $_screen->id ] = $screen;
+
+		return $screen;
+ 	}
+
+	public static function get_from_guid( $guid ) {
+		$screen = new stdClass;
+
+		// admin:page:arg1:arg2:arg3:...
+		$screen->guid = $guid;
+		$bits = explode( ':', $guid );
+		$screen->in_admin = $bits[0];
+		$screen->is_user    = ( 'user' == $in_admin );
+		$screen->is_network = ( 'network' == $in_admin );
+		$screen->base = $screen->id = $bits[1];
+
+		switch (  $screen->id ) {
+			case 'edit-tags':
+				$screen->taxonomy = $bits[2];
+				$screen->post_type = $bits[3];
+				$screen->id = 'edit-' . $screen->taxonomy;
+				break;
+			case 'edit':
+				$screen->post_type = $bits[2];
+				$screen->id = 'edit-' . $screen->post_type;
+				break;
+			case 'post':
+				$screen->post_type = $bits[2];
+				$screen->action = 'add';
+				break;
+			case 'media':
+			case 'link':
+			case 'user':
+				$screen->action = 'add';
+				break;
+		}
+
+		if ( 'link' == $screen->post_type )
+			$screen->post_type = '';
+
+		return $screen;
+	}
+
+	public static function get_from_hook( $hook_name = '' ) {
 		$post_type = $taxonomy = null;
 		$in_admin = false;
 		$action = '';
@@ -437,7 +508,7 @@
 
 			if ( ! $in_admin )
 				$in_admin = 'site';
-		} else {
+		} elseif ( ! $in_admin ) {
 			if ( defined( 'WP_NETWORK_ADMIN' ) && WP_NETWORK_ADMIN )
 				$in_admin = 'network';
 			elseif ( defined( 'WP_USER_ADMIN' ) && WP_USER_ADMIN )
@@ -508,15 +579,10 @@
 			$base .= '-user';
  		}
 
-		if ( isset( self::$_registry[ $id ] ) ) {
-			$screen = self::$_registry[ $id ];
-			if ( $screen === get_current_screen() )
-				return $screen;
-		} else {
-			$screen = new WP_Screen();
-			$screen->id     = $id;
-		}
+		// @todo create guid
 
+		$screen = new stdClass;
+		$screen->id         = $id;
 		$screen->base       = $base;
 		$screen->action     = $action;
 		$screen->post_type  = (string) $post_type;
@@ -525,10 +591,8 @@
 		$screen->is_network = ( 'network' == $in_admin );
 		$screen->in_admin   = $in_admin;
 
-		self::$_registry[ $id ] = $screen;
-
 		return $screen;
- 	}
+	}
 
 	/**
 	 * Makes the screen object the current screen.
