[evolution] Bug 605416 - Add aliases for accounts



commit f982b73031d5332a80c9a5752e79f6c2b37ba4fb
Author: Milan Crha <mcrha redhat com>
Date:   Tue Oct 18 18:41:15 2016 +0200

    Bug 605416 - Add aliases for accounts

 src/calendar/gui/e-meeting-store.c                 |   20 +
 src/calendar/gui/itip-utils.c                      |  220 ++++++++---
 src/composer/e-composer-from-header.c              |   20 +-
 src/composer/e-composer-from-header.h              |   10 +-
 src/composer/e-composer-header-table.c             |   51 ++-
 src/composer/e-composer-header-table.h             |   10 +-
 src/composer/e-msg-composer.c                      |  145 +++++---
 src/e-util/e-mail-identity-combo-box.c             |  333 +++++++++++++++--
 src/e-util/e-mail-identity-combo-box.h             |   15 +
 src/e-util/e-mail-signature-combo-box.c            |  192 +++++++++-
 src/e-util/e-mail-signature-combo-box.h            |   15 +
 src/libemail-engine/e-mail-session.c               |   17 +-
 src/libemail-engine/e-mail-utils.c                 |  111 ++++--
 src/libemail-engine/e-mail-utils.h                 |    6 +-
 src/mail/e-mail-config-identity-page.c             |  400 +++++++++++++++++++-
 src/mail/em-composer-utils.c                       |  135 +++++---
 src/modules/itip-formatter/itip-view.c             |  110 +++++-
 src/modules/mdn/evolution-mdn.c                    |   29 +-
 src/plugins/mail-to-task/mail-to-task.c            |   34 ++-
 .../mailing-list-actions/mailing-list-actions.c    |    2 +-
 src/plugins/templates/templates.c                  |    6 +-
 21 files changed, 1573 insertions(+), 308 deletions(-)
---
diff --git a/src/calendar/gui/e-meeting-store.c b/src/calendar/gui/e-meeting-store.c
index ae2012b..13c2e86 100644
--- a/src/calendar/gui/e-meeting-store.c
+++ b/src/calendar/gui/e-meeting-store.c
@@ -1122,6 +1122,7 @@ e_meeting_store_find_self (EMeetingStore *store,
        for (iter = list; iter != NULL; iter = g_list_next (iter)) {
                ESource *source = E_SOURCE (iter->data);
                ESourceMailIdentity *extension;
+               GHashTable *aliases;
                const gchar *address;
 
                extension = e_source_get_extension (source, extension_name);
@@ -1133,6 +1134,25 @@ e_meeting_store_find_self (EMeetingStore *store,
 
                if (attendee != NULL)
                        break;
+
+               aliases = e_source_mail_identity_get_aliases_as_hash_table (extension);
+               if (aliases) {
+                       GHashTableIter iter;
+                       gpointer key = NULL;
+
+                       g_hash_table_iter_init (&iter, aliases);
+                       while (!attendee && g_hash_table_iter_next (&iter, &key, NULL)) {
+                               const gchar *email = key;
+
+                               if (email && *email)
+                                       attendee = e_meeting_store_find_attendee (store, email, row);
+                       }
+
+                       g_hash_table_destroy (aliases);
+               }
+
+               if (attendee)
+                       break;
        }
 
        g_list_free_full (list, (GDestroyNotify) g_object_unref);
diff --git a/src/calendar/gui/itip-utils.c b/src/calendar/gui/itip-utils.c
index ec3c8db..4793b8b 100644
--- a/src/calendar/gui/itip-utils.c
+++ b/src/calendar/gui/itip-utils.c
@@ -110,6 +110,42 @@ itip_get_default_name_and_address (ESourceRegistry *registry,
        return success;
 }
 
+static gint
+sort_identities_by_email_cb (gconstpointer ptr1,
+                            gconstpointer ptr2)
+{
+       const gchar **pv1 = (const gchar **) ptr1, **pv2 = (const gchar **) ptr2;
+       const gchar *addr1, *addr2;
+       gint res;
+
+       if (!pv1 || !*pv1 || !pv2 || !*pv2) {
+               if (pv1 && *pv1)
+                       return -1;
+               if (pv2 && *pv2)
+                       return 1;
+               return 0;
+       }
+
+       addr1 = strchr (*pv1, '<');
+       addr2 = strchr (*pv2, '<');
+
+       if (addr1)
+               addr1++;
+       else
+               addr1 = *pv1;
+       if (addr2)
+               addr2++;
+       else
+               addr2 = *pv2;
+
+       res = g_ascii_strcasecmp (addr1, addr2);
+
+       if (!res && addr1 != *pv1 && addr2 != *pv2)
+               res = g_ascii_strcasecmp (*pv1, *pv2);
+
+       return res;
+}
+
 /**
  * itip_get_user_identities:
  * @registry: an #ESourceRegistry
@@ -122,10 +158,9 @@ itip_get_default_name_and_address (ESourceRegistry *registry,
 gchar **
 itip_get_user_identities (ESourceRegistry *registry)
 {
-       GList *list, *iter;
+       GList *list, *link;
        const gchar *extension_name;
-       gchar **identities;
-       guint ii = 0;
+       GPtrArray *identities;
 
        g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
 
@@ -133,30 +168,61 @@ itip_get_user_identities (ESourceRegistry *registry)
 
        list = e_source_registry_list_enabled (registry, extension_name);
 
-       identities = g_new0 (gchar *, g_list_length (list) + 1);
+       identities = g_ptr_array_sized_new (g_list_length (list) + 1);
 
-       for (iter = list; iter != NULL; iter = g_list_next (iter)) {
-               ESource *source = E_SOURCE (iter->data);
+       for (link = list; link != NULL; link = g_list_next (link)) {
+               ESource *source = E_SOURCE (link->data);
                ESourceMailIdentity *extension;
                const gchar *name, *address;
+               gchar *aliases;
 
                extension = e_source_get_extension (source, extension_name);
 
                name = e_source_mail_identity_get_name (extension);
                address = e_source_mail_identity_get_address (extension);
 
-               if (!address)
-                       continue;
+               if (address) {
+                       if (name && *name)
+                               g_ptr_array_add (identities, g_strdup_printf ("%s <%s>", name, address));
+                       else
+                               g_ptr_array_add (identities, g_strdup_printf ("%s", address));
+               }
 
-               if (name && *name)
-                       identities[ii++] = g_strdup_printf ("%s <%s>", name, address);
-               else
-                       identities[ii++] = g_strdup_printf ("%s", address);
+               aliases = e_source_mail_identity_dup_aliases (extension);
+               if (aliases && *aliases) {
+                       CamelInternetAddress *inet_address;
+                       gint ii, len;
+
+                       inet_address = camel_internet_address_new ();
+                       len = camel_address_decode (CAMEL_ADDRESS (inet_address), aliases);
+
+                       for (ii = 0; ii < len; ii++) {
+                               const gchar *alias_name = NULL, *alias_address = NULL;
+
+                               if (camel_internet_address_get (inet_address, ii, &alias_name, 
&alias_address) &&
+                                   alias_address && *alias_address) {
+                                       if (!alias_name || !*alias_name)
+                                               alias_name = name;
+
+                                       if (alias_name && *alias_name)
+                                               g_ptr_array_add (identities, g_strdup_printf ("%s <%s>", 
alias_name, alias_address));
+                                       else
+                                               g_ptr_array_add (identities, g_strdup_printf ("%s", 
alias_address));
+                               }
+                       }
+               }
+
+               g_free (aliases);
        }
 
        g_list_free_full (list, (GDestroyNotify) g_object_unref);
 
-       return identities;
+       g_ptr_array_sort (identities, sort_identities_by_email_cb);
+
+       /* NULL-terminated array */
+       g_ptr_array_add (identities, NULL);
+
+       return (gchar **) g_ptr_array_free (identities, FALSE);
 }
 
 /**
@@ -235,21 +301,25 @@ itip_address_is_user (ESourceRegistry *registry,
 
        list = e_source_registry_list_sources (registry, extension_name);
 
-       for (iter = list; iter != NULL; iter = g_list_next (iter)) {
+       for (iter = list; iter && !match; iter = g_list_next (iter)) {
                ESource *source = E_SOURCE (iter->data);
                ESourceMailIdentity *extension;
+               GHashTable *aliases;
                const gchar *id_address;
 
                extension = e_source_get_extension (source, extension_name);
                id_address = e_source_mail_identity_get_address (extension);
 
-               if (id_address == NULL)
-                       continue;
-
-               if (g_ascii_strcasecmp (address, id_address) == 0) {
+               if (id_address && g_ascii_strcasecmp (address, id_address) == 0) {
                        match = TRUE;
                        break;
                }
+
+               aliases = e_source_mail_identity_get_aliases_as_hash_table (extension);
+               if (aliases) {
+                       match = g_hash_table_contains (aliases, address);
+                       g_hash_table_destroy (aliases);
+               }
        }
 
        g_list_free_full (list, (GDestroyNotify) g_object_unref);
@@ -381,7 +451,8 @@ itip_has_any_attendees (ECalComponent *comp)
 
 static ECalComponentAttendee *
 get_attendee (GSList *attendees,
-              gchar *address)
+             const gchar *address,
+             GHashTable *aliases)
 {
        GSList *l;
 
@@ -390,8 +461,14 @@ get_attendee (GSList *attendees,
 
        for (l = attendees; l; l = l->next) {
                ECalComponentAttendee *attendee = l->data;
+               const gchar *nomailto;
 
-               if (!g_ascii_strcasecmp (itip_strip_mailto (attendee->value), address)) {
+               nomailto = itip_strip_mailto (attendee->value);
+               if (!nomailto || !*nomailto)
+                       continue;
+
+               if ((address && g_ascii_strcasecmp (nomailto, address) == 0) ||
+                   (aliases && g_hash_table_contains (aliases, nomailto))) {
                        return attendee;
                }
        }
@@ -401,15 +478,21 @@ get_attendee (GSList *attendees,
 
 static ECalComponentAttendee *
 get_attendee_if_attendee_sentby_is_user (GSList *attendees,
-                                         gchar *address)
+                                        const gchar *address,
+                                        GHashTable *aliases)
 {
        GSList *l;
 
        for (l = attendees; l; l = l->next) {
                ECalComponentAttendee *attendee = l->data;
+               const gchar *nomailto;
+
+               nomailto = itip_strip_mailto (attendee->sentby);
+               if (!nomailto || !*nomailto)
+                       continue;
 
-               if (attendee->sentby && g_str_equal (
-                       itip_strip_mailto (attendee->sentby), address)) {
+               if ((address && g_ascii_strcasecmp (nomailto, address) == 0) ||
+                   (aliases && g_hash_table_contains (aliases, nomailto))) {
                        return attendee;
                }
        }
@@ -451,7 +534,7 @@ itip_get_comp_attendee (ESourceRegistry *registry,
                        &address, NULL, NULL);
 
        if (address != NULL && *address != '\0') {
-               attendee = get_attendee (attendees, address);
+               attendee = get_attendee (attendees, address, NULL);
 
                if (attendee) {
                        gchar *user_email;
@@ -464,8 +547,7 @@ itip_get_comp_attendee (ESourceRegistry *registry,
                        return user_email;
                }
 
-               attendee = get_attendee_if_attendee_sentby_is_user (
-                       attendees, address);
+               attendee = get_attendee_if_attendee_sentby_is_user (attendees, address, NULL);
 
                if (attendee != NULL) {
                        gchar *user_email;
@@ -486,27 +568,27 @@ itip_get_comp_attendee (ESourceRegistry *registry,
        list = e_source_registry_list_enabled (registry, extension_name);
 
        for (link = list; link != NULL; link = g_list_next (link)) {
-               ESourceExtension *extension;
+               ESourceMailIdentity *extension;
+               GHashTable *aliases;
 
                source = E_SOURCE (link->data);
 
                extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
                extension = e_source_get_extension (source, extension_name);
 
-               address = e_source_mail_identity_dup_address (
-                       E_SOURCE_MAIL_IDENTITY (extension));
+               address = e_source_mail_identity_dup_address (extension);
 
-               if (address == NULL)
-                       continue;
+               aliases = e_source_mail_identity_get_aliases_as_hash_table (extension);
 
-               attendee = get_attendee (attendees, address);
+               attendee = get_attendee (attendees, address, aliases);
                if (attendee != NULL) {
                        gchar *user_email;
 
-                       user_email = g_strdup (
-                               itip_strip_mailto (attendee->value));
+                       user_email = g_strdup (itip_strip_mailto (attendee->value));
                        e_cal_component_free_attendee_list (attendees);
 
+                       if (aliases)
+                               g_hash_table_destroy (aliases);
                        g_free (address);
 
                        return user_email;
@@ -515,20 +597,22 @@ itip_get_comp_attendee (ESourceRegistry *registry,
                /* If the account was not found in the attendees list, then
                 * let's check the 'sentby' fields of the attendees if we can
                 * find the account. */
-               attendee = get_attendee_if_attendee_sentby_is_user (
-                       attendees, address);
+               attendee = get_attendee_if_attendee_sentby_is_user (attendees, address, aliases);
                if (attendee) {
                        gchar *user_email;
 
-                       user_email = g_strdup (
-                               itip_strip_mailto (attendee->sentby));
+                       user_email = g_strdup (itip_strip_mailto (attendee->sentby));
                        e_cal_component_free_attendee_list (attendees);
 
+                       if (aliases)
+                               g_hash_table_destroy (aliases);
                        g_free (address);
 
                        return user_email;
                }
 
+               if (aliases)
+                       g_hash_table_destroy (aliases);
                g_free (address);
        }
 
@@ -666,7 +750,8 @@ users_has_attendee (const GSList *users,
 static gchar *
 comp_from (ECalComponentItipMethod method,
            ECalComponent *comp,
-           ESourceRegistry *registry)
+           ESourceRegistry *registry,
+          gchar **from_name)
 {
        ECalComponentOrganizer organizer;
        ECalComponentAttendee *attendee;
@@ -700,6 +785,8 @@ comp_from (ECalComponentItipMethod method,
                                _("An organizer must be set."));
                        return NULL;
                }
+               if (from_name)
+                       *from_name = g_strdup (organizer.cn);
                return g_strdup (itip_strip_mailto (organizer.value));
 
        default:
@@ -708,9 +795,11 @@ comp_from (ECalComponentItipMethod method,
 
                e_cal_component_get_attendee_list (comp, &attendees);
                attendee = attendees->data;
-               if (attendee->value != NULL)
+               if (attendee->value != NULL) {
                        from = g_strdup (itip_strip_mailto (attendee->value));
-               else
+                       if (from_name)
+                               *from_name = g_strdup (attendee->cn);
+               } else
                        from = NULL;
                e_cal_component_free_attendee_list (attendees);
 
@@ -1663,18 +1752,26 @@ find_enabled_identity (ESourceRegistry *registry,
        for (link = list; link != NULL; link = g_list_next (link)) {
                ESource *source = E_SOURCE (link->data);
                ESourceMailIdentity *extension;
+               GHashTable *aliases;
                const gchar *address;
 
                extension = e_source_get_extension (source, extension_name);
                address = e_source_mail_identity_get_address (extension);
 
-               if (address == NULL)
-                       continue;
-
-               if (g_ascii_strcasecmp (address, id_address) == 0) {
+               if (address && g_ascii_strcasecmp (address, id_address) == 0) {
                        mail_identity = g_object_ref (source);
                        break;
                }
+
+               aliases = e_source_mail_identity_get_aliases_as_hash_table (extension);
+               if (aliases) {
+                       if (g_hash_table_contains (aliases, id_address))
+                               mail_identity = g_object_ref (source);
+                       g_hash_table_destroy (aliases);
+
+                       if (mail_identity)
+                               break;
+               }
        }
 
        g_list_free_full (list, (GDestroyNotify) g_object_unref);
@@ -1686,7 +1783,9 @@ static gchar *
 get_identity_uid_for_from (EShell *shell,
                           ECalComponentItipMethod method,
                           ECalComponent *comp,
-                          ECalClient *cal_client)
+                          ECalClient *cal_client,
+                          gchar **identity_name,
+                          gchar **identity_address)
 {
        EClientCache *client_cache;
        ESourceRegistry *registry;
@@ -1701,17 +1800,30 @@ get_identity_uid_for_from (EShell *shell,
                ECalComponentOrganizer organizer = {0};
 
                e_cal_component_get_organizer (comp, &organizer);
-               if (organizer.value != NULL)
+               if (organizer.value != NULL) {
                        source = find_enabled_identity (
                                registry,
                                itip_strip_mailto (organizer.value));
+
+                       if (source) {
+                               if (identity_name)
+                                       *identity_name = g_strdup (organizer.cn);
+                               if (identity_address)
+                                       *identity_address = g_strdup (itip_strip_mailto (organizer.value));
+                       }
+               }
        }
 
        if (source == NULL) {
-               gchar *from = comp_from (method, comp, registry);
+               gchar *from = comp_from (method, comp, registry, identity_name);
 
-               if (from != NULL)
+               if (from != NULL) {
                        source = find_enabled_identity (registry, from);
+                       if (source) {
+                               if (identity_address)
+                                       *identity_address = g_strdup (from);
+                       }
+               }
 
                g_free (from);
        }
@@ -1815,6 +1927,8 @@ itip_send_component_begin (ItipSendComponentData *isc,
 
 typedef struct _CreateComposerData {
        gchar *identity_uid;
+       gchar *identity_name;
+       gchar *identity_address;
        EDestination **destinations;
        gchar *subject;
        gchar *ical_string;
@@ -1853,7 +1967,7 @@ itip_send_component_composer_created_cb (GObject *source_object,
        table = e_msg_composer_get_header_table (composer);
 
        if (ccd->identity_uid)
-               e_composer_header_table_set_identity_uid (table, ccd->identity_uid);
+               e_composer_header_table_set_identity_uid (table, ccd->identity_uid, ccd->identity_name, 
ccd->identity_address);
 
        e_composer_header_table_set_subject (table, ccd->subject);
        e_composer_header_table_set_destinations_to (table, ccd->destinations);
@@ -1902,6 +2016,8 @@ itip_send_component_composer_created_cb (GObject *source_object,
        e_destination_freev (ccd->destinations);
        g_clear_object (&ccd->comp);
        g_free (ccd->identity_uid);
+       g_free (ccd->identity_name);
+       g_free (ccd->identity_address);
        g_free (ccd->subject);
        g_free (ccd->ical_string);
        g_free (ccd->content_type);
@@ -1953,7 +2069,7 @@ itip_send_component_complete (ItipSendComponentData *isc)
        top_level = comp_toplevel_with_zones (isc->method, comp, isc->cal_client, isc->zones);
 
        ccd = g_new0 (CreateComposerData, 1);
-       ccd->identity_uid = get_identity_uid_for_from (shell, isc->method, isc->send_comp, isc->cal_client);
+       ccd->identity_uid = get_identity_uid_for_from (shell, isc->method, isc->send_comp, isc->cal_client, 
&ccd->identity_name, &ccd->identity_address);
        ccd->destinations = destinations;
        ccd->subject = comp_subject (isc->registry, isc->method, comp);
        ccd->ical_string = icalcomponent_as_ical_string_r (top_level);
@@ -2231,7 +2347,7 @@ reply_to_calendar_comp (ESourceRegistry *registry,
        top_level = comp_toplevel_with_zones (method, comp, cal_client, zones);
 
        ccd = g_new0 (CreateComposerData, 1);
-       ccd->identity_uid = get_identity_uid_for_from (shell, method, send_comp, cal_client);
+       ccd->identity_uid = get_identity_uid_for_from (shell, method, send_comp, cal_client, 
&ccd->identity_name, &ccd->identity_address);
        ccd->destinations = comp_to_list (registry, method, comp, NULL, reply_all, NULL);
        ccd->subject = comp_subject (registry, method, comp);
        ccd->ical_string = icalcomponent_as_ical_string_r (top_level);
diff --git a/src/composer/e-composer-from-header.c b/src/composer/e-composer-from-header.c
index dd530be..b117454 100644
--- a/src/composer/e-composer-from-header.c
+++ b/src/composer/e-composer-from-header.c
@@ -96,6 +96,7 @@ composer_from_header_constructed (GObject *object)
        /* Input widget must be set before chaining up. */
 
        widget = e_mail_identity_combo_box_new (registry);
+       e_mail_identity_combo_box_set_allow_aliases (E_MAIL_IDENTITY_COMBO_BOX (widget), TRUE);
        gtk_widget_show (widget);
        g_signal_connect (
                widget, "changed",
@@ -205,21 +206,29 @@ e_composer_from_header_get_identities_widget (EComposerFromHeader *header)
        return GTK_COMBO_BOX (E_COMPOSER_HEADER (header)->input_widget);
 }
 
-const gchar *
-e_composer_from_header_get_active_id (EComposerFromHeader *header)
+gchar *
+e_composer_from_header_dup_active_id (EComposerFromHeader *header,
+                                     gchar **alias_name,
+                                     gchar **alias_address)
 {
        GtkComboBox *combo_box;
+       gchar *identity_uid = NULL;
 
        g_return_val_if_fail (E_IS_COMPOSER_FROM_HEADER (header), NULL);
 
        combo_box = e_composer_from_header_get_identities_widget (header);
 
-       return gtk_combo_box_get_active_id (combo_box);
+       if (!e_mail_identity_combo_box_get_active_uid (E_MAIL_IDENTITY_COMBO_BOX (combo_box), &identity_uid, 
alias_name, alias_address))
+               return NULL;
+
+       return identity_uid;
 }
 
 void
 e_composer_from_header_set_active_id (EComposerFromHeader *header,
-                                      const gchar *active_id)
+                                     const gchar *active_id,
+                                     const gchar *alias_name,
+                                     const gchar *alias_address)
 {
        GtkComboBox *combo_box;
 
@@ -230,7 +239,8 @@ e_composer_from_header_set_active_id (EComposerFromHeader *header,
 
        combo_box = e_composer_from_header_get_identities_widget (header);
 
-       if (!gtk_combo_box_set_active_id (combo_box, active_id) && active_id && *active_id) {
+       if (!e_mail_identity_combo_box_set_active_uid (E_MAIL_IDENTITY_COMBO_BOX (combo_box),
+               active_id, alias_name, alias_address) && active_id && *active_id) {
                ESourceRegistry *registry;
                GtkTreeModel *model;
                GtkTreeIter iter;
diff --git a/src/composer/e-composer-from-header.h b/src/composer/e-composer-from-header.h
index 7dd3579..79ffab1 100644
--- a/src/composer/e-composer-from-header.h
+++ b/src/composer/e-composer-from-header.h
@@ -61,11 +61,15 @@ GType               e_composer_from_header_get_type (void);
 EComposerHeader *
                e_composer_from_header_new      (ESourceRegistry *registry,
                                                 const gchar *label);
-const gchar *  e_composer_from_header_get_active_id
-                                               (EComposerFromHeader *header);
+gchar *                e_composer_from_header_dup_active_id
+                                               (EComposerFromHeader *header,
+                                                gchar **alias_name,
+                                                gchar **alias_address);
 void           e_composer_from_header_set_active_id
                                                (EComposerFromHeader *header,
-                                                const gchar *active_id);
+                                                const gchar *active_id,
+                                                const gchar *alias_name,
+                                                const gchar *alias_address);
 GtkEntry *     e_composer_from_header_get_name_entry
                                                (EComposerFromHeader *header);
 const gchar *  e_composer_from_header_get_name (EComposerFromHeader *header);
diff --git a/src/composer/e-composer-header-table.c b/src/composer/e-composer-header-table.c
index 6b952c4..8291c83 100644
--- a/src/composer/e-composer-header-table.c
+++ b/src/composer/e-composer-header-table.c
@@ -409,13 +409,13 @@ composer_header_table_show_post_headers (EComposerHeaderTable *table)
        ESourceRegistry *registry;
        GList *list, *link;
        const gchar *extension_name;
-       const gchar *target_uid;
+       gchar *target_uid;
        gboolean show_post_headers = FALSE;
 
        client_cache = e_composer_header_table_ref_client_cache (table);
        registry = e_client_cache_ref_registry (client_cache);
 
-       target_uid = e_composer_header_table_get_identity_uid (table);
+       target_uid = e_composer_header_table_dup_identity_uid (table, NULL, NULL);
 
        extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
        list = e_source_registry_list_sources (registry, extension_name);
@@ -455,6 +455,7 @@ composer_header_table_show_post_headers (EComposerHeaderTable *table)
 
        g_object_unref (client_cache);
        g_object_unref (registry);
+       g_free (target_uid);
 
        return show_post_headers;
 }
@@ -471,18 +472,19 @@ composer_header_table_from_changed_cb (EComposerHeaderTable *table)
        EComposerTextHeader *text_header;
        EDestination **old_destinations;
        EDestination **new_destinations;
-       const gchar *name = NULL;
-       const gchar *address = NULL;
+       gchar *name = NULL;
+       gchar *address = NULL;
+       gchar *uid;
        const gchar *reply_to = NULL;
        const gchar * const *bcc = NULL;
        const gchar * const *cc = NULL;
-       const gchar *uid;
 
        /* Keep "Post-To" and "Reply-To" synchronized with "From" */
 
-       uid = e_composer_header_table_get_identity_uid (table);
+       uid = e_composer_header_table_dup_identity_uid (table, &name, &address);
        if (uid != NULL)
                source = e_composer_header_table_ref_source (table, uid);
+       g_free (uid);
 
        /* Make sure this is really a mail identity source. */
        if (source != NULL) {
@@ -506,8 +508,16 @@ composer_header_table_from_changed_cb (EComposerHeaderTable *table)
                extension_name = E_SOURCE_EXTENSION_MAIL_COMPOSITION;
                mc = e_source_get_extension (source, extension_name);
 
-               name = e_source_mail_identity_get_name (mi);
-               address = e_source_mail_identity_get_address (mi);
+               if (!address) {
+                       g_free (name);
+
+                       name = e_source_mail_identity_dup_name (mi);
+                       address = e_source_mail_identity_dup_address (mi);
+               }
+
+               if (!name)
+                       name = e_source_mail_identity_dup_name (mi);
+
                reply_to = e_source_mail_identity_get_reply_to (mi);
                bcc = e_source_mail_composition_get_bcc (mc);
                cc = e_source_mail_composition_get_cc (mc);
@@ -586,6 +596,9 @@ composer_header_table_from_changed_cb (EComposerHeaderTable *table)
                composer_header_table_setup_post_headers (table);
        else
                composer_header_table_setup_mail_headers (table);
+
+       g_free (name);
+       g_free (address);
 }
 
 static void
@@ -641,7 +654,7 @@ composer_header_table_set_property (GObject *object,
                case PROP_IDENTITY_UID:
                        e_composer_header_table_set_identity_uid (
                                E_COMPOSER_HEADER_TABLE (object),
-                               g_value_get_string (value));
+                               g_value_get_string (value), NULL, NULL);
                        return;
 
                case PROP_POST_TO:
@@ -716,10 +729,10 @@ composer_header_table_get_property (GObject *object,
                        return;
 
                case PROP_IDENTITY_UID:
-                       g_value_set_string (
+                       g_value_take_string (
                                value,
-                               e_composer_header_table_get_identity_uid (
-                               E_COMPOSER_HEADER_TABLE (object)));
+                               e_composer_header_table_dup_identity_uid (
+                               E_COMPOSER_HEADER_TABLE (object), NULL, NULL));
                        return;
 
                case PROP_POST_TO:
@@ -1331,8 +1344,10 @@ e_composer_header_table_set_destinations_to (EComposerHeaderTable *table,
        e_composer_name_header_set_destinations (name_header, destinations);
 }
 
-const gchar *
-e_composer_header_table_get_identity_uid (EComposerHeaderTable *table)
+gchar *
+e_composer_header_table_dup_identity_uid (EComposerHeaderTable *table,
+                                         gchar **chosen_alias_name,
+                                         gchar **chosen_alias_address)
 {
        EComposerHeader *header;
        EComposerHeaderType type;
@@ -1344,12 +1359,14 @@ e_composer_header_table_get_identity_uid (EComposerHeaderTable *table)
        header = e_composer_header_table_get_header (table, type);
        from_header = E_COMPOSER_FROM_HEADER (header);
 
-       return e_composer_from_header_get_active_id (from_header);
+       return e_composer_from_header_dup_active_id (from_header, chosen_alias_name, chosen_alias_address);
 }
 
 void
 e_composer_header_table_set_identity_uid (EComposerHeaderTable *table,
-                                          const gchar *identity_uid)
+                                         const gchar *identity_uid,
+                                         const gchar *alias_name,
+                                         const gchar *alias_address)
 {
        EComposerHeader *header;
        EComposerHeaderType type;
@@ -1361,7 +1378,7 @@ e_composer_header_table_set_identity_uid (EComposerHeaderTable *table,
        header = e_composer_header_table_get_header (table, type);
        from_header = E_COMPOSER_FROM_HEADER (header);
 
-       e_composer_from_header_set_active_id (from_header, identity_uid);
+       e_composer_from_header_set_active_id (from_header, identity_uid, alias_name, alias_address);
 }
 
 const gchar *
diff --git a/src/composer/e-composer-header-table.h b/src/composer/e-composer-header-table.h
index cff5ed1..75913e8 100644
--- a/src/composer/e-composer-header-table.h
+++ b/src/composer/e-composer-header-table.h
@@ -104,11 +104,15 @@ void              e_composer_header_table_add_destinations_to
 void           e_composer_header_table_set_destinations_to
                                                (EComposerHeaderTable *table,
                                                 EDestination **destinations);
-const gchar *  e_composer_header_table_get_identity_uid
-                                               (EComposerHeaderTable *table);
+gchar *                e_composer_header_table_dup_identity_uid
+                                               (EComposerHeaderTable *table,
+                                                gchar **chosen_alias_name,
+                                                gchar **chosen_alias_address);
 void           e_composer_header_table_set_identity_uid
                                                (EComposerHeaderTable *table,
-                                                const gchar *identity_uid);
+                                                const gchar *identity_uid,
+                                                const gchar *alias_name,
+                                                const gchar *alias_address);
 const gchar *  e_composer_header_table_get_from_name
                                                (EComposerHeaderTable *table);
 const gchar *  e_composer_header_table_get_from_address
diff --git a/src/composer/e-msg-composer.c b/src/composer/e-msg-composer.c
index cb89c25..ff3b703 100644
--- a/src/composer/e-msg-composer.c
+++ b/src/composer/e-msg-composer.c
@@ -162,26 +162,13 @@ G_DEFINE_TYPE_WITH_CODE (
 static void
 async_context_free (AsyncContext *context)
 {
-       if (context->activity != NULL)
-               g_object_unref (context->activity);
-
-       if (context->message != NULL)
-               g_object_unref (context->message);
-
-       if (context->top_level_part != NULL)
-               g_object_unref (context->top_level_part);
-
-       if (context->text_plain_part != NULL)
-               g_object_unref (context->text_plain_part);
-
-       if (context->source != NULL)
-               g_object_unref (context->source);
-
-       if (context->session != NULL)
-               g_object_unref (context->session);
-
-       if (context->from != NULL)
-               g_object_unref (context->from);
+       g_clear_object (&context->activity);
+       g_clear_object (&context->message);
+       g_clear_object (&context->top_level_part);
+       g_clear_object (&context->text_plain_part);
+       g_clear_object (&context->source);
+       g_clear_object (&context->session);
+       g_clear_object (&context->from);
 
        if (context->recipients != NULL)
                g_ptr_array_free (context->recipients, TRUE);
@@ -528,16 +515,16 @@ build_message_headers (EMsgComposer *composer,
        EComposerHeaderTable *table;
        EComposerHeader *header;
        ESource *source;
+       gchar *alias_name = NULL, *alias_address = NULL, *uid;
        const gchar *subject;
        const gchar *reply_to;
-       const gchar *uid;
 
        g_return_if_fail (E_IS_MSG_COMPOSER (composer));
        g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message));
 
        table = e_msg_composer_get_header_table (composer);
 
-       uid = e_composer_header_table_get_identity_uid (table);
+       uid = e_composer_header_table_dup_identity_uid (table, &alias_name, &alias_address);
        source = e_composer_header_table_ref_source (table, uid);
 
        /* Subject: */
@@ -551,7 +538,7 @@ build_message_headers (EMsgComposer *composer,
                EComposerHeader *composer_header;
                const gchar *extension_name;
                const gchar *header_name;
-               const gchar *name, *address = NULL;
+               const gchar *name = NULL, *address = NULL;
                const gchar *transport_uid;
                const gchar *sent_folder;
 
@@ -565,12 +552,22 @@ build_message_headers (EMsgComposer *composer,
                }
 
                if (!address) {
+                       if (alias_name)
+                               name = alias_name;
+                       if (alias_address)
+                               address = alias_address;
+               }
+
+               if (!address || !name || !*name) {
                        ESourceMailIdentity *mail_identity;
 
                        mail_identity = e_source_get_extension (source, E_SOURCE_EXTENSION_MAIL_IDENTITY);
 
-                       name = e_source_mail_identity_get_name (mail_identity);
-                       address = e_source_mail_identity_get_address (mail_identity);
+                       if (!name || !*name)
+                               name = e_source_mail_identity_get_name (mail_identity);
+
+                       if (!address)
+                               address = e_source_mail_identity_get_address (mail_identity);
                }
 
                extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION;
@@ -662,6 +659,10 @@ build_message_headers (EMsgComposer *composer,
                }
                g_list_free (list);
        }
+
+       g_free (uid);
+       g_free (alias_name);
+       g_free (alias_address);
 }
 
 static CamelCipherHash
@@ -1102,8 +1103,8 @@ composer_build_message (EMsgComposer *composer,
        ESourceMailIdentity *mi;
        const gchar *extension_name;
        const gchar *iconv_charset = NULL;
-       const gchar *identity_uid;
        const gchar *organization;
+       gchar *identity_uid;
        CamelMultipart *body = NULL;
        CamelContentType *type;
        CamelStream *stream;
@@ -1120,8 +1121,10 @@ composer_build_message (EMsgComposer *composer,
        view = e_msg_composer_get_attachment_view (composer);
        store = e_attachment_view_get_store (view);
 
-       identity_uid = e_composer_header_table_get_identity_uid (table);
+       identity_uid = e_composer_header_table_dup_identity_uid (table, NULL, NULL);
        source = e_composer_header_table_ref_source (table, identity_uid);
+       g_free (identity_uid);
+
        g_return_if_fail (source != NULL);
 
        /* Do all the non-blocking work here, and defer
@@ -1639,14 +1642,18 @@ msg_composer_mail_identity_changed_cb (EMsgComposer *composer)
        gboolean smime_encrypt;
        gboolean composer_realized;
        const gchar *extension_name;
-       const gchar *uid, *active_signature_id;
+       const gchar *active_signature_id;
+       gchar *uid, *alias_name = NULL, *alias_address = NULL;
 
        table = e_msg_composer_get_header_table (composer);
-       uid = e_composer_header_table_get_identity_uid (table);
+       uid = e_composer_header_table_dup_identity_uid (table, &alias_name, &alias_address);
 
        /* Silently return if no identity is selected. */
-       if (uid == NULL)
+       if (!uid) {
+               g_free (alias_name);
+               g_free (alias_address);
                return;
+       }
 
        source = e_composer_header_table_ref_source (table, uid);
        g_return_if_fail (source != NULL);
@@ -1697,13 +1704,17 @@ msg_composer_mail_identity_changed_cb (EMsgComposer *composer)
        gtk_toggle_action_set_active (action, active);
 
        combo_box = e_composer_header_table_get_signature_combo_box (table);
-       e_mail_signature_combo_box_set_identity_uid (combo_box, uid);
+       e_mail_signature_combo_box_set_identity (combo_box, uid, alias_name, alias_address);
 
        g_object_unref (source);
+       g_free (uid);
 
        active_signature_id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (combo_box));
        if (g_strcmp0 (active_signature_id, E_MAIL_SIGNATURE_AUTOGENERATED_UID) == 0)
                e_composer_update_signature (composer);
+
+       g_free (alias_name);
+       g_free (alias_address);
 }
 
 static void
@@ -2130,10 +2141,10 @@ msg_composer_realize_cb (EMsgComposer *composer)
        if (g_settings_get_boolean (settings, "composer-toolbar-show-sign-encrypt")) {
                EComposerHeaderTable *table;
                ESource *source;
-               const gchar *identity_uid;
+               gchar *identity_uid;
 
                table = e_msg_composer_get_header_table (composer);
-               identity_uid = e_composer_header_table_get_identity_uid (table);
+               identity_uid = e_composer_header_table_dup_identity_uid (table, NULL, NULL);
                source = e_composer_header_table_ref_source (table, identity_uid);
 
                if (source) {
@@ -2172,6 +2183,8 @@ msg_composer_realize_cb (EMsgComposer *composer)
 
                        g_clear_object (&source);
                }
+
+               g_free (identity_uid);
        }
 
        g_clear_object (&settings);
@@ -2500,7 +2513,10 @@ msg_composer_constructed (GObject *object)
        composer->priv->notify_destinations_to_handler = e_signal_connect_notify_swapped (
                table, "notify::destinations-to",
                G_CALLBACK (msg_composer_notify_header_cb), composer);
-       composer->priv->notify_identity_uid_handler = e_signal_connect_notify_swapped (
+       /* Do not use e_signal_connect_notify_swapped() here, it it avoids notification
+          when the property didn't change, but it's about the consolidated property,
+          identity uid, name and address, where only one of the three can change. */
+       composer->priv->notify_identity_uid_handler = g_signal_connect_swapped (
                table, "notify::identity-uid",
                G_CALLBACK (msg_composer_mail_identity_changed_cb), composer);
        composer->priv->notify_reply_to_handler = e_signal_connect_notify_swapped (
@@ -3549,7 +3565,7 @@ e_msg_composer_setup_with_message (EMsgComposer *composer,
        EContentEditor *cnt_editor;
        GtkToggleAction *action;
        struct _camel_header_raw *xev;
-       gchar *identity_uid;
+       gchar *identity_uid, *tmp = NULL;
        gint len, i;
        gboolean is_message_from_draft = FALSE;
 
@@ -3592,9 +3608,11 @@ e_msg_composer_setup_with_message (EMsgComposer *composer,
                }
                if (!identity_uid) {
                        source = em_utils_guess_mail_identity_with_recipients (
-                               e_shell_get_registry (e_msg_composer_get_shell (composer)), message, NULL, 
NULL);
-                       if (source)
-                               identity_uid = e_source_dup_uid (source);
+                               e_shell_get_registry (e_msg_composer_get_shell (composer)), message, NULL, 
NULL, NULL, NULL);
+                       if (source) {
+                               tmp = e_source_dup_uid (source);
+                               identity_uid = tmp;
+                       }
                }
        }
 
@@ -3604,6 +3622,8 @@ e_msg_composer_setup_with_message (EMsgComposer *composer,
                        table, identity_uid);
        }
 
+       g_free (tmp);
+
        auto_cc = g_hash_table_new_full (
                (GHashFunc) camel_strcase_hash,
                (GEqualFunc) camel_strcase_equal,
@@ -3685,14 +3705,11 @@ e_msg_composer_setup_with_message (EMsgComposer *composer,
 
        subject = camel_mime_message_get_subject (message);
 
-       e_composer_header_table_set_identity_uid (table, identity_uid);
        e_composer_header_table_set_destinations_to (table, Tov);
        e_composer_header_table_set_destinations_cc (table, Ccv);
        e_composer_header_table_set_destinations_bcc (table, Bccv);
        e_composer_header_table_set_subject (table, subject);
 
-       g_free (identity_uid);
-
        e_destination_freev (Tov);
        e_destination_freev (Ccv);
        e_destination_freev (Bccv);
@@ -3706,6 +3723,9 @@ e_msg_composer_setup_with_message (EMsgComposer *composer,
                        EComposerFromHeader *header_from;
                        const gchar *filled_name, *filled_address;
 
+                       /* First try whether such alias exists... */
+                       e_composer_header_table_set_identity_uid (table, identity_uid, name, address);
+
                        header_from = E_COMPOSER_FROM_HEADER (e_composer_header_table_get_header (table, 
E_COMPOSER_HEADER_FROM));
 
                        filled_name = e_composer_from_header_get_name (header_from);
@@ -3719,13 +3739,21 @@ e_msg_composer_setup_with_message (EMsgComposer *composer,
 
                        if (g_strcmp0 (filled_name, name) != 0 ||
                            g_strcmp0 (filled_address, address) != 0) {
+                               /* ... and if not, then reset to the main identity address */
+                               e_composer_header_table_set_identity_uid (table, identity_uid, NULL, NULL);
                                e_composer_from_header_set_name (header_from, name);
                                e_composer_from_header_set_address (header_from, address);
                                e_composer_from_header_set_override_visible (header_from, TRUE);
                        }
+               } else {
+                       e_composer_header_table_set_identity_uid (table, identity_uid, NULL, NULL);
                }
+       } else {
+               e_composer_header_table_set_identity_uid (table, identity_uid, NULL, NULL);
        }
 
+       g_free (identity_uid);
+
        /* Restore the format editing preference */
        format = camel_medium_get_header (
                CAMEL_MEDIUM (message), "X-Evolution-Format");
@@ -4716,7 +4744,7 @@ e_msg_composer_set_body (EMsgComposer *composer,
        EHTMLEditor *editor;
        EContentEditor *cnt_editor;
        ESource *source;
-       const gchar *identity_uid;
+       gchar *identity_uid;
        const gchar *content;
 
        g_return_if_fail (E_IS_MSG_COMPOSER (composer));
@@ -4728,7 +4756,7 @@ e_msg_composer_set_body (EMsgComposer *composer,
        /* Disable signature */
        priv->disable_signature = TRUE;
 
-       identity_uid = e_composer_header_table_get_identity_uid (table);
+       identity_uid = e_composer_header_table_dup_identity_uid (table, NULL, NULL);
        source = e_composer_header_table_ref_source (table, identity_uid);
 
        content = _("The composer contains a non-text message body, which cannot be edited.");
@@ -4761,6 +4789,7 @@ e_msg_composer_set_body (EMsgComposer *composer,
        }
 
        g_object_unref (source);
+       g_free (identity_uid);
 }
 
 /**
@@ -5246,12 +5275,12 @@ e_msg_composer_get_message_draft_finish (EMsgComposer *composer,
 CamelInternetAddress *
 e_msg_composer_get_from (EMsgComposer *composer)
 {
-       CamelInternetAddress *inet_address = NULL;
+       CamelInternetAddress *inet_address;
        ESourceMailIdentity *mail_identity;
        EComposerHeaderTable *table;
        ESource *source;
        const gchar *extension_name;
-       const gchar *uid;
+       gchar *uid, *alias_name = NULL, *alias_address = NULL;
        gchar *name;
        gchar *address;
 
@@ -5259,25 +5288,43 @@ e_msg_composer_get_from (EMsgComposer *composer)
 
        table = e_msg_composer_get_header_table (composer);
 
-       uid = e_composer_header_table_get_identity_uid (table);
+       uid = e_composer_header_table_dup_identity_uid (table, &alias_name, &alias_address);
+
        source = e_composer_header_table_ref_source (table, uid);
        g_return_val_if_fail (source != NULL, NULL);
 
        extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
        mail_identity = e_source_get_extension (source, extension_name);
 
-       name = e_source_mail_identity_dup_name (mail_identity);
-       address = e_source_mail_identity_dup_address (mail_identity);
+       if (alias_name) {
+               name = alias_name;
+               alias_name = NULL;
+       } else {
+               name = e_source_mail_identity_dup_name (mail_identity);
+       }
+
+       if (!name)
+               name = e_source_mail_identity_dup_name (mail_identity);
+
+       if (alias_address) {
+               address = alias_address;
+               alias_address = NULL;
+       } else {
+               address = e_source_mail_identity_dup_address (mail_identity);
+       }
 
        g_object_unref (source);
 
-       if (name != NULL && address != NULL) {
+       if (address != NULL) {
                inet_address = camel_internet_address_new ();
                camel_internet_address_add (inet_address, name, address);
        }
 
+       g_free (uid);
        g_free (name);
        g_free (address);
+       g_free (alias_name);
+       g_free (alias_address);
 
        return inet_address;
 }
diff --git a/src/e-util/e-mail-identity-combo-box.c b/src/e-util/e-mail-identity-combo-box.c
index 4f8d8b1..eed26b6 100644
--- a/src/e-util/e-mail-identity-combo-box.c
+++ b/src/e-util/e-mail-identity-combo-box.c
@@ -46,6 +46,7 @@ struct _EMailIdentityComboBoxPrivate {
        gulong source_removed_handler_id;
 
        gboolean allow_none;
+       gboolean allow_aliases;
 
        guint refresh_idle_id;
 
@@ -54,13 +55,17 @@ struct _EMailIdentityComboBoxPrivate {
 
 enum {
        PROP_0,
+       PROP_ALLOW_ALIASES,
        PROP_ALLOW_NONE,
        PROP_REGISTRY
 };
 
 enum {
        COLUMN_DISPLAY_NAME,
-       COLUMN_UID
+       COLUMN_COMBO_ID,
+       COLUMN_UID,
+       COLUMN_NAME,
+       COLUMN_ADDRESS
 };
 
 G_DEFINE_TYPE (
@@ -172,6 +177,12 @@ mail_identity_combo_box_set_property (GObject *object,
                                       GParamSpec *pspec)
 {
        switch (property_id) {
+               case PROP_ALLOW_ALIASES:
+                       e_mail_identity_combo_box_set_allow_aliases (
+                               E_MAIL_IDENTITY_COMBO_BOX (object),
+                               g_value_get_boolean (value));
+                       return;
+
                case PROP_ALLOW_NONE:
                        e_mail_identity_combo_box_set_allow_none (
                                E_MAIL_IDENTITY_COMBO_BOX (object),
@@ -195,6 +206,13 @@ mail_identity_combo_box_get_property (GObject *object,
                                       GParamSpec *pspec)
 {
        switch (property_id) {
+               case PROP_ALLOW_ALIASES:
+                       g_value_set_boolean (
+                               value,
+                               e_mail_identity_combo_box_get_allow_aliases (
+                               E_MAIL_IDENTITY_COMBO_BOX (object)));
+                       return;
+
                case PROP_ALLOW_NONE:
                        g_value_set_boolean (
                                value,
@@ -267,9 +285,9 @@ mail_identity_combo_box_constructed (GObject *object)
        combo_box = GTK_COMBO_BOX (object);
        cell_layout = GTK_CELL_LAYOUT (object);
 
-       list_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
+       list_store = gtk_list_store_new (5, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, 
G_TYPE_STRING);
        gtk_combo_box_set_model (combo_box, GTK_TREE_MODEL (list_store));
-       gtk_combo_box_set_id_column (combo_box, COLUMN_UID);
+       gtk_combo_box_set_id_column (combo_box, COLUMN_COMBO_ID);
        g_object_unref (list_store);
 
        cell_renderer = gtk_cell_renderer_text_new ();
@@ -296,6 +314,17 @@ e_mail_identity_combo_box_class_init (EMailIdentityComboBoxClass *class)
 
        g_object_class_install_property (
                object_class,
+               PROP_ALLOW_ALIASES,
+               g_param_spec_boolean (
+                       "allow-aliases",
+                       "Allow separate items with identity aliases",
+                       NULL,
+                       FALSE,
+                       G_PARAM_READWRITE |
+                       G_PARAM_STATIC_STRINGS));
+
+       g_object_class_install_property (
+               object_class,
                PROP_ALLOW_NONE,
                g_param_spec_boolean (
                        "allow-none",
@@ -343,6 +372,67 @@ e_mail_identity_combo_box_new (ESourceRegistry *registry)
                "registry", registry, NULL);
 }
 
+static gchar *
+mail_identity_combo_box_build_alias_id (const gchar *identity_uid,
+                                       const gchar *name,
+                                       const gchar *address)
+{
+       g_return_val_if_fail (identity_uid != NULL, NULL);
+
+       if (!address)
+               return g_strdup (identity_uid);
+
+       return g_strconcat (identity_uid, "\n", address, "\n", name, NULL);
+}
+
+static void
+mail_identity_combo_box_add_address (GtkListStore *list_store,
+                                    GHashTable *address_table,
+                                    const gchar *name,
+                                    const gchar *address,
+                                    gboolean is_alias_entry,
+                                    const gchar *identity_uid,
+                                    const gchar *identity_display_name)
+{
+       GtkTreeIter iter;
+       GQueue *queue;
+       GString *string;
+       gchar *alias_id;
+
+       g_return_if_fail (GTK_IS_LIST_STORE (list_store));
+       g_return_if_fail (address_table != NULL);
+
+       if (!address || !*address)
+               return;
+
+       queue = g_hash_table_lookup (address_table, address);
+
+       string = g_string_sized_new (512);
+       if (name && *name)
+               g_string_append_printf (string, "%s <%s>", name, address);
+       else
+               g_string_append_printf (string, "%s", address);
+
+       /* Show the account name for duplicate email addresses. */
+       if (queue != NULL && g_queue_get_length (queue) > 1)
+               g_string_append_printf (string, " (%s)", identity_display_name);
+
+       alias_id = mail_identity_combo_box_build_alias_id (identity_uid, name, address);
+
+       gtk_list_store_append (list_store, &iter);
+
+       gtk_list_store_set (list_store, &iter,
+               COLUMN_DISPLAY_NAME, string->str,
+               COLUMN_COMBO_ID, is_alias_entry ? alias_id : identity_uid,
+               COLUMN_UID, identity_uid,
+               COLUMN_NAME, is_alias_entry ? name : NULL,
+               COLUMN_ADDRESS, is_alias_entry ? address : NULL,
+               -1);
+
+       g_string_free (string, TRUE);
+       g_free (alias_id);
+}
+
 /**
  * e_mail_identity_combo_box_refresh:
  * @combo_box: an #EMailIdentityComboBox
@@ -402,68 +492,103 @@ e_mail_identity_combo_box_refresh (EMailIdentityComboBox *combo_box)
        for (link = list; link != NULL; link = g_list_next (link)) {
                ESourceMailIdentity *extension;
                GQueue *queue;
+               GHashTable *aliases;
                const gchar *address;
 
                source = E_SOURCE (link->data);
                extension = e_source_get_extension (source, extension_name);
                address = e_source_mail_identity_get_address (extension);
 
-               if (address == NULL)
-                       continue;
+               if (address) {
+                       queue = g_hash_table_lookup (address_table, address);
+                       if (queue == NULL) {
+                               queue = g_queue_new ();
+                               g_hash_table_insert (
+                                       address_table,
+                                       g_strdup (address), queue);
+                       }
 
-               queue = g_hash_table_lookup (address_table, address);
-               if (queue == NULL) {
-                       queue = g_queue_new ();
-                       g_hash_table_insert (
-                               address_table,
-                               g_strdup (address), queue);
+                       g_queue_push_tail (queue, source);
                }
 
-               g_queue_push_tail (queue, source);
+               if (!e_mail_identity_combo_box_get_allow_aliases (combo_box))
+                       continue;
+
+               aliases = e_source_mail_identity_get_aliases_as_hash_table (extension);
+               if (aliases) {
+                       GHashTableIter iter;
+                       gpointer key;
+
+                       g_hash_table_iter_init (&iter, aliases);
+                       while (g_hash_table_iter_next (&iter, &key, NULL)) {
+                               address = key;
+
+                               if (address && *address) {
+                                       queue = g_hash_table_lookup (address_table, address);
+                                       if (queue) {
+                                               if (!g_queue_find (queue, source))
+                                                       g_queue_push_tail (queue, source);
+                                       } else {
+                                               queue = g_queue_new ();
+                                               g_hash_table_insert (
+                                                       address_table,
+                                                       g_strdup (address), queue);
+
+                                               g_queue_push_tail (queue, source);
+                                       }
+                               }
+                       }
+                       g_hash_table_destroy (aliases);
+               }
        }
 
        for (link = list; link != NULL; link = g_list_next (link)) {
                ESourceMailIdentity *extension;
-               GtkTreeIter iter;
-               GQueue *queue;
-               GString *string;
                const gchar *address;
-               const gchar *display_name;
                const gchar *name;
                const gchar *uid;
+               const gchar *display_name;
+               gchar *aliases;
 
                source = E_SOURCE (link->data);
 
+               uid = e_source_get_uid (source);
+               display_name = e_source_get_display_name (source);
                extension = e_source_get_extension (source, extension_name);
                name = e_source_mail_identity_get_name (extension);
                address = e_source_mail_identity_get_address (extension);
 
-               if (address == NULL)
+               mail_identity_combo_box_add_address (GTK_LIST_STORE (tree_model),
+                       address_table, name, address, FALSE, uid, display_name);
+
+               if (!e_mail_identity_combo_box_get_allow_aliases (combo_box))
                        continue;
 
-               queue = g_hash_table_lookup (address_table, address);
+               aliases = e_source_mail_identity_dup_aliases (extension);
+               if (aliases && *aliases) {
+                       CamelInternetAddress *inet_address;
+                       gint ii, len;
 
-               display_name = e_source_get_display_name (source);
-               uid = e_source_get_uid (source);
+                       inet_address = camel_internet_address_new ();
+                       len = camel_address_decode (CAMEL_ADDRESS (inet_address), aliases);
 
-               string = g_string_sized_new (512);
-               if (name && *name)
-                       g_string_append_printf (string, "%s <%s>", name, address);
-               else
-                       g_string_append_printf (string, "%s", address);
+                       for (ii = 0; ii < len; ii++) {
+                               const gchar *alias_name = NULL, *alias_address = NULL;
 
-               /* Show the account name for duplicate email addresses. */
-               if (queue != NULL && g_queue_get_length (queue) > 1)
-                       g_string_append_printf (string, " (%s)", display_name);
+                               if (camel_internet_address_get (inet_address, ii, &alias_name, 
&alias_address) &&
+                                   alias_address && *alias_address) {
+                                       if (!alias_name || !*alias_name)
+                                               alias_name = name;
 
-               gtk_list_store_append (GTK_LIST_STORE (tree_model), &iter);
+                                       mail_identity_combo_box_add_address (GTK_LIST_STORE (tree_model),
+                                               address_table, alias_name, alias_address, TRUE, uid, 
display_name);
+                               }
+                       }
 
-               gtk_list_store_set (
-                       GTK_LIST_STORE (tree_model), &iter,
-                       COLUMN_DISPLAY_NAME, string->str,
-                       COLUMN_UID, uid, -1);
+                       g_clear_object (&inet_address);
+               }
 
-               g_string_free (string, TRUE);
+               g_free (aliases);
        }
 
        g_hash_table_destroy (address_table);
@@ -478,7 +603,9 @@ e_mail_identity_combo_box_refresh (EMailIdentityComboBox *combo_box)
                gtk_list_store_set (
                        GTK_LIST_STORE (tree_model), &iter,
                        COLUMN_DISPLAY_NAME, _("None"),
-                       COLUMN_UID, "", -1);
+                       COLUMN_UID, "",
+                       COLUMN_COMBO_ID, "",
+                       -1);
        }
 
        /* Try and restore the previous selected source, or else pick
@@ -561,6 +688,142 @@ e_mail_identity_combo_box_set_allow_none (EMailIdentityComboBox *combo_box,
 }
 
 /**
+ * e_mail_identity_combo_box_get_allow_aliases:
+ * @combo_box: an #EMailIdentityComboBox
+ *
+ * Returns whether to show also aliases of the mail identities.
+ *
+ * Returns: whether to show also aliases of the mail identities
+ *
+ * Since: 3.24
+ **/
+gboolean
+e_mail_identity_combo_box_get_allow_aliases (EMailIdentityComboBox *combo_box)
+{
+       g_return_val_if_fail (E_IS_MAIL_IDENTITY_COMBO_BOX (combo_box), FALSE);
+
+       return combo_box->priv->allow_aliases;
+}
+
+/**
+ * e_mail_identity_combo_box_set_allow_aliases:
+ * @combo_box: an #EMailIdentityComboBox
+ * @allow_aliases: whether to show also aliases of the mail identities
+ *
+ * Sets whether to show also aliases of the mail identities.
+ *
+ * Changing this property will automatically rebuild the combo box model.
+ *
+ * Since: 3.24
+ **/
+void
+e_mail_identity_combo_box_set_allow_aliases (EMailIdentityComboBox *combo_box,
+                                            gboolean allow_aliases)
+{
+       g_return_if_fail (E_IS_MAIL_IDENTITY_COMBO_BOX (combo_box));
+
+       if (allow_aliases == combo_box->priv->allow_aliases)
+               return;
+
+       combo_box->priv->allow_aliases = allow_aliases;
+
+       g_object_notify (G_OBJECT (combo_box), "allow-aliases");
+
+       e_mail_identity_combo_box_refresh (combo_box);
+}
+
+/**
+ * e_mail_identity_combo_box_get_active_uid:
+ * @combo_box: an #EMailIdentityComboBox
+ * @identity_uid: (out) (transfer full): identity UID of the currently active item
+ * @alias_name: (out) (nullable) (transfer full): alias name of the currently active item
+ * @alias_address: (out) (nullable) (transfer full): alias address of the currently active item
+ *
+ * Sets identity UID, used name and used address for the currently
+ * active item in the @combo_box. Both @alias_name and @alias_address
+ * are optional.
+ *
+ * Returns: Whether any item was selected. If %FALSE is returned, then
+ *   the values of the output arguments are unchanged. Free the returned
+ *   values with g_free() when done with them.
+ *
+ * Since: 3.24
+ **/
+gboolean
+e_mail_identity_combo_box_get_active_uid (EMailIdentityComboBox *combo_box,
+                                         gchar **identity_uid,
+                                         gchar **alias_name,
+                                         gchar **alias_address)
+{
+       GtkTreeIter iter;
+       gchar *name = NULL, *address = NULL;
+
+       g_return_val_if_fail (E_IS_MAIL_IDENTITY_COMBO_BOX (combo_box), FALSE);
+       g_return_val_if_fail (identity_uid != NULL, FALSE);
+
+       if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo_box), &iter))
+               return FALSE;
+
+       gtk_tree_model_get (gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)), &iter,
+               COLUMN_UID, identity_uid,
+               COLUMN_NAME, &name,
+               COLUMN_ADDRESS, &address,
+               -1);
+
+       if (alias_name)
+               *alias_name = name;
+       else
+               g_free (name);
+
+       if (alias_address)
+               *alias_address = address;
+       else
+               g_free (address);
+
+       return TRUE;
+}
+
+/**
+ * e_mail_identity_combo_box_set_active_uid:
+ * @combo_box: an #EMailIdentityComboBox
+ * @identity_uid: identity UID to select
+ * @alias_name: (nullable): alias name to select
+ * @alias_address: (nullable): alias address to select
+ *
+ * Selects an item which corresponds to @identity_uid. If the @alias_address
+ * is specified, then it will try to select an alias entry with this address
+ * for this identity UID. If no such can be found, then picks the main
+ * @identity_uid item instead.
+ *
+ * Returns: Whether such identity_uid had been found and selected.
+ *
+ * Since: 3.24
+ **/
+gboolean
+e_mail_identity_combo_box_set_active_uid (EMailIdentityComboBox *combo_box,
+                                         const gchar *identity_uid,
+                                         const gchar *alias_name,
+                                         const gchar *alias_address)
+{
+       gchar *alias_id;
+       gboolean found;
+
+       g_return_val_if_fail (E_IS_MAIL_IDENTITY_COMBO_BOX (combo_box), FALSE);
+       g_return_val_if_fail (identity_uid != NULL, FALSE);
+
+       alias_id = mail_identity_combo_box_build_alias_id (identity_uid, alias_name, alias_address);
+
+       found = gtk_combo_box_set_active_id (GTK_COMBO_BOX (combo_box), alias_id);
+
+       g_free (alias_id);
+
+       if (!found && alias_address)
+               found = gtk_combo_box_set_active_id (GTK_COMBO_BOX (combo_box), identity_uid);
+
+       return found;
+}
+
+/**
  * e_mail_identity_combo_box_get_refreshing:
  * @combo_box: an #EMailIdentityComboBox
  *
diff --git a/src/e-util/e-mail-identity-combo-box.h b/src/e-util/e-mail-identity-combo-box.h
index 4b37774..5f704e0 100644
--- a/src/e-util/e-mail-identity-combo-box.h
+++ b/src/e-util/e-mail-identity-combo-box.h
@@ -79,6 +79,21 @@ gboolean     e_mail_identity_combo_box_get_allow_none
 void           e_mail_identity_combo_box_set_allow_none
                                        (EMailIdentityComboBox *combo_box,
                                         gboolean allow_none);
+gboolean       e_mail_identity_combo_box_get_allow_aliases
+                                       (EMailIdentityComboBox *combo_box);
+void           e_mail_identity_combo_box_set_allow_aliases
+                                       (EMailIdentityComboBox *combo_box,
+                                        gboolean allow_aliases);
+gboolean       e_mail_identity_combo_box_get_active_uid
+                                       (EMailIdentityComboBox *combo_box,
+                                        gchar **identity_uid,
+                                        gchar **alias_name,
+                                        gchar **alias_address);
+gboolean       e_mail_identity_combo_box_set_active_uid
+                                       (EMailIdentityComboBox *combo_box,
+                                        const gchar *identity_uid,
+                                        const gchar *alias_name,
+                                        const gchar *alias_address);
 gboolean       e_mail_identity_combo_box_get_refreshing
                                        (EMailIdentityComboBox *combo_box);
 
diff --git a/src/e-util/e-mail-signature-combo-box.c b/src/e-util/e-mail-signature-combo-box.c
index 92949b8..8ba4428 100644
--- a/src/e-util/e-mail-signature-combo-box.c
+++ b/src/e-util/e-mail-signature-combo-box.c
@@ -32,11 +32,15 @@ struct _EMailSignatureComboBoxPrivate {
        ESourceRegistry *registry;
        guint refresh_idle_id;
        gchar *identity_uid;
+       gchar *identity_name;
+       gchar *identity_address;
 };
 
 enum {
        PROP_0,
        PROP_IDENTITY_UID,
+       PROP_IDENTITY_NAME,
+       PROP_IDENTITY_ADDRESS,
        PROP_REGISTRY
 };
 
@@ -162,6 +166,18 @@ mail_signature_combo_box_set_property (GObject *object,
                                g_value_get_string (value));
                        return;
 
+               case PROP_IDENTITY_NAME:
+                       e_mail_signature_combo_box_set_identity_name (
+                               E_MAIL_SIGNATURE_COMBO_BOX (object),
+                               g_value_get_string (value));
+                       return;
+
+               case PROP_IDENTITY_ADDRESS:
+                       e_mail_signature_combo_box_set_identity_address (
+                               E_MAIL_SIGNATURE_COMBO_BOX (object),
+                               g_value_get_string (value));
+                       return;
+
                case PROP_REGISTRY:
                        mail_signature_combo_box_set_registry (
                                E_MAIL_SIGNATURE_COMBO_BOX (object),
@@ -186,6 +202,20 @@ mail_signature_combo_box_get_property (GObject *object,
                                E_MAIL_SIGNATURE_COMBO_BOX (object)));
                        return;
 
+               case PROP_IDENTITY_NAME:
+                       g_value_set_string (
+                               value,
+                               e_mail_signature_combo_box_get_identity_name (
+                               E_MAIL_SIGNATURE_COMBO_BOX (object)));
+                       return;
+
+               case PROP_IDENTITY_ADDRESS:
+                       g_value_set_string (
+                               value,
+                               e_mail_signature_combo_box_get_identity_address (
+                               E_MAIL_SIGNATURE_COMBO_BOX (object)));
+                       return;
+
                case PROP_REGISTRY:
                        g_value_set_object (
                                value,
@@ -230,6 +260,8 @@ mail_signature_combo_box_finalize (GObject *object)
        priv = E_MAIL_SIGNATURE_COMBO_BOX_GET_PRIVATE (object);
 
        g_free (priv->identity_uid);
+       g_free (priv->identity_name);
+       g_free (priv->identity_address);
 
        /* Chain up to parent's finalize() method. */
        G_OBJECT_CLASS (e_mail_signature_combo_box_parent_class)->
@@ -300,6 +332,28 @@ e_mail_signature_combo_box_class_init (EMailSignatureComboBoxClass *class)
 
        g_object_class_install_property (
                object_class,
+               PROP_IDENTITY_NAME,
+               g_param_spec_string (
+                       "identity-name",
+                       "Identity Name",
+                       NULL,
+                       NULL,
+                       G_PARAM_READWRITE |
+                       G_PARAM_STATIC_STRINGS));
+
+       g_object_class_install_property (
+               object_class,
+               PROP_IDENTITY_ADDRESS,
+               g_param_spec_string (
+                       "identity-address",
+                       "Identity Address",
+                       NULL,
+                       NULL,
+                       G_PARAM_READWRITE |
+                       G_PARAM_STATIC_STRINGS));
+
+       g_object_class_install_property (
+               object_class,
                PROP_REGISTRY,
                g_param_spec_object (
                        "registry",
@@ -423,14 +477,27 @@ e_mail_signature_combo_box_get_identity_uid (EMailSignatureComboBox *combo_box)
        return combo_box->priv->identity_uid;
 }
 
-void
-e_mail_signature_combo_box_set_identity_uid (EMailSignatureComboBox *combo_box,
-                                             const gchar *identity_uid)
+static void
+mail_signature_combo_box_emit_changed_for_autogenerated (EMailSignatureComboBox *combo_box)
 {
        const gchar *active_id;
 
        g_return_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box));
 
+       /* If "Autogenerated" is selected, emit a "changed" signal as
+        * a hint to whomever is listening to reload the signature. */
+       active_id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (combo_box));
+       if (g_strcmp0 (active_id, E_MAIL_SIGNATURE_AUTOGENERATED_UID) == 0)
+               g_signal_emit_by_name (combo_box, "changed");
+}
+
+static void
+mail_signature_combo_box_set_identity_uid (EMailSignatureComboBox *combo_box,
+                                          const gchar *identity_uid,
+                                          gboolean can_emit_changed)
+{
+       g_return_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box));
+
        if (g_strcmp0 (combo_box->priv->identity_uid, identity_uid) == 0)
                return;
 
@@ -439,11 +506,108 @@ e_mail_signature_combo_box_set_identity_uid (EMailSignatureComboBox *combo_box,
 
        g_object_notify (G_OBJECT (combo_box), "identity-uid");
 
-       /* If "Autogenerated" is selected, emit a "changed" signal as
-        * a hint to whomever is listening to reload the signature. */
-       active_id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (combo_box));
-       if (g_strcmp0 (active_id, E_MAIL_SIGNATURE_AUTOGENERATED_UID) == 0)
-               g_signal_emit_by_name (combo_box, "changed");
+       if (can_emit_changed)
+               mail_signature_combo_box_emit_changed_for_autogenerated (combo_box);
+}
+
+void
+e_mail_signature_combo_box_set_identity_uid (EMailSignatureComboBox *combo_box,
+                                             const gchar *identity_uid)
+{
+       g_return_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box));
+
+       mail_signature_combo_box_set_identity_uid (combo_box, identity_uid, TRUE);
+}
+
+const gchar *
+e_mail_signature_combo_box_get_identity_name (EMailSignatureComboBox *combo_box)
+{
+       g_return_val_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box), NULL);
+
+       return combo_box->priv->identity_name;
+}
+
+static void
+mail_signature_combo_box_set_identity_name (EMailSignatureComboBox *combo_box,
+                                           const gchar *identity_name,
+                                           gboolean can_emit_changed)
+{
+       g_return_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box));
+
+       if (g_strcmp0 (combo_box->priv->identity_name, identity_name) == 0)
+               return;
+
+       g_free (combo_box->priv->identity_name);
+       combo_box->priv->identity_name = g_strdup (identity_name);
+
+       g_object_notify (G_OBJECT (combo_box), "identity-name");
+
+       if (can_emit_changed)
+               mail_signature_combo_box_emit_changed_for_autogenerated (combo_box);
+}
+
+void
+e_mail_signature_combo_box_set_identity_name (EMailSignatureComboBox *combo_box,
+                                             const gchar *identity_name)
+{
+       g_return_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box));
+
+       mail_signature_combo_box_set_identity_name (combo_box, identity_name, TRUE);
+}
+
+const gchar *
+e_mail_signature_combo_box_get_identity_address (EMailSignatureComboBox *combo_box)
+{
+       g_return_val_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box), NULL);
+
+       return combo_box->priv->identity_address;
+}
+
+static void
+mail_signature_combo_box_set_identity_address (EMailSignatureComboBox *combo_box,
+                                              const gchar *identity_address,
+                                              gboolean can_emit_changed)
+{
+       g_return_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box));
+
+       if (g_strcmp0 (combo_box->priv->identity_address, identity_address) == 0)
+               return;
+
+       g_free (combo_box->priv->identity_address);
+       combo_box->priv->identity_address = g_strdup (identity_address);
+
+       g_object_notify (G_OBJECT (combo_box), "identity-address");
+
+       if (can_emit_changed)
+               mail_signature_combo_box_emit_changed_for_autogenerated (combo_box);
+}
+
+void
+e_mail_signature_combo_box_set_identity_address (EMailSignatureComboBox *combo_box,
+                                                const gchar *identity_address)
+{
+       g_return_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box));
+
+       mail_signature_combo_box_set_identity_address (combo_box, identity_address, TRUE);
+}
+
+void
+e_mail_signature_combo_box_set_identity (EMailSignatureComboBox *combo_box,
+                                        const gchar *identity_uid,
+                                        const gchar *identity_name,
+                                        const gchar *identity_address)
+{
+       g_return_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box));
+
+       g_object_freeze_notify (G_OBJECT (combo_box));
+
+       mail_signature_combo_box_set_identity_uid (combo_box, identity_uid, FALSE);
+       mail_signature_combo_box_set_identity_name (combo_box, identity_name, FALSE);
+       mail_signature_combo_box_set_identity_address (combo_box, identity_address, FALSE);
+
+       g_object_thaw_notify (G_OBJECT (combo_box));
+
+       mail_signature_combo_box_emit_changed_for_autogenerated (combo_box);
 }
 
 /**************** e_mail_signature_combo_box_load_selected() *****************/
@@ -473,6 +637,8 @@ mail_signature_combo_box_autogenerate (EMailSignatureComboBox *combo_box,
        GString *buffer;
        const gchar *extension_name;
        const gchar *identity_uid;
+       const gchar *identity_name;
+       const gchar *identity_address;
        const gchar *text;
        gchar *escaped;
 
@@ -512,13 +678,19 @@ mail_signature_combo_box_autogenerate (EMailSignatureComboBox *combo_box,
 
        buffer = g_string_sized_new (512);
 
-       text = e_source_mail_identity_get_name (extension);
+       identity_name = e_mail_signature_combo_box_get_identity_name (combo_box);
+       identity_address = e_mail_signature_combo_box_get_identity_address (combo_box);
+
+       if (identity_address && !*identity_address)
+               identity_address = NULL;
+
+       text = (identity_address && identity_name && *identity_name) ? identity_name : 
e_source_mail_identity_get_name (extension);
        escaped = (text != NULL) ? g_markup_escape_text (text, -1) : NULL;
        if (escaped != NULL && *escaped != '\0')
                g_string_append (buffer, escaped);
        g_free (escaped);
 
-       text = e_source_mail_identity_get_address (extension);
+       text = identity_address ? identity_address : e_source_mail_identity_get_address (extension);
        escaped = (text != NULL) ? g_markup_escape_text (text, -1) : NULL;
        if (escaped != NULL && *escaped != '\0')
                g_string_append_printf (
diff --git a/src/e-util/e-mail-signature-combo-box.h b/src/e-util/e-mail-signature-combo-box.h
index dff5a98..62c440a 100644
--- a/src/e-util/e-mail-signature-combo-box.h
+++ b/src/e-util/e-mail-signature-combo-box.h
@@ -75,6 +75,21 @@ const gchar *        e_mail_signature_combo_box_get_identity_uid
 void           e_mail_signature_combo_box_set_identity_uid
                                        (EMailSignatureComboBox *combo_box,
                                         const gchar *identity_uid);
+const gchar *  e_mail_signature_combo_box_get_identity_name
+                                       (EMailSignatureComboBox *combo_box);
+void           e_mail_signature_combo_box_set_identity_name
+                                       (EMailSignatureComboBox *combo_box,
+                                        const gchar *identity_name);
+const gchar *  e_mail_signature_combo_box_get_identity_address
+                                       (EMailSignatureComboBox *combo_box);
+void           e_mail_signature_combo_box_set_identity_address
+                                       (EMailSignatureComboBox *combo_box,
+                                        const gchar *identity_address);
+void           e_mail_signature_combo_box_set_identity
+                                       (EMailSignatureComboBox *combo_box,
+                                        const gchar *identity_uid,
+                                        const gchar *identity_name,
+                                        const gchar *identity_address);
 void           e_mail_signature_combo_box_load_selected
                                        (EMailSignatureComboBox *combo_box,
                                         gint io_priority,
diff --git a/src/libemail-engine/e-mail-session.c b/src/libemail-engine/e-mail-session.c
index fc612bc..b34edab 100644
--- a/src/libemail-engine/e-mail-session.c
+++ b/src/libemail-engine/e-mail-session.c
@@ -1376,6 +1376,7 @@ mail_session_forward_to_sync (CamelSession *session,
        struct _camel_header_raw *xev;
        gboolean success;
        gchar *subject;
+       gchar *alias_name = NULL, *alias_address = NULL;
 
        g_return_val_if_fail (folder != NULL, FALSE);
        g_return_val_if_fail (message != NULL, FALSE);
@@ -1395,7 +1396,7 @@ mail_session_forward_to_sync (CamelSession *session,
 
        /* This returns a new ESource reference. */
        source = em_utils_guess_mail_identity_with_recipients (
-               registry, message, folder, NULL);
+               registry, message, folder, NULL, &alias_name, &alias_address);
        if (source == NULL) {
                g_set_error (
                        error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
@@ -1406,8 +1407,16 @@ mail_session_forward_to_sync (CamelSession *session,
 
        extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
        extension = e_source_get_extension (source, extension_name);
-       from_address = e_source_mail_identity_get_address (extension);
-       from_name = e_source_mail_identity_get_name (extension);
+       if (alias_address) {
+               from_name = alias_name;
+               from_address = alias_address;
+       } else {
+               from_name = e_source_mail_identity_get_name (extension);
+               from_address = e_source_mail_identity_get_address (extension);
+       }
+
+       if (!from_name || !*from_name)
+               from_name = e_source_mail_identity_get_name (extension);
 
        forward = camel_mime_message_new ();
 
@@ -1518,6 +1527,8 @@ mail_session_forward_to_sync (CamelSession *session,
        camel_message_info_unref (info);
 
        g_object_unref (source);
+       g_free (alias_address);
+       g_free (alias_name);
 
        return success;
 }
diff --git a/src/libemail-engine/e-mail-utils.c b/src/libemail-engine/e-mail-utils.c
index 862ec00..8fc3632 100644
--- a/src/libemail-engine/e-mail-utils.c
+++ b/src/libemail-engine/e-mail-utils.c
@@ -431,7 +431,9 @@ em_utils_guess_mail_identity (ESourceRegistry *registry,
 static gboolean
 mail_account_in_recipients (ESourceRegistry *registry,
                             ESource *source,
-                            GHashTable *recipients)
+                            GHashTable *recipients,
+                           gchar **identity_name,
+                           gchar **identity_address)
 {
        ESourceExtension *extension;
        const gchar *extension_name;
@@ -466,31 +468,69 @@ mail_account_in_recipients (ESourceRegistry *registry,
        address = e_source_mail_identity_dup_address (
                E_SOURCE_MAIL_IDENTITY (extension));
 
-       g_object_unref (source);
-
        if (address != NULL) {
                match = g_hash_table_contains (recipients, address);
                g_free (address);
        }
 
+       if (!match) {
+               gchar *aliases;
+
+               aliases = e_source_mail_identity_dup_aliases (E_SOURCE_MAIL_IDENTITY (extension));
+               if (aliases) {
+                       CamelInternetAddress *inet_address;
+                       gint ii, len;
+
+                       inet_address = camel_internet_address_new ();
+                       len = camel_address_decode (CAMEL_ADDRESS (inet_address), aliases);
+
+                       for (ii = 0; ii < len && !match; ii++) {
+                               const gchar *name = NULL, *email = NULL;
+
+                               if (camel_internet_address_get (inet_address, ii, &name, &email) && email && 
*email) {
+                                       match = g_hash_table_contains (recipients, email);
+                                       if (match) {
+                                               if (identity_name)
+                                                       *identity_name = g_strdup (name);
+                                               if (identity_address)
+                                                       *identity_address = g_strdup (email);
+                                       }
+                               }
+                       }
+
+                       g_clear_object (&inet_address);
+                       g_free (aliases);
+               }
+       }
+
+       g_object_unref (source);
+
        return match;
 }
 
-ESource *
-em_utils_guess_mail_account_with_recipients_and_sort (ESourceRegistry *registry,
-                                                      CamelMimeMessage *message,
-                                                      CamelFolder *folder,
-                                                      const gchar *message_uid,
-                                                      EMailUtilsSortSourcesFunc sort_func,
-                                                      gpointer sort_func_data)
+static ESource *
+guess_mail_account_with_recipients_and_sort (ESourceRegistry *registry,
+                                            CamelMimeMessage *message,
+                                            CamelFolder *folder,
+                                            const gchar *message_uid,
+                                            gchar **identity_name,
+                                            gchar **identity_address,
+                                            EMailUtilsSortSourcesFunc sort_func,
+                                            gpointer sort_func_data)
 {
+       const gchar *recipt_types[] = {
+               CAMEL_RECIPIENT_TYPE_TO,
+               CAMEL_RECIPIENT_TYPE_CC,
+               CAMEL_RECIPIENT_TYPE_BCC,
+               NULL
+       };
        ESource *source = NULL;
        GHashTable *recipients;
        CamelInternetAddress *addr;
        GList *list, *iter;
        const gchar *extension_name;
-       const gchar *type;
        const gchar *key;
+       gint ii;
 
        /* This policy is subject to debate and tweaking,
         * but please also document the rational here. */
@@ -502,22 +542,14 @@ em_utils_guess_mail_account_with_recipients_and_sort (ESourceRegistry *registry,
         * Only the keys matter here; the values just need to be non-NULL. */
        recipients = g_hash_table_new (g_str_hash, g_str_equal);
 
-       type = CAMEL_RECIPIENT_TYPE_TO;
-       addr = camel_mime_message_get_recipients (message, type);
-       if (addr != NULL) {
-               gint index = 0;
-
-               while (camel_internet_address_get (addr, index++, NULL, &key))
-                       g_hash_table_add (recipients, (gpointer) key);
-       }
-
-       type = CAMEL_RECIPIENT_TYPE_CC;
-       addr = camel_mime_message_get_recipients (message, type);
-       if (addr != NULL) {
-               gint index = 0;
+       for (ii = 0; recipt_types[ii]; ii++) {
+               addr = camel_mime_message_get_recipients (message, recipt_types[ii]);
+               if (addr != NULL) {
+                       gint index = 0;
 
-               while (camel_internet_address_get (addr, index++, NULL, &key))
-                       g_hash_table_add (recipients, (gpointer) key);
+                       while (camel_internet_address_get (addr, index++, NULL, &key))
+                               g_hash_table_add (recipients, (gpointer) key);
+               }
        }
 
        /* First Preference: We were given a folder that maps to an
@@ -531,7 +563,7 @@ em_utils_guess_mail_account_with_recipients_and_sort (ESourceRegistry *registry,
        if (source == NULL)
                goto second_preference;
 
-       if (mail_account_in_recipients (registry, source, recipients))
+       if (mail_account_in_recipients (registry, source, recipients, identity_name, identity_address))
                goto exit;
 
 second_preference:
@@ -553,7 +585,7 @@ second_preference:
        for (iter = list; iter != NULL; iter = g_list_next (iter)) {
                ESource *temp = E_SOURCE (iter->data);
 
-               if (mail_account_in_recipients (registry, temp, recipients)) {
+               if (mail_account_in_recipients (registry, temp, recipients, identity_name, identity_address)) 
{
                        source = g_object_ref (temp);
                        break;
                }
@@ -575,10 +607,23 @@ exit:
 }
 
 ESource *
+em_utils_guess_mail_account_with_recipients_and_sort (ESourceRegistry *registry,
+                                                     CamelMimeMessage *message,
+                                                     CamelFolder *folder,
+                                                     const gchar *message_uid,
+                                                     EMailUtilsSortSourcesFunc sort_func,
+                                                     gpointer sort_func_data)
+{
+       return guess_mail_account_with_recipients_and_sort (registry, message, folder, message_uid, NULL, 
NULL, sort_func, sort_func_data);
+}
+
+ESource *
 em_utils_guess_mail_identity_with_recipients_and_sort (ESourceRegistry *registry,
                                                        CamelMimeMessage *message,
                                                        CamelFolder *folder,
                                                        const gchar *message_uid,
+                                                      gchar **identity_name,
+                                                      gchar **identity_address,
                                                        EMailUtilsSortSourcesFunc sort_func,
                                                        gpointer sort_func_data)
 {
@@ -590,8 +635,8 @@ em_utils_guess_mail_identity_with_recipients_and_sort (ESourceRegistry *registry
        g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
        g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), NULL);
 
-       source = em_utils_guess_mail_account_with_recipients_and_sort (
-               registry, message, folder, message_uid, sort_func, sort_func_data);
+       source = guess_mail_account_with_recipients_and_sort (
+               registry, message, folder, message_uid, identity_name, identity_address, sort_func, 
sort_func_data);
 
        if (source == NULL)
                return NULL;
@@ -630,9 +675,11 @@ ESource *
 em_utils_guess_mail_identity_with_recipients (ESourceRegistry *registry,
                                               CamelMimeMessage *message,
                                               CamelFolder *folder,
-                                              const gchar *message_uid)
+                                              const gchar *message_uid,
+                                             gchar **identity_name,
+                                             gchar **identity_address)
 {
-       return em_utils_guess_mail_identity_with_recipients_and_sort (registry, message, folder, message_uid, 
NULL, NULL);
+       return em_utils_guess_mail_identity_with_recipients_and_sort (registry, message, folder, message_uid, 
identity_name, identity_address, NULL, NULL);
 }
 
 ESource *
diff --git a/src/libemail-engine/e-mail-utils.h b/src/libemail-engine/e-mail-utils.h
index 95796d3..ac90883 100644
--- a/src/libemail-engine/e-mail-utils.h
+++ b/src/libemail-engine/e-mail-utils.h
@@ -56,7 +56,9 @@ ESource *     em_utils_guess_mail_identity_with_recipients
                                                (ESourceRegistry *registry,
                                                 CamelMimeMessage *message,
                                                 CamelFolder *folder,
-                                                const gchar *message_uid);
+                                                const gchar *message_uid,
+                                                gchar **identity_name,
+                                                gchar **identity_address);
 ESource *      em_utils_guess_mail_account_with_recipients_and_sort
                                                (ESourceRegistry *registry,
                                                 CamelMimeMessage *message,
@@ -69,6 +71,8 @@ ESource *     em_utils_guess_mail_identity_with_recipients_and_sort
                                                 CamelMimeMessage *message,
                                                 CamelFolder *folder,
                                                 const gchar *message_uid,
+                                                gchar **identity_name,
+                                                gchar **identity_address,
                                                 EMailUtilsSortSourcesFunc sort_func,
                                                 gpointer sort_func_data);
 ESource *      em_utils_ref_mail_identity_for_store
diff --git a/src/mail/e-mail-config-identity-page.c b/src/mail/e-mail-config-identity-page.c
index 7c60091..ab43f47 100644
--- a/src/mail/e-mail-config-identity-page.c
+++ b/src/mail/e-mail-config-identity-page.c
@@ -41,6 +41,10 @@ struct _EMailConfigIdentityPagePrivate {
        GtkWidget *name_entry;          /* not referenced */
        GtkWidget *address_entry;       /* not referenced */
        GtkWidget *reply_to_entry;      /* not referenced */
+       GtkWidget *aliases_treeview;    /* not referenced */
+       GtkWidget *aliases_add_button;  /* not referenced */
+       GtkWidget *aliases_edit_button; /* not referenced */
+       GtkWidget *aliases_remove_button; /* not referenced */
 };
 
 enum {
@@ -112,6 +116,218 @@ mail_config_identity_page_add_signature_cb (GtkButton *button,
 }
 
 static void
+mail_config_identity_page_add_alias_clicked_cb (GtkWidget *button,
+                                               gpointer user_data)
+{
+       EMailConfigIdentityPage *page = user_data;
+       GtkTreeModel *model;
+       GtkTreeView *tree_view;
+       GtkTreeViewColumn *column;
+       GtkTreePath *path;
+       GtkTreeIter iter;
+
+       g_return_if_fail (E_IS_MAIL_CONFIG_IDENTITY_PAGE (page));
+
+       tree_view = GTK_TREE_VIEW (page->priv->aliases_treeview);
+       model = gtk_tree_view_get_model (tree_view);
+
+       gtk_list_store_append (GTK_LIST_STORE (model), &iter);
+
+       path = gtk_tree_model_get_path (model, &iter);
+       column = gtk_tree_view_get_column (tree_view, 0);
+       gtk_tree_view_set_cursor (tree_view, path, column, TRUE);
+       gtk_tree_view_row_activated (tree_view, path, column);
+       gtk_tree_path_free (path);
+}
+
+static void
+mail_config_identity_page_edit_alias_clicked_cb (GtkWidget *button,
+                                                gpointer user_data)
+{
+       EMailConfigIdentityPage *page = user_data;
+       GtkTreeSelection *selection;
+       GtkTreeModel *model;
+       GtkTreePath *path;
+       GtkTreeIter iter;
+       GtkTreeViewColumn *focus_col;
+       GtkTreeView *treeview;
+
+       g_return_if_fail (E_IS_MAIL_CONFIG_IDENTITY_PAGE (page));
+
+       treeview = GTK_TREE_VIEW (page->priv->aliases_treeview);
+       selection = gtk_tree_view_get_selection (treeview);
+       if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+               return;
+
+       focus_col = gtk_tree_view_get_column (treeview, 0);
+       path = gtk_tree_model_get_path (model, &iter);
+
+       if (path) {
+               gtk_tree_view_set_cursor (treeview, path, focus_col, TRUE);
+               gtk_tree_path_free (path);
+       }
+}
+
+static void
+mail_config_identity_page_remove_alias_clicked_cb (GtkWidget *button,
+                                                  gpointer user_data)
+{
+       EMailConfigIdentityPage *page = user_data;
+       GtkTreeSelection *selection;
+       GtkTreeModel *model;
+       GtkTreeIter iter;
+       GtkTreePath *path;
+       gboolean valid = FALSE;
+       gint len;
+
+       g_return_if_fail (E_IS_MAIL_CONFIG_IDENTITY_PAGE (page));
+
+       selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (page->priv->aliases_treeview));
+       if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+               return;
+
+       /* Get the path and move to the previous node */
+       path = gtk_tree_model_get_path (model, &iter);
+       if (path)
+               valid = gtk_tree_path_prev (path);
+
+       gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+
+       len = gtk_tree_model_iter_n_children (model, NULL);
+       if (len > 0) {
+               if (gtk_list_store_iter_is_valid (GTK_LIST_STORE (model), &iter)) {
+                       gtk_tree_selection_select_iter (selection, &iter);
+               } else {
+                       if (path && valid) {
+                               gtk_tree_model_get_iter (model, &iter, path);
+                               gtk_tree_selection_select_iter (selection, &iter);
+                       }
+               }
+       } else {
+               gtk_widget_set_sensitive (page->priv->aliases_edit_button, FALSE);
+               gtk_widget_set_sensitive (page->priv->aliases_remove_button, FALSE);
+       }
+
+       gtk_widget_grab_focus (page->priv->aliases_treeview);
+       gtk_tree_path_free (path);
+
+       e_mail_config_page_changed (E_MAIL_CONFIG_PAGE (page));
+}
+
+static void
+mail_config_identity_page_aliases_cell_edited_cb (GtkCellRendererText *cell,
+                                                 gchar *path_string,
+                                                 gchar *new_text,
+                                                 gpointer user_data)
+{
+       EMailConfigIdentityPage *page = user_data;
+       GtkTreeModel *model;
+       GtkTreeIter iter;
+
+       g_return_if_fail (E_IS_MAIL_CONFIG_IDENTITY_PAGE (page));
+
+       model = gtk_tree_view_get_model (GTK_TREE_VIEW (page->priv->aliases_treeview));
+       gtk_tree_model_get_iter_from_string (model, &iter, path_string);
+
+       if (!new_text || !(*g_strstrip (new_text))) {
+               mail_config_identity_page_remove_alias_clicked_cb (NULL, page);
+       } else {
+               gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, new_text, -1);
+               e_mail_config_page_changed (E_MAIL_CONFIG_PAGE (page));
+       }
+}
+
+static void
+mail_config_identity_page_aliases_cell_editing_canceled_cb (GtkCellRenderer *cell,
+                                                           gpointer user_data)
+{
+       EMailConfigIdentityPage *page = user_data;
+       GtkTreeSelection *selection;
+       GtkTreeModel *model;
+       GtkTreeIter iter;
+       gchar *text = NULL;
+
+       g_return_if_fail (E_IS_MAIL_CONFIG_IDENTITY_PAGE (page));
+
+       selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (page->priv->aliases_treeview));
+       if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+               return;
+
+       gtk_tree_model_get (model, &iter, 0, &text, -1);
+
+       if (!text || !*text)
+               mail_config_identity_page_remove_alias_clicked_cb (NULL, page);
+
+       g_free (text);
+}
+
+static void
+mail_config_identity_page_aliases_selection_changed_cb (GtkTreeSelection *selection,
+                                                       gpointer user_data)
+{
+       EMailConfigIdentityPage *page = user_data;
+       GtkTreeModel *model;
+       GtkTreeIter iter;
+
+       g_return_if_fail (E_IS_MAIL_CONFIG_IDENTITY_PAGE (page));
+
+       if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+               gtk_widget_set_sensitive (page->priv->aliases_edit_button, TRUE);
+               gtk_widget_set_sensitive (page->priv->aliases_remove_button, TRUE);
+       } else {
+               gtk_widget_set_sensitive (page->priv->aliases_edit_button, FALSE);
+               gtk_widget_set_sensitive (page->priv->aliases_remove_button, FALSE);
+       }
+}
+
+static void
+mail_config_identity_page_fill_aliases (EMailConfigIdentityPage *page,
+                                       ESourceMailIdentity *extension)
+{
+       GtkListStore *list_store;
+       GtkTreeIter iter;
+       CamelInternetAddress *inetaddress;
+       gchar *aliases;
+       gint ii, len;
+
+       g_return_if_fail (E_IS_MAIL_CONFIG_IDENTITY_PAGE (page));
+       g_return_if_fail (E_IS_SOURCE_MAIL_IDENTITY (extension));
+
+       aliases = e_source_mail_identity_dup_aliases (extension);
+       if (!aliases)
+               return;
+
+       inetaddress = camel_internet_address_new ();
+       len = camel_address_decode (CAMEL_ADDRESS (inetaddress), aliases);
+       g_free (aliases);
+
+       if (len <= 0) {
+               g_clear_object (&inetaddress);
+               return;
+       }
+
+       list_store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (page->priv->aliases_treeview)));
+
+       for (ii = 0; ii < len; ii++) {
+               const gchar *name = NULL, *email = NULL;
+
+               if (camel_internet_address_get (inetaddress, ii, &name, &email)) {
+                       gchar *formatted;
+
+                       formatted = camel_internet_address_format_address (name, email);
+                       if (formatted && *formatted) {
+                               gtk_list_store_append (list_store, &iter);
+                               gtk_list_store_set (list_store, &iter, 0, formatted, -1);
+                       }
+
+                       g_free (formatted);
+               }
+       }
+
+       g_clear_object (&inetaddress);
+}
+
+static void
 mail_config_identity_page_set_registry (EMailConfigIdentityPage *page,
                                         ESourceRegistry *registry)
 {
@@ -251,19 +467,11 @@ mail_config_identity_page_dispose (GObject *object)
 
        priv = E_MAIL_CONFIG_IDENTITY_PAGE_GET_PRIVATE (object);
 
-       if (priv->identity_source != NULL) {
-               g_object_unref (priv->identity_source);
-               priv->identity_source = NULL;
-       }
-
-       if (priv->registry != NULL) {
-               g_object_unref (priv->registry);
-               priv->registry = NULL;
-       }
+       g_clear_object (&priv->identity_source);
+       g_clear_object (&priv->registry);
 
        /* Chain up to parent's dispose() method. */
-       G_OBJECT_CLASS (e_mail_config_identity_page_parent_class)->
-               dispose (object);
+       G_OBJECT_CLASS (e_mail_config_identity_page_parent_class)->dispose (object);
 }
 
 static void
@@ -274,8 +482,12 @@ mail_config_identity_page_constructed (GObject *object)
        ESourceRegistry *registry;
        ESourceMailIdentity *extension;
        GtkLabel *label;
+       GtkTreeModel *model;
+       GtkTreeSelection *selection;
+       GtkCellRenderer *renderer;
        GtkWidget *widget;
        GtkWidget *container;
+       GtkWidget *scrolledwindow;
        GtkSizeGroup *size_group;
        const gchar *extension_name;
        const gchar *text;
@@ -578,9 +790,99 @@ mail_config_identity_page_constructed (GObject *object)
                widget, "clicked",
                G_CALLBACK (mail_config_identity_page_add_signature_cb), page);
 
-       g_object_unref (size_group);
+       widget = gtk_label_new_with_mnemonic (_("A_liases:"));
+       gtk_widget_set_margin_left (widget, 12);
+       gtk_size_group_add_widget (size_group, widget);
+       gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.0);
+       gtk_grid_attach (GTK_GRID (container), widget, 0, 4, 1, 1);
+       gtk_widget_show (widget);
 
-       e_extensible_load_extensions (E_EXTENSIBLE (page));
+       label = GTK_LABEL (widget);
+
+       widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
+       gtk_grid_attach (GTK_GRID (container), widget, 1, 4, 2, 1);
+       gtk_widget_show (widget);
+
+       container = widget;
+
+       scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
+       gtk_box_pack_start (GTK_BOX (container), scrolledwindow, TRUE, TRUE, 0);
+       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow), GTK_POLICY_AUTOMATIC, 
GTK_POLICY_AUTOMATIC);
+       gtk_widget_show (scrolledwindow);
+
+       model = GTK_TREE_MODEL (gtk_list_store_new (1, G_TYPE_STRING));
+       widget = gtk_tree_view_new_with_model (model);
+       gtk_container_add (GTK_CONTAINER (scrolledwindow), widget);
+       gtk_widget_show (widget);
+
+       gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget);
+
+       g_object_unref (model);
+
+       renderer = gtk_cell_renderer_text_new ();
+       gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (widget), -1, "Aliases",
+               renderer, "text", 0, NULL);
+       g_object_set (renderer, "editable", TRUE, NULL);
+       g_signal_connect (
+               renderer, "edited",
+               G_CALLBACK (mail_config_identity_page_aliases_cell_edited_cb), page);
+       g_signal_connect (
+               renderer, "editing-canceled",
+               G_CALLBACK (mail_config_identity_page_aliases_cell_editing_canceled_cb), page);
+       gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (widget), FALSE);
+       gtk_tree_view_column_set_expand (gtk_tree_view_get_column (GTK_TREE_VIEW (widget), 0), TRUE);
+
+       selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
+       gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
+       g_signal_connect (
+               selection, "changed",
+               G_CALLBACK (mail_config_identity_page_aliases_selection_changed_cb), page);
+
+       page->priv->aliases_treeview = widget;
+
+       widget = gtk_button_box_new (GTK_ORIENTATION_VERTICAL);
+       g_object_set (G_OBJECT (widget),
+               "halign", GTK_ALIGN_START,
+               "hexpand", FALSE,
+               "valign", GTK_ALIGN_START,
+               "vexpand", FALSE,
+               NULL);
+       gtk_container_add (GTK_CONTAINER (container), widget);
+       gtk_widget_show (widget);
+
+       container = widget;
+
+       widget = e_dialog_button_new_with_icon ("list-add", _("Add"));
+       gtk_container_add (GTK_CONTAINER (container), widget);
+       gtk_widget_show (widget);
+
+       g_signal_connect (widget, "clicked",
+               G_CALLBACK (mail_config_identity_page_add_alias_clicked_cb), page);
+
+       page->priv->aliases_add_button = widget;
+
+       widget = gtk_button_new_with_mnemonic (_("Edit"));
+       gtk_container_add (GTK_CONTAINER (container), widget);
+       gtk_widget_show (widget);
+
+       g_signal_connect (widget, "clicked",
+               G_CALLBACK (mail_config_identity_page_edit_alias_clicked_cb), page);
+
+       page->priv->aliases_edit_button = widget;
+
+       widget = e_dialog_button_new_with_icon ("list-remove", _("Remove"));
+       gtk_container_add (GTK_CONTAINER (container), widget);
+       gtk_widget_show (widget);
+
+       g_signal_connect (widget, "clicked",
+               G_CALLBACK (mail_config_identity_page_remove_alias_clicked_cb), page);
+
+       page->priv->aliases_remove_button = widget;
+
+       mail_config_identity_page_aliases_selection_changed_cb (selection, page);
+       mail_config_identity_page_fill_aliases (page, extension);
+
+       g_object_unref (size_group);
 
        widget = gtk_check_button_new_with_mnemonic (_("_Look up mail server details based on the entered 
e-mail address"));
        g_object_set (G_OBJECT (widget),
@@ -597,6 +899,8 @@ mail_config_identity_page_constructed (GObject *object)
        page->priv->autodiscover_check = widget;
 
        gtk_container_add (GTK_CONTAINER (page), widget);
+
+       e_extensible_load_extensions (E_EXTENSIBLE (page));
 }
 
 static gboolean
@@ -675,12 +979,77 @@ mail_config_identity_page_check_complete (EMailConfigPage *page)
 }
 
 static void
+mail_config_identity_page_commit_changes (EMailConfigPage *cfg_page,
+                                         GQueue *source_queue)
+{
+       EMailConfigIdentityPage *page;
+       ESource *identity_source;
+       ESourceMailIdentity *identity_extension;
+       GtkTreeModel *model;
+       GtkTreeIter iter;
+       CamelInternetAddress *inetaddress_complete;
+       gboolean valid;
+
+       g_return_if_fail (E_IS_MAIL_CONFIG_IDENTITY_PAGE (cfg_page));
+
+       page = E_MAIL_CONFIG_IDENTITY_PAGE (cfg_page);
+       identity_source = e_mail_config_identity_page_get_identity_source (page);
+       identity_extension = e_source_get_extension (identity_source, E_SOURCE_EXTENSION_MAIL_IDENTITY);
+
+       inetaddress_complete = camel_internet_address_new ();
+
+       model = gtk_tree_view_get_model (GTK_TREE_VIEW (page->priv->aliases_treeview));
+       for (valid = gtk_tree_model_get_iter_first (model, &iter);
+            valid;
+            valid = gtk_tree_model_iter_next (model, &iter)) {
+               gchar *raw = NULL;
+
+               gtk_tree_model_get (model, &iter, 0, &raw, -1);
+
+               if (raw && (*g_strstrip (raw))) {
+                       CamelInternetAddress *inetaddress;
+                       CamelAddress *address;
+
+                       inetaddress = camel_internet_address_new ();
+                       address = CAMEL_ADDRESS (inetaddress);
+
+                       if (camel_address_unformat (address, raw) > 0) {
+                               gint ii, len = camel_address_length (address);
+
+                               for (ii = 0; ii < len; ii++) {
+                                       const gchar *name = NULL, *email = NULL;
+
+                                       if (camel_internet_address_get (inetaddress, ii, &name, &email))
+                                               camel_internet_address_add (inetaddress_complete, name, 
email);
+                               }
+                       }
+
+                       g_object_unref (inetaddress);
+               }
+
+               g_free (raw);
+       }
+
+       if (camel_address_length (CAMEL_ADDRESS (inetaddress_complete)) > 0) {
+               gchar *aliases;
+
+               aliases = camel_address_encode (CAMEL_ADDRESS (inetaddress_complete));
+               e_source_mail_identity_set_aliases (identity_extension, aliases);
+
+               g_free (aliases);
+       } else {
+               e_source_mail_identity_set_aliases (identity_extension, NULL);
+       }
+
+       g_object_unref (inetaddress_complete);
+}
+
+static void
 e_mail_config_identity_page_class_init (EMailConfigIdentityPageClass *class)
 {
        GObjectClass *object_class;
 
-       g_type_class_add_private (
-               class, sizeof (EMailConfigIdentityPagePrivate));
+       g_type_class_add_private (class, sizeof (EMailConfigIdentityPagePrivate));
 
        object_class = G_OBJECT_CLASS (class);
        object_class->set_property = mail_config_identity_page_set_property;
@@ -779,6 +1148,7 @@ e_mail_config_identity_page_interface_init (EMailConfigPageInterface *iface)
        iface->title = _("Identity");
        iface->sort_order = E_MAIL_CONFIG_IDENTITY_PAGE_SORT_ORDER;
        iface->check_complete = mail_config_identity_page_check_complete;
+       iface->commit_changes = mail_config_identity_page_commit_changes;
 }
 
 static void
diff --git a/src/mail/em-composer-utils.c b/src/mail/em-composer-utils.c
index 8b9334a..82db435 100644
--- a/src/mail/em-composer-utils.c
+++ b/src/mail/em-composer-utils.c
@@ -448,13 +448,14 @@ composer_presend_check_identity (EMsgComposer *composer,
        EClientCache *client_cache;
        ESourceRegistry *registry;
        ESource *source;
-       const gchar *uid;
+       gchar *uid;
        gboolean success = TRUE;
 
        table = e_msg_composer_get_header_table (composer);
 
-       uid = e_composer_header_table_get_identity_uid (table);
+       uid = e_composer_header_table_dup_identity_uid (table, NULL, NULL);
        source = e_composer_header_table_ref_source (table, uid);
+       g_free (uid);
        g_return_val_if_fail (source != NULL, FALSE);
 
        client_cache = e_composer_header_table_ref_client_cache (table);
@@ -1078,7 +1079,7 @@ em_utils_composer_save_to_drafts_cb (EMsgComposer *composer,
        EComposerHeaderTable *table;
        ESource *source;
        const gchar *local_drafts_folder_uri;
-       const gchar *identity_uid;
+       gchar *identity_uid;
        gchar *drafts_folder_uri = NULL;
 
        async_context = g_slice_new0 (AsyncContext);
@@ -1089,7 +1090,7 @@ em_utils_composer_save_to_drafts_cb (EMsgComposer *composer,
 
        table = e_msg_composer_get_header_table (composer);
 
-       identity_uid = e_composer_header_table_get_identity_uid (table);
+       identity_uid = e_composer_header_table_dup_identity_uid (table, NULL, NULL);
        source = e_composer_header_table_ref_source (table, identity_uid);
 
        /* Get the selected identity's preferred Drafts folder. */
@@ -1128,6 +1129,8 @@ em_utils_composer_save_to_drafts_cb (EMsgComposer *composer,
 
                g_free (drafts_folder_uri);
        }
+
+       g_free (identity_uid);
 }
 
 static void
@@ -1353,7 +1356,7 @@ set_up_new_composer (EMsgComposer *composer,
        }
 
        e_composer_header_table_set_subject (table, subject);
-       e_composer_header_table_set_identity_uid (table, identity);
+       e_composer_header_table_set_identity_uid (table, identity, NULL, NULL);
 
        em_utils_apply_send_account_override_to_composer (composer, folder);
 
@@ -1528,7 +1531,7 @@ msg_composer_created_with_mailto_cb (GObject *source_object,
 
                if (source != NULL) {
                        const gchar *uid = e_source_get_uid (source);
-                       e_composer_header_table_set_identity_uid (table, uid);
+                       e_composer_header_table_set_identity_uid (table, uid, NULL, NULL);
                        g_object_unref (source);
                }
        }
@@ -2365,7 +2368,7 @@ em_utils_redirect_message (EMsgComposer *composer,
        source = em_utils_check_send_account_override (shell, message, NULL);
        if (!source)
                source = em_utils_guess_mail_identity_with_recipients_and_sort (
-                       registry, message, NULL, NULL, sort_sources_by_ui, shell);
+                       registry, message, NULL, NULL, NULL, NULL, sort_sources_by_ui, shell);
 
        if (source != NULL) {
                identity_uid = e_source_dup_uid (source);
@@ -2422,11 +2425,13 @@ static void
 reply_setup_composer (EMsgComposer *composer,
                      CamelMimeMessage *message,
                      const gchar *identity_uid,
+                     const gchar *identity_name,
+                     const gchar *identity_address,
                      CamelInternetAddress *to,
                      CamelInternetAddress *cc,
                      CamelFolder *folder,
                      const gchar *message_uid,
-                    CamelNNTPAddress *postto)
+                     CamelNNTPAddress *postto)
 {
        gchar *message_id, *references;
        EDestination **tov, **ccv;
@@ -2462,7 +2467,7 @@ reply_setup_composer (EMsgComposer *composer,
        table = e_msg_composer_get_header_table (composer);
        e_composer_header_table_set_subject (table, subject);
        e_composer_header_table_set_destinations_to (table, tov);
-       e_composer_header_table_set_identity_uid (table, identity_uid);
+       e_composer_header_table_set_identity_uid (table, identity_uid, identity_name, identity_address);
 
        /* Add destinations instead of setting, so we don't remove
         * automatic CC addresses that have already been added. */
@@ -2767,6 +2772,52 @@ concat_unique_addrs (CamelInternetAddress *dest,
        }
 }
 
+static void
+add_source_to_recipient_hash (ESourceRegistry *registry,
+                             GHashTable *rcpt_hash,
+                             const gchar *address,
+                             ESource *default_source,
+                             ESource *source,
+                             gboolean source_is_default,
+                             gboolean source_is_enabled)
+{
+       ESource *cached_source;
+       gboolean insert_source;
+       gboolean cached_is_default;
+       gboolean cached_is_enabled;
+
+       g_return_if_fail (rcpt_hash != NULL);
+       g_return_if_fail (E_IS_SOURCE (source));
+
+       if (!address || !*address)
+               return;
+
+       cached_source = g_hash_table_lookup (rcpt_hash, address);
+
+       if (cached_source != NULL) {
+               cached_is_default = e_source_equal (cached_source, default_source);
+               cached_is_enabled = e_source_registry_check_enabled (registry, cached_source);
+       } else {
+               cached_is_default = FALSE;
+               cached_is_enabled = FALSE;
+       }
+
+       /* Accounts with identical email addresses that are enabled
+        * take precedence over disabled accounts.  If all accounts
+        * with matching email addresses are disabled, the first
+        * one in the list takes precedence.  The default account
+        * always takes precedence no matter what. */
+       insert_source =
+               source_is_default ||
+               cached_source == NULL ||
+               (source_is_enabled &&
+                !cached_is_enabled &&
+                !cached_is_default);
+
+       if (insert_source)
+               g_hash_table_insert (rcpt_hash, g_strdup (address), g_object_ref (source));
+}
+
 static GHashTable *
 generate_recipient_hash (ESourceRegistry *registry)
 {
@@ -2777,9 +2828,10 @@ generate_recipient_hash (ESourceRegistry *registry)
 
        g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
 
-       rcpt_hash = g_hash_table_new (
-               (GHashFunc) camel_strcase_hash,
-               (GEqualFunc) camel_strcase_equal);
+       rcpt_hash = g_hash_table_new_full (
+               camel_strcase_hash,
+               camel_strcase_equal,
+               g_free, g_object_unref);
 
        default_source = e_source_registry_ref_default_mail_identity (registry);
 
@@ -2788,12 +2840,9 @@ generate_recipient_hash (ESourceRegistry *registry)
 
        for (link = list; link != NULL; link = g_list_next (link)) {
                ESource *source = E_SOURCE (link->data);
-               ESource *cached_source;
                ESourceMailIdentity *extension;
+               GHashTable *aliases;
                const gchar *address;
-               gboolean insert_source;
-               gboolean cached_is_default;
-               gboolean cached_is_enabled;
                gboolean source_is_default;
                gboolean source_is_enabled;
 
@@ -2811,36 +2860,22 @@ generate_recipient_hash (ESourceRegistry *registry)
 
                address = e_source_mail_identity_get_address (extension);
 
-               if (address == NULL)
-                       continue;
+               add_source_to_recipient_hash (registry, rcpt_hash, address, default_source, source, 
source_is_default, source_is_enabled);
 
-               cached_source = g_hash_table_lookup (rcpt_hash, address);
+               aliases = e_source_mail_identity_get_aliases_as_hash_table (extension);
+               if (aliases) {
+                       GHashTableIter iter;
+                       gpointer key;
 
-               if (cached_source != NULL) {
-                       cached_is_default = e_source_equal (
-                               cached_source, default_source);
-                       cached_is_enabled = e_source_registry_check_enabled (
-                               registry, cached_source);
-               } else {
-                       cached_is_default = FALSE;
-                       cached_is_enabled = FALSE;
-               }
+                       g_hash_table_iter_init (&iter, aliases);
+                       while (g_hash_table_iter_next (&iter, &key, NULL)) {
+                               address = key;
 
-               /* Accounts with identical email addresses that are enabled
-                * take precedence over disabled accounts.  If all accounts
-                * with matching email addresses are disabled, the first
-                * one in the list takes precedence.  The default account
-                * always takes precedence no matter what. */
-               insert_source =
-                       source_is_default ||
-                       cached_source == NULL ||
-                       (source_is_enabled &&
-                        !cached_is_enabled &&
-                        !cached_is_default);
+                               add_source_to_recipient_hash (registry, rcpt_hash, address, default_source, 
source, source_is_default, source_is_enabled);
+                       }
 
-               if (insert_source)
-                       g_hash_table_insert (
-                               rcpt_hash, (gchar *) address, source);
+                       g_hash_table_destroy (aliases);
+               }
        }
 
        g_list_free_full (list, (GDestroyNotify) g_object_unref);
@@ -3276,7 +3311,7 @@ em_utils_reply_to_message (EMsgComposer *composer,
        EShell *shell;
        ESourceMailCompositionReplyStyle prefer_reply_style = E_SOURCE_MAIL_COMPOSITION_REPLY_STYLE_DEFAULT;
        ESource *source;
-       gchar *identity_uid = NULL;
+       gchar *identity_uid = NULL, *identity_name = NULL, *identity_address = NULL;
        guint32 flags;
 
        g_return_if_fail (E_IS_MSG_COMPOSER (composer));
@@ -3292,7 +3327,7 @@ em_utils_reply_to_message (EMsgComposer *composer,
        source = em_utils_check_send_account_override (shell, message, folder);
        if (!source)
                source = em_utils_guess_mail_identity_with_recipients_and_sort (
-                       registry, message, folder, message_uid, sort_sources_by_ui, shell);
+                       registry, message, folder, message_uid, &identity_name, &identity_address, 
sort_sources_by_ui, shell);
        if (source != NULL) {
                identity_uid = e_source_dup_uid (source);
                if (e_source_has_extension (source, E_SOURCE_EXTENSION_MAIL_COMPOSITION)) {
@@ -3344,7 +3379,7 @@ em_utils_reply_to_message (EMsgComposer *composer,
                break;
        }
 
-       reply_setup_composer (composer, message, identity_uid, to, cc, folder, message_uid, postto);
+       reply_setup_composer (composer, message, identity_uid, identity_name, identity_address, to, cc, 
folder, message_uid, postto);
        e_msg_composer_add_message_attachments (composer, message, TRUE);
 
        if (postto)
@@ -3355,10 +3390,10 @@ em_utils_reply_to_message (EMsgComposer *composer,
        /* If there was no send-account override */
        if (!identity_uid) {
                EComposerHeaderTable *header_table;
-               const gchar *used_identity_uid;
+               gchar *used_identity_uid;
 
                header_table = e_msg_composer_get_header_table (composer);
-               used_identity_uid = e_composer_header_table_get_identity_uid (header_table);
+               used_identity_uid = e_composer_header_table_dup_identity_uid (header_table, NULL, NULL);
 
                if (used_identity_uid) {
                        source = e_source_registry_ref_source (e_shell_get_registry (shell), 
used_identity_uid);
@@ -3373,6 +3408,8 @@ em_utils_reply_to_message (EMsgComposer *composer,
                                g_object_unref (source);
                        }
                }
+
+               g_free (used_identity_uid);
        }
 
        switch (prefer_reply_style) {
@@ -3415,6 +3452,8 @@ em_utils_reply_to_message (EMsgComposer *composer,
        gtk_widget_show (GTK_WIDGET (composer));
 
        g_free (identity_uid);
+       g_free (identity_name);
+       g_free (identity_address);
 }
 
 static void
@@ -3620,7 +3659,7 @@ em_utils_apply_send_account_override_to_composer (EMsgComposer *composer,
                return;
 
        header_table = e_msg_composer_get_header_table (composer);
-       e_composer_header_table_set_identity_uid (header_table, e_source_get_uid (source));
+       e_composer_header_table_set_identity_uid (header_table, e_source_get_uid (source), NULL, NULL);
 
        g_object_unref (source);
 }
diff --git a/src/modules/itip-formatter/itip-view.c b/src/modules/itip-formatter/itip-view.c
index e6d470a..f494cdb 100644
--- a/src/modules/itip-formatter/itip-view.c
+++ b/src/modules/itip-formatter/itip-view.c
@@ -3104,15 +3104,43 @@ find_to_address (ItipView *view,
                ESource *source = E_SOURCE (link->data);
                icalproperty *prop = NULL;
                icalparameter *param;
-               const gchar *address;
+               gchar *address;
                gchar *text;
 
                extension = e_source_get_extension (source, extension_name);
-               address = e_source_mail_identity_get_address (extension);
+               address = e_source_mail_identity_dup_address (extension);
 
                prop = find_attendee (ical_comp, address);
-               if (prop == NULL)
+               if (!prop) {
+                       GHashTable *aliases;
+
+                       aliases = e_source_mail_identity_get_aliases_as_hash_table (extension);
+                       if (aliases) {
+                               GHashTableIter iter;
+                               gpointer key = NULL;
+
+                               g_hash_table_iter_init (&iter, aliases);
+                               while (g_hash_table_iter_next (&iter, &key, NULL)) {
+                                       const gchar *alias_address = key;
+
+                                       if (alias_address && *alias_address) {
+                                               prop = find_attendee (ical_comp, alias_address);
+                                               if (prop) {
+                                                       g_free (address);
+                                                       address = g_strdup (alias_address);
+                                                       break;
+                                               }
+                                       }
+                               }
+
+                               g_hash_table_destroy (aliases);
+                       }
+               }
+
+               if (!prop) {
+                       g_free (address);
                        continue;
+               }
 
                param = icalproperty_get_first_parameter (prop, ICAL_CN_PARAMETER);
                if (param != NULL)
@@ -3124,7 +3152,7 @@ find_to_address (ItipView *view,
                g_free (text);
                g_strstrip (view->priv->to_address);
 
-               view->priv->my_address = g_strdup (address);
+               view->priv->my_address = address;
 
                param = icalproperty_get_first_parameter (prop, ICAL_RSVP_PARAMETER);
                if (param != NULL &&
@@ -3162,15 +3190,43 @@ find_to_address (ItipView *view,
                ESource *source = E_SOURCE (link->data);
                icalproperty *prop = NULL;
                icalparameter *param;
-               const gchar *address;
+               gchar *address;
                gchar *text;
 
                extension = e_source_get_extension (source, extension_name);
-               address = e_source_mail_identity_get_address (extension);
+               address = e_source_mail_identity_dup_address (extension);
 
                prop = find_attendee_if_sentby (ical_comp, address);
-               if (prop == NULL)
+               if (!prop) {
+                       GHashTable *aliases;
+
+                       aliases = e_source_mail_identity_get_aliases_as_hash_table (extension);
+                       if (aliases) {
+                               GHashTableIter iter;
+                               gpointer key = NULL;
+
+                               g_hash_table_iter_init (&iter, aliases);
+                               while (g_hash_table_iter_next (&iter, &key, NULL)) {
+                                       const gchar *alias_address = key;
+
+                                       if (alias_address && *alias_address) {
+                                               prop = find_attendee_if_sentby (ical_comp, alias_address);
+                                               if (prop) {
+                                                       g_free (address);
+                                                       address = g_strdup (alias_address);
+                                                       break;
+                                               }
+                                       }
+                               }
+
+                               g_hash_table_destroy (aliases);
+                       }
+               }
+
+               if (!prop) {
+                       g_free (address);
                        continue;
+               }
 
                param = icalproperty_get_first_parameter (prop, ICAL_CN_PARAMETER);
                if (param != NULL)
@@ -3182,7 +3238,7 @@ find_to_address (ItipView *view,
                g_free (text);
                g_strstrip (view->priv->to_address);
 
-               view->priv->my_address = g_strdup (address);
+               view->priv->my_address = address;
 
                param = icalproperty_get_first_parameter (prop, ICAL_RSVP_PARAMETER);
                if (param != NULL &&
@@ -3252,19 +3308,45 @@ find_from_address (ItipView *view,
        for (link = list; link != NULL; link = g_list_next (link)) {
                ESource *source = E_SOURCE (link->data);
                ESourceMailIdentity *extension;
+               GHashTable *aliases;
                const gchar *address;
 
                extension = e_source_get_extension (source, extension_name);
                address = e_source_mail_identity_get_address (extension);
 
-               if (address == NULL)
-                       continue;
+               if (address) {
+                       if ((organizer_clean && !g_ascii_strcasecmp (organizer_clean, address))
+                           || (organizer_sentby_clean && !g_ascii_strcasecmp (organizer_sentby_clean, 
address))) {
+                               view->priv->my_address = g_strdup (address);
+
+                               break;
+                       }
+               }
 
-               if ((organizer_clean && !g_ascii_strcasecmp (organizer_clean, address))
-                   || (organizer_sentby_clean && !g_ascii_strcasecmp (organizer_sentby_clean, address))) {
-                       view->priv->my_address = g_strdup (address);
+               aliases = e_source_mail_identity_get_aliases_as_hash_table (extension);
+               if (aliases) {
+                       GHashTableIter iter;
+                       gpointer key = NULL;
+                       gboolean found = FALSE;
+
+                       g_hash_table_iter_init (&iter, aliases);
+                       while (g_hash_table_iter_next (&iter, &key, NULL)) {
+                               const gchar *alias_address = key;
+
+                               if (alias_address && *alias_address) {
+                                       if ((organizer_clean && !g_ascii_strcasecmp (organizer_clean, 
alias_address))
+                                           || (organizer_sentby_clean && !g_ascii_strcasecmp 
(organizer_sentby_clean, alias_address))) {
+                                               view->priv->my_address = g_strdup (alias_address);
+                                               found = TRUE;
+                                               break;
+                                       }
+                               }
+                       }
 
-                       break;
+                       g_hash_table_destroy (aliases);
+
+                       if (found)
+                               break;
                }
        }
 
diff --git a/src/modules/mdn/evolution-mdn.c b/src/modules/mdn/evolution-mdn.c
index 1a8cbad..155b9ec 100644
--- a/src/modules/mdn/evolution-mdn.c
+++ b/src/modules/mdn/evolution-mdn.c
@@ -55,6 +55,7 @@ struct _MdnContext {
        CamelMessageInfo *info;
        CamelMimeMessage *message;
        gchar *notify_to;
+       gchar *identity_address;
 };
 
 typedef enum {
@@ -88,6 +89,7 @@ mdn_context_free (MdnContext *context)
        g_object_unref (context->message);
 
        g_free (context->notify_to);
+       g_free (context->identity_address);
 
        g_slice_free (MdnContext, context);
 }
@@ -206,6 +208,7 @@ mdn_notify_sender (ESource *identity_source,
                    CamelMimeMessage *message,
                    CamelMessageInfo *info,
                    const gchar *notify_to,
+                  const gchar *identity_address,
                    MdnActionMode action_mode,
                    MdnSendingMode sending_mode)
 {
@@ -228,9 +231,9 @@ mdn_notify_sender (ESource *identity_source,
        const gchar *message_subject;
        const gchar *extension_name;
        const gchar *transport_uid;
-       const gchar *self_address;
        const gchar *sent_folder_uri;
        const gchar *hostname;
+       gchar *self_address;
        gchar *receipt_subject;
        gchar *disposition;
        gchar *recipient;
@@ -263,8 +266,10 @@ mdn_notify_sender (ESource *identity_source,
        extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
        extension = e_source_get_extension (identity_source, extension_name);
 
-       self_address = e_source_mail_identity_get_address (
-               E_SOURCE_MAIL_IDENTITY (extension));
+       if (identity_address && *identity_address)
+               self_address = g_strdup (identity_address);
+       else
+               self_address = e_source_mail_identity_dup_address (E_SOURCE_MAIL_IDENTITY (extension));
 
        extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION;
        extension = e_source_get_extension (identity_source, extension_name);
@@ -418,6 +423,7 @@ mdn_notify_sender (ESource *identity_source,
 
        camel_message_info_unref (receipt_info);
 
+       g_free (self_address);
        g_free (message_date);
        g_free (message_id);
 }
@@ -433,6 +439,7 @@ mdn_notify_action_cb (GtkAction *action,
                context->message,
                context->info,
                context->notify_to,
+               context->identity_address,
                MDN_ACTION_MODE_MANUAL,
                MDN_SENDING_MODE_MANUAL);
 
@@ -471,7 +478,7 @@ mdn_message_loaded_cb (EMailReader *reader,
        CamelMessageInfo *info;
        EMdnResponsePolicy response_policy;
        const gchar *extension_name;
-       gchar *notify_to = NULL;
+       gchar *notify_to = NULL, *identity_address = NULL;
 
        backend = e_mail_reader_get_backend (reader);
        session = e_mail_backend_get_session (backend);
@@ -507,8 +514,7 @@ mdn_message_loaded_cb (EMailReader *reader,
                goto exit;
 
        /* This returns a new ESource reference. */
-       source = em_utils_guess_mail_identity_with_recipients (
-               registry, message, folder, message_uid);
+       source = em_utils_guess_mail_identity_with_recipients (registry, message, folder, message_uid, NULL, 
&identity_address);
        if (source == NULL)
                goto exit;
 
@@ -527,9 +533,11 @@ mdn_message_loaded_cb (EMailReader *reader,
                context->folder = g_object_ref (folder);
                context->message = g_object_ref (message);
                context->info = camel_message_info_ref (info);
-
                context->notify_to = notify_to;
+               context->identity_address = identity_address;
+
                notify_to = NULL;
+               identity_address = NULL;
 
                tooltip = g_strdup_printf (
                        _("Send a read receipt to '%s'"),
@@ -563,6 +571,7 @@ exit:
                camel_message_info_unref (info);
 
        g_clear_object (&folder);
+       g_free (identity_address);
        g_free (notify_to);
 }
 
@@ -580,7 +589,7 @@ mdn_message_seen_cb (EMailReader *reader,
        CamelMessageInfo *info;
        EMdnResponsePolicy response_policy;
        const gchar *extension_name;
-       gchar *notify_to = NULL;
+       gchar *notify_to = NULL, *identity_address = NULL;
 
        backend = e_mail_reader_get_backend (reader);
        session = e_mail_backend_get_session (backend);
@@ -601,7 +610,7 @@ mdn_message_seen_cb (EMailReader *reader,
 
        /* This returns a new ESource reference. */
        source = em_utils_guess_mail_identity_with_recipients (
-               registry, message, folder, message_uid);
+               registry, message, folder, message_uid, NULL, &identity_address);
        if (source == NULL)
                goto exit;
 
@@ -613,6 +622,7 @@ mdn_message_seen_cb (EMailReader *reader,
                mdn_notify_sender (
                        source, reader, folder,
                        message, info, notify_to,
+                       identity_address,
                        MDN_ACTION_MODE_AUTOMATIC,
                        MDN_SENDING_MODE_AUTOMATIC);
 
@@ -623,6 +633,7 @@ exit:
                camel_message_info_unref (info);
 
        g_clear_object (&folder);
+       g_free (identity_address);
        g_free (notify_to);
 }
 
diff --git a/src/plugins/mail-to-task/mail-to-task.c b/src/plugins/mail-to-task/mail-to-task.c
index 527698c..71f2b58 100644
--- a/src/plugins/mail-to-task/mail-to-task.c
+++ b/src/plugins/mail-to-task/mail-to-task.c
@@ -41,6 +41,8 @@
 #include <calendar/gui/e-comp-editor.h>
 #include <calendar/gui/itip-utils.h>
 
+#include "libemail-engine/libemail-engine.h"
+
 #define E_SHELL_WINDOW_ACTION_CONVERT_TO_APPOINTMENT(window) \
        E_SHELL_WINDOW_ACTION ((window), "mail-convert-to-appointment")
 #define E_SHELL_WINDOW_ACTION_CONVERT_TO_MEETING(window) \
@@ -270,7 +272,9 @@ set_description (ECalComponent *comp,
 
 static gchar *
 set_organizer (ECalComponent *comp,
-               CamelFolder *folder)
+              CamelMimeMessage *message,
+              CamelFolder *folder,
+              const gchar *message_uid)
 {
        EShell *shell;
        ESource *source = NULL;
@@ -280,11 +284,15 @@ set_organizer (ECalComponent *comp,
        const gchar *address, *name;
        ECalComponentOrganizer organizer = {NULL, NULL, NULL, NULL};
        gchar *mailto = NULL;
+       gchar *identity_name = NULL, *identity_address = NULL;
 
        shell = e_shell_get_default ();
        registry = e_shell_get_registry (shell);
 
-       if (folder != NULL) {
+       source = em_utils_guess_mail_identity_with_recipients (registry, message, folder,
+               message_uid, &identity_name, &identity_address);
+
+       if (!source && folder) {
                CamelStore *store;
 
                store = camel_folder_get_parent_store (folder);
@@ -299,10 +307,17 @@ set_organizer (ECalComponent *comp,
        extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
        extension = e_source_get_extension (source, extension_name);
 
-       name = e_source_mail_identity_get_name (extension);
-       address = e_source_mail_identity_get_address (extension);
+       name = identity_name;
+       if (!name || !*name)
+               name = e_source_mail_identity_get_name (extension);
+
+       address = identity_address;
+       if (!address || !*address) {
+               name = e_source_mail_identity_get_name (extension);
+               address = e_source_mail_identity_get_address (extension);
+       }
 
-       if (name != NULL && address != NULL) {
+       if (address && *address) {
                mailto = g_strconcat ("mailto:";, address, NULL);
                organizer.value = mailto;
                organizer.cn = name;
@@ -310,6 +325,8 @@ set_organizer (ECalComponent *comp,
        }
 
        g_object_unref (source);
+       g_free (identity_name);
+       g_free (identity_address);
 
        return mailto;
 }
@@ -871,12 +888,11 @@ do_mail_to_event (AsyncData *data)
                        icalproperty *icalprop;
                        icalcomponent *icalcomp;
                        struct _manage_comp *mc;
+                       const gchar *message_uid = g_ptr_array_index (uids, i);
 
                        /* retrieve the message from the CamelFolder */
                        /* FIXME Not passing a GCancellable or GError. */
-                       message = camel_folder_get_message_sync (
-                               folder, g_ptr_array_index (uids, i),
-                               NULL, NULL);
+                       message = camel_folder_get_message_sync (folder, message_uid, NULL, NULL);
                        if (!message) {
                                continue;
                        }
@@ -928,7 +944,7 @@ do_mail_to_event (AsyncData *data)
                                gchar *organizer;
 
                                /* set actual user as organizer, to be able to change event's properties */
-                               organizer = set_organizer (comp, data->folder);
+                               organizer = set_organizer (comp, message, data->folder, message_uid);
                                set_attendees (comp, message, organizer);
                                g_free (organizer);
                        }
diff --git a/src/plugins/mailing-list-actions/mailing-list-actions.c 
b/src/plugins/mailing-list-actions/mailing-list-actions.c
index 9affe98..fcad750 100644
--- a/src/plugins/mailing-list-actions/mailing-list-actions.c
+++ b/src/plugins/mailing-list-actions/mailing-list-actions.c
@@ -142,7 +142,7 @@ send_message_composer_created_cb (GObject *source_object,
                table = e_msg_composer_get_header_table (composer);
 
                if (smd->uid)
-                       e_composer_header_table_set_identity_uid (table, smd->uid);
+                       e_composer_header_table_set_identity_uid (table, smd->uid, NULL, NULL);
 
                e_msg_composer_send (composer);
        }
diff --git a/src/plugins/templates/templates.c b/src/plugins/templates/templates.c
index cdd6319..6654bc0 100644
--- a/src/plugins/templates/templates.c
+++ b/src/plugins/templates/templates.c
@@ -1142,13 +1142,13 @@ get_account_templates_folder_uri (EMsgComposer *composer)
 {
        EComposerHeaderTable *table;
        ESource *source;
-       const gchar *identity_uid;
+       gchar *identity_uid;
        gchar *templates_folder_uri = NULL;
 
        g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), NULL);
 
        table = e_msg_composer_get_header_table (composer);
-       identity_uid = e_composer_header_table_get_identity_uid (table);
+       identity_uid = e_composer_header_table_dup_identity_uid (table, NULL, NULL);
        source = e_composer_header_table_ref_source (table, identity_uid);
 
        /* Get the selected identity's preferred Templates folder. */
@@ -1163,6 +1163,8 @@ get_account_templates_folder_uri (EMsgComposer *composer)
                g_object_unref (source);
        }
 
+       g_free (identity_uid);
+
        return templates_folder_uri;
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]