diff -up -ru composer.orig/e-msg-composer.c composer/e-msg-composer.c
--- composer.orig/e-msg-composer.c	2008-02-25 05:52:12.000000000 +0100
+++ composer/e-msg-composer.c	2008-03-28 09:22:51.000000000 +0100
@@ -154,6 +154,17 @@ struct _EMsgComposerClass {
 };
 
 
+struct _EMsgComposerSaveState {
+	guint32 has_changed : 1;
+	guint32 had_undo    : 1;
+};
+
+typedef enum {
+	STATE_SAVE,
+	STATE_AUTOSAVE,
+	STATE_LAST
+} _EMsgComposerState;
+
 struct _EMsgComposerPrivate {
 
 
@@ -208,8 +219,8 @@ struct _EMsgComposerPrivate {
 	guint32 view_subject           : 1;
 	guint32 request_receipt        : 1;
 	guint32 set_priority	       : 1;
-	guint32 has_changed            : 1;
-	guint32 autosaved              : 1;
+
+	struct _EMsgComposerSaveState state[STATE_LAST];
 
 	guint32 mode_post              : 1;
 
@@ -1404,6 +1415,43 @@ set_editor_text(EMsgComposer *composer, 
 		e_msg_composer_show_sig_file (composer);
 }
 
+static void
+e_msg_composer_do_unset_changed (EMsgComposer *composer, _EMsgComposerState state)
+{
+	CORBA_Environment ev;
+	EMsgComposerPrivate *p = composer->priv;
+
+	if (state >= STATE_LAST)
+		return;
+
+	CORBA_exception_init (&ev);
+	p->state[state].had_undo = GNOME_GtkHTML_Editor_Engine_hasUndo (p->eeditor_engine, &ev);
+	CORBA_exception_free (&ev);
+
+	p->state[state].has_changed = FALSE;
+}
+
+static gboolean
+e_msg_composer_is_dirty (EMsgComposer *composer, _EMsgComposerState state)
+{
+	CORBA_Environment ev;
+	gboolean rv;
+	EMsgComposerPrivate *p = composer->priv;
+
+	if (state >= STATE_LAST || p->state[state].has_changed)
+		return TRUE;
+
+	CORBA_exception_init (&ev);
+	if (GNOME_GtkHTML_Editor_Engine_hasUndo (p->eeditor_engine, &ev))
+		rv = !p->state[state].had_undo ||
+		     !GNOME_GtkHTML_Editor_Engine_runCommand (p->eeditor_engine, "is-saved", &ev);
+	else
+		rv = p->state[state].had_undo;
+	CORBA_exception_free (&ev);
+
+	return rv;
+}
+
 /* Commands.  */
 
 static void
@@ -1452,8 +1500,12 @@ save (EMsgComposer *composer, const char
 		e_error_run((GtkWindow *)composer, E_ERROR_NO_SAVE_FILE,
 			    filename, _("Unknown reason"));
 	} else {
+		gboolean dirty_autosave = e_msg_composer_is_dirty (composer, STATE_AUTOSAVE);
 		GNOME_GtkHTML_Editor_Engine_runCommand (p->eeditor_engine, "saved", &ev);
-		e_msg_composer_unset_autosaved (composer);
+		e_msg_composer_do_unset_changed (composer, STATE_SAVE);
+		/* Restore autosave state */
+		if (dirty_autosave)
+			p->state[STATE_AUTOSAVE].has_changed = TRUE;
 	}
 	CORBA_exception_free (&ev);
 }
@@ -1513,7 +1565,7 @@ autosave_save_draft (EMsgComposer *compo
 	int fd, camelfd;
 	gboolean success = TRUE;
 
-	if (!e_msg_composer_is_dirty (composer))
+	if (!e_msg_composer_is_dirty (composer, STATE_AUTOSAVE))
 		return TRUE;
 
 	fd = p->autosave_fd;
@@ -1551,12 +1603,15 @@ autosave_save_draft (EMsgComposer *compo
 			    file, g_strerror(errno), NULL);
 		success = FALSE;
 	} else {
+		gboolean dirty_save = e_msg_composer_is_dirty (composer, STATE_SAVE);
 		CORBA_Environment ev;
 		CORBA_exception_init (&ev);
 		GNOME_GtkHTML_Editor_Engine_runCommand (p->eeditor_engine, "saved", &ev);
 		CORBA_exception_free (&ev);
-		e_msg_composer_unset_changed (composer);
-		e_msg_composer_set_autosaved (composer);
+		e_msg_composer_do_unset_changed (composer, STATE_AUTOSAVE);
+		/* Restore save state */
+		if (dirty_save)
+			p->state[STATE_SAVE].has_changed = TRUE;
 	}
 
 	camel_object_unref (stream);
@@ -1614,7 +1669,6 @@ autosave_manager_query_load_orphans (Aut
 	const char *dname;
 	GSList *match = NULL;
 	gint len = strlen (AUTOSAVE_SEED);
-	gint load = FALSE;
 	gchar *dirname;
 
 	dirname = g_build_filename (g_get_home_dir (), ".evolution", NULL);
@@ -1648,20 +1702,12 @@ autosave_manager_query_load_orphans (Aut
 	g_dir_close (dir);
 	g_free (dirname);
 
-	if (match != NULL)
-		load = e_error_run(parent, "mail-composer:recover-autosave", NULL) == GTK_RESPONSE_YES;
-
 	while (match != NULL) {
 		GSList *next = match->next;
 		char *filename = match->data;
 		EMsgComposer *composer;
 
-		if (load) {
-			/* FIXME: composer is never used */
-			composer = autosave_load_draft (filename);
-		} else {
-			g_unlink (filename);
-		}
+		composer = autosave_load_draft (filename);
 
 		g_free (filename);
 		g_slist_free_1 (match);
@@ -1793,9 +1839,13 @@ autosave_manager_unregister (AutosaveMan
 static void
 menu_file_save_draft_cb (BonoboUIComponent *uic, void *data, const char *path)
 {
+	EMsgComposer *composer = E_MSG_COMPOSER (data);
+	gboolean dirty_autosave = e_msg_composer_is_dirty (composer, STATE_AUTOSAVE);
 	g_signal_emit (data, signals[SAVE_DRAFT], 0, FALSE);
-	e_msg_composer_unset_changed (E_MSG_COMPOSER (data));
-	e_msg_composer_unset_autosaved (E_MSG_COMPOSER (data));
+	e_msg_composer_do_unset_changed (composer, STATE_SAVE);
+	/* Restore autosave state */
+	if (dirty_autosave)
+		composer->priv->state[STATE_AUTOSAVE].has_changed = TRUE;
 }
 
 /* Exit dialog.  (Displays a "Save composition to 'Drafts' before exiting?" warning before actually exiting.)  */
@@ -1807,7 +1857,7 @@ do_exit (EMsgComposer *composer)
 	int button;
 	EMsgComposerPrivate *p = composer->priv;
 
-	if (!e_msg_composer_is_dirty (composer) && !e_msg_composer_is_autosaved (composer)) {
+ 	if (!e_msg_composer_is_dirty (composer, STATE_SAVE)) {
 		gtk_widget_destroy (GTK_WIDGET (composer));
 		return;
 	}
@@ -1822,9 +1872,14 @@ do_exit (EMsgComposer *composer)
 	switch (button) {
 	case GTK_RESPONSE_YES:
 		/* Save */
-		g_signal_emit (GTK_OBJECT (composer), signals[SAVE_DRAFT], 0, TRUE);
-		e_msg_composer_unset_changed (composer);
-		e_msg_composer_unset_autosaved (composer);
+		{
+			gboolean dirty_autosave = e_msg_composer_is_dirty (composer, STATE_AUTOSAVE);
+			g_signal_emit (GTK_OBJECT (composer), signals[SAVE_DRAFT], 0, TRUE);
+			e_msg_composer_do_unset_changed (composer, STATE_SAVE);
+			/* Restore autosave state */
+			if (dirty_autosave)
+				p->state[STATE_AUTOSAVE].has_changed = TRUE;
+		}
 		gtk_widget_destroy (GTK_WIDGET (composer));
 		break;
 	case GTK_RESPONSE_NO:
@@ -2254,6 +2309,8 @@ menu_changed_charset_cb (BonoboUICompone
 		/* Charset menu names are "Charset-%s" where %s is the charset name */
 		g_free (p->charset);
 		p->charset = g_strdup (path + strlen ("Charset-"));
+		/* Mark the composer as changed so it prompts about unsaved changes on close */
+		e_msg_composer_set_changed (composer);
 	}
 }
 
@@ -3273,8 +3330,10 @@ init (EMsgComposer *composer)
 	p->smime_sign               = FALSE;
 	p->smime_encrypt            = FALSE;
 
-	p->has_changed              = FALSE;
-	p->autosaved                = FALSE;
+	p->state[STATE_SAVE].has_changed     = FALSE;
+	p->state[STATE_SAVE].had_undo        = FALSE;
+	p->state[STATE_AUTOSAVE].has_changed = TRUE;
+	p->state[STATE_AUTOSAVE].had_undo    = FALSE;
 
 	p->redirect                 = NULL;
 	p->send_invoked		    = FALSE;
@@ -3941,7 +4000,10 @@ create_composer (int visible_mask)
 
 	autosave_manager_register (am, composer);
 
-	p->has_changed = FALSE;
+	p->state[STATE_SAVE].has_changed     = FALSE;
+	p->state[STATE_SAVE].had_undo        = FALSE;
+	p->state[STATE_AUTOSAVE].has_changed = TRUE;
+	p->state[STATE_AUTOSAVE].had_undo    = FALSE;
 
 	return composer;
 }
@@ -6177,7 +6239,8 @@ e_msg_composer_guess_mime_type (const ch
  * @composer: An EMsgComposer object.
  *
  * Mark the composer as changed, so before the composer gets destroyed
- * the user will be prompted about unsaved changes.
+ * the user will be prompted about unsaved changes, and the message will be
+ * autosaved.
  **/
 void
 e_msg_composer_set_changed (EMsgComposer *composer)
@@ -6185,7 +6248,8 @@ e_msg_composer_set_changed (EMsgComposer
 	EMsgComposerPrivate *p = composer->priv;
 	g_return_if_fail (E_IS_MSG_COMPOSER (composer));
 
-	p->has_changed = TRUE;
+	p->state[STATE_SAVE].has_changed     = TRUE;
+	p->state[STATE_AUTOSAVE].has_changed = TRUE;
 }
 
 
@@ -6199,59 +6263,9 @@ e_msg_composer_set_changed (EMsgComposer
 void
 e_msg_composer_unset_changed (EMsgComposer *composer)
 {
-	EMsgComposerPrivate *p = composer->priv;
 	g_return_if_fail (E_IS_MSG_COMPOSER (composer));
 
-	p->has_changed = FALSE;
-}
-
-gboolean
-e_msg_composer_is_dirty (EMsgComposer *composer)
-{
-	EMsgComposerPrivate *p = composer->priv;
-	CORBA_Environment ev;
-	gboolean rv;
-
-	CORBA_exception_init (&ev);
-	rv = p->has_changed
-		|| (GNOME_GtkHTML_Editor_Engine_hasUndo (p->eeditor_engine, &ev) &&
-		    !GNOME_GtkHTML_Editor_Engine_runCommand (p->eeditor_engine, "is-saved", &ev));
-	CORBA_exception_free (&ev);
-
-	return rv;
-}
-
-/**
- * e_msg_composer_set_autosaved:
- * @composer: An EMsgComposer object.
- *
- * Mark the composer as autosaved, so before the composer gets destroyed
- * the user will be prompted about unsaved changes.
- **/
-void
-e_msg_composer_set_autosaved (EMsgComposer *composer)
-{
-	EMsgComposerPrivate *p = composer->priv;
-	g_return_if_fail (E_IS_MSG_COMPOSER (composer));
-
-	p->autosaved = TRUE;
-}
-
-
-/**
- * e_msg_composer_unset_autosaved:
- * @composer: An EMsgComposer object.
- *
- * Mark the composer as unautosaved, so no prompt about unsaved changes
- * will appear before destroying the composer.
- **/
-void
-e_msg_composer_unset_autosaved (EMsgComposer *composer)
-{
-	EMsgComposerPrivate *p = composer->priv;
-	g_return_if_fail (E_IS_MSG_COMPOSER (composer));
-
-	p->autosaved = FALSE;
+	e_msg_composer_do_unset_changed (composer, STATE_SAVE);
 }
 
 /**
@@ -6281,15 +6295,6 @@ e_msg_composer_get_attachment_bar (EMsgC
        return (EAttachmentBar*) p->attachment_bar;
 }
 
-gboolean
-e_msg_composer_is_autosaved (EMsgComposer *composer)
-{
-	EMsgComposerPrivate *p = composer->priv;
-	g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), FALSE);
-
-	return p->autosaved;
-}
-
 void
 e_msg_composer_set_enable_autosave  (EMsgComposer *composer, gboolean enabled)
 {
diff -up -ru composer.orig/e-msg-composer.h composer/e-msg-composer.h
--- composer.orig/e-msg-composer.h	2008-01-28 04:59:48.000000000 +0100
+++ composer/e-msg-composer.h	2008-03-28 09:22:51.000000000 +0100
@@ -143,10 +143,6 @@ void                     e_msg_composer_
 char                    *e_msg_composer_guess_mime_type                  (const char        *file_name);
 void                     e_msg_composer_set_changed                      (EMsgComposer      *composer);
 void                     e_msg_composer_unset_changed                    (EMsgComposer      *composer);
-gboolean                 e_msg_composer_is_dirty                         (EMsgComposer      *composer);
-void                     e_msg_composer_set_autosaved                    (EMsgComposer      *composer);
-void                     e_msg_composer_unset_autosaved                  (EMsgComposer      *composer);
-gboolean                 e_msg_composer_is_autosaved                     (EMsgComposer      *composer);
 void                     e_msg_composer_set_enable_autosave              (EMsgComposer      *composer,
 									  gboolean           enabled);
 
