Index: mail/message-list.h
===================================================================
--- mail/message-list.h	(revision 35634)
+++ mail/message-list.h	(working copy)
@@ -113,6 +113,10 @@ struct _MessageList {
 	/* Current search string, or %NULL */
 	char *search;
 
+	/* which message uid should be left in the list even not in a search after rebuild;
+	   rebuild will clear the value to NULL */
+	char *ensure_uid;
+
 	/* are we regenerating the message_list because set_folder was just called? */
 	guint just_set_folder : 1;
 
@@ -220,6 +224,7 @@ void           message_list_set_threaded
 
 void	       message_list_set_hidedeleted (MessageList *ml, gboolean hidedeleted);
 void	       message_list_set_search (MessageList *ml, const char *search);
+void	       message_list_ensure_message (MessageList *ml, const char *uid);
 
 void           message_list_save_state (MessageList *ml);
 
Index: mail/ChangeLog
===================================================================
--- mail/ChangeLog	(revision 35634)
+++ mail/ChangeLog	(working copy)
@@ -1,3 +1,15 @@
+2008-06-14  Milan Crha  <mcrha@redhat.com>
+
+	** Fix for bug #467892
+
+	* message-list.h: (struct _MessageList), (message_list_ensure_message):
+	* message-list.c: (message_list_init), (message_list_finalise),
+	(message_list_ensure_message), (regen_list_exec), (regen_list_done):
+	Be able to set a message uid to keep in a list after regeneration.
+	* em-folder-view.c: (em_folder_view_open_selected):
+	Inherit search criteria and ensure keeping the selected message
+	in the view even it may not belong to the filter anymore.
+
 2008-06-13  Milan Crha  <mcrha@redhat.com>
 
 	** Fix for bug #337160
Index: mail/em-folder-view.c
===================================================================
--- mail/em-folder-view.c	(revision 35634)
+++ mail/em-folder-view.c	(working copy)
@@ -559,8 +559,9 @@ em_folder_view_open_selected(EMFolderVie
 
 		emmb = (EMMessageBrowser *)em_message_browser_window_new();
 		message_list_set_threaded(((EMFolderView *)emmb)->list, emfv->list->threaded);
-		/* do not inherit search filter, because it can hide actual message for some filters */
-		/*message_list_set_search(((EMFolderView *)emmb)->list, emfv->list->search);*/
+		/* always keep actual message in a list view, even it doesn't belong to the filter anymore */
+		message_list_ensure_message (((EMFolderView *)emmb)->list, views->pdata[i]);
+		message_list_set_search (((EMFolderView *)emmb)->list, emfv->list->search);
 		em_folder_view_set_hide_deleted((EMFolderView *)emmb, emfv->hide_deleted);
 		/* FIXME: session needs to be passed easier than this */
 		em_format_set_session((EMFormat *)((EMFolderView *)emmb)->preview, ((EMFormat *)emfv->preview)->session);
Index: mail/message-list.c
===================================================================
--- mail/message-list.c	(revision 35634)
+++ mail/message-list.c	(working copy)
@@ -2159,6 +2159,7 @@ message_list_init (MessageList *message_
 	message_list->hide_after = ML_HIDE_NONE_END;
 
 	message_list->search = NULL;
+	message_list->ensure_uid = NULL;
 
 	message_list->hide_lock = g_mutex_new();
 
@@ -2260,6 +2261,7 @@ message_list_finalise (GObject *object)
 	}
 
 	g_free(message_list->search);
+	g_free(message_list->ensure_uid);
 	g_free(message_list->frozen_search);
 	g_free(message_list->cursor_uid);
 
@@ -3573,6 +3575,16 @@ message_list_set_search (MessageList *ml
 	}
 }
 
+/* will ensure that the message with UID uid will be in the message list after the next rebuild */
+void
+message_list_ensure_message (MessageList *ml, const char *uid)
+{
+	g_return_if_fail (ml != NULL);
+
+	g_free (ml->ensure_uid);
+	ml->ensure_uid = g_strdup (uid);
+}
+
 /* returns the number of messages displayable *after* expression hiding has taken place */
 unsigned int
 message_list_length (MessageList *ml)
@@ -3887,15 +3899,21 @@ regen_list_exec (struct _regen_list_msg 
 		/* If m->changes is not NULL, then it means we are called from folder_changed event,
 		   thus we will keep the selected message to be sure it doesn't disappear because
 		   it no longer belong to our search filter. */
-		if (m->changes && m->ml->search && m->ml->cursor_uid && uids) {
+		if (uids && m->ml->search && ((m->changes && m->ml->cursor_uid) || m->ml->ensure_uid)) {
+			const char *looking_for = m->ml->cursor_uid;
+
+			/* ensure_uid has precedence of cursor_uid */
+			if (m->ml->ensure_uid)
+				looking_for = m->ml->ensure_uid;
+
 			for (i = 0; i < uids->len; i++) {
-				if (g_str_equal (m->ml->cursor_uid, uids->pdata [i]))
+				if (g_str_equal (looking_for, uids->pdata [i]))
 					break;
 			}
 
 			/* cursor_uid has been filtered out */
 			if (i == uids->len) {
-				gboolean was_deleted = (camel_folder_get_message_flags (m->folder, m->ml->cursor_uid) & CAMEL_MESSAGE_DELETED) != 0;
+				gboolean was_deleted = (camel_folder_get_message_flags (m->folder, looking_for) & CAMEL_MESSAGE_DELETED) != 0;
 
 				/* I would really like to check for CAMEL_MESSAGE_FOLDER_FLAGGED on a message,
 				   so I would know whether it was changed locally, and then just check the changes
@@ -3904,7 +3922,7 @@ regen_list_exec (struct _regen_list_msg 
 				   on the flag whether we can view deleted messages or not. */
 
 				if (!was_deleted || (was_deleted && !m->hidedel))
-					g_ptr_array_add (uids, g_strdup (m->ml->cursor_uid));
+					g_ptr_array_add (uids, g_strdup (looking_for));
 			}
 		}
 	}
@@ -4037,6 +4055,11 @@ regen_list_done (struct _regen_list_msg 
 	if (m->ml->priv->destroyed)
 		return;
 
+	if (m->ml->ensure_uid) {
+		g_free (m->ml->ensure_uid);
+		m->ml->ensure_uid = NULL;
+	}
+
 	if (!m->complete)
 		return;
 
