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

Bug#771502: Pre-approval for evolution/3.12.9~git20141130.241663-1



Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Hi,

following the update in evolution-data-server, I’m proposing another one 
in evolution, again fixing a number of crashes and UI bugs, including a RC 
bug.

Upstream also removed the geoclue build-dependency that was no longer 
used.

evolution (3.12.9~git20141130.241663-1) UNRELEASED; urgency=medium

  * New upstream git snapshot from stable branch, includes only bugfixes 
    and translations.
    + Fix crash caused by hidden alert buttons. Closes: #770390.
  * Remove geoclue build-dependency.
  * Update (build-)dependencies on e-d-s to 3.12.9~.

I’m attaching the upstream and Debian changes. Individual upstream 
changes can be found at 
https://git.gnome.org/browse/evolution/log/?h=evolution-3-12

unblock evolution/3.12.9~git20141130.241663-1

Thanks again for your tireless work.
-- 
 .''`.        Josselin Mouette
: :' :
`. `'
  `-
Index: debian/control
===================================================================
--- debian/control	(révision 2640)
+++ debian/control	(copie de travail)
@@ -20,7 +20,6 @@
                dpkg-dev (>= 1.16.1),
                libcamel1.2-dev (>= 3.12.7),
                libchamplain-gtk-0.12-dev,
-               libgeoclue-dev (>= 0.12.0),
                libglib2.0-dev (>= 2.36),
                libgtk-3-dev (>= 3.8.0),
                libgail-3-dev (>= 3.0.2),
Index: debian/changelog
===================================================================
--- debian/changelog	(révision 2640)
+++ debian/changelog	(copie de travail)
@@ -1,3 +1,12 @@
+evolution (3.12.9~git20141130.241663-1) UNRELEASED; urgency=medium
+
+  * New upstream git snapshot from stable branch, includes only bugfixes 
+    and translations.
+    + Fix crash caused by hidden alert buttons. Closes: #770390.
+  * Remove geoclue build-dependency.
+
+ -- Josselin Mouette <joss@debian.org>  Sun, 30 Nov 2014 10:08:31 +0100
+
 evolution (3.12.7-1) unstable; urgency=medium
 
   * New upstream release 3.12.7
diff --git a/AUTHORS b/AUTHORS
index fdf3f54..05fff3e 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -3,7 +3,6 @@ inception at Ximian, Inc. in the late 1990s, and we thank them all.
 
 The Evolution project is currently maintained by:
 
-  Matthew Barnes <mbarnes@redhat.com>
   Milan Crha <mcrha@redhat.com>
   Fabiano Fid�io <fabiano@fidencio.org>
 
diff --git a/MAINTAINERS b/MAINTAINERS
index 5625868..01bab6a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1,4 +1,3 @@
-Matthew Barnes <mbarnes@redhat.com>
 Milan Crha <mcrha@redhat.com>
 
 User Documentation:
diff --git a/NEWS b/NEWS
index 40f3b4e..df7c7bc 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,35 @@
+Evolution 3.12.8 2014-11-10
+---------------------------
+
+Bug Fixes:
+	Bug 729305 - EAlertDialog too wide with wrapped GtkLabel-s (Milan Crha)
+	Bug 737330 - EShellSwitcher: Count with GtkPaned::handle-size for button widths (Milan Crha)
+	Bug 738453 - Inefficient sort by subject in message list (Milan Crha)
+	Bug 738463 - [a11y] Fix various problems with fetching children (Mike Gorse)
+	Bug 650670 - Duplicate entries when contact is in several address books (Milan Crha)
+	Bug 739375 - Crash when sort folder with Due By column (Milan Crha)
+	Bug 739386 - Forward style Inline is missing a line break (Milan Crha)
+	Bug 739364 - Drop references to geoclue (Milan Crha)
+	Bug 676471 - Double free when sorting by date columns in calendar (Milan Crha)
+	Bug 739605 - Remove alert buttons on the alert bar hide (Milan Crha)
+	Bug 739562 - Message composer autosave not updating (Milan Crha)
+
+Miscellaneous:
+	Update AUTHORS, MAINTAINERS, doap, etc. (Matthew Barnes)
+	Address two possible places causing runtime warning on a GSource removal (Milan Crha)
+	cal_comp_util_compare_event_timezones: Do not ask with NULL tzid (Milan Crha)
+	[Mark-All-Read] Save changes to the server immediately (Milan Crha)
+	Avoid automatic mail account update when the application is exiting (Milan Crha)
+
+Translations:
+	Fran Diéguez (gl)
+	Daniel Mustieles (es)
+	Marek Černocký (cs)
+	Aurimas Černius (lt)
+	Kjartan Maraas (nb)
+	Bernd Homuth (de)
+	Guillaume Bernard (fr)
+
 Evolution 3.12.7 2014-10-13
 ---------------------------
 
diff --git a/addressbook/gui/widgets/e-contact-map.c b/addressbook/gui/widgets/e-contact-map.c
index 5ae1fbd..fde0e8b 100644
--- a/addressbook/gui/widgets/e-contact-map.c
+++ b/addressbook/gui/widgets/e-contact-map.c
@@ -26,8 +26,6 @@
 
 #include <champlain/champlain.h>
 #include <champlain-gtk/champlain-gtk.h>
-#include <geoclue/geoclue-address.h>
-#include <geoclue/geoclue-position.h>
 #include <geocode-glib/geocode-glib.h>
 
 #include <clutter/clutter.h>
diff --git a/calendar/alarm-notify/alarm-queue.c b/calendar/alarm-notify/alarm-queue.c
index f52a9ef..7087f8a 100644
--- a/calendar/alarm-notify/alarm-queue.c
+++ b/calendar/alarm-notify/alarm-queue.c
@@ -342,7 +342,8 @@ alarm_queue_discard_alarm_cb (GObject *source,
 
 	g_return_if_fail (client != NULL);
 
-	if (!e_cal_client_discard_alarm_finish (client, result, &error))
+	if (!e_cal_client_discard_alarm_finish (client, result, &error) &&
+	    !g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_NOT_SUPPORTED))
 		g_warning ("Failed to discard alarm at '%s': %s",
 			e_source_get_display_name (e_client_get_source (E_CLIENT (client))),
 			error ? error->message : "Unknown error");
@@ -375,8 +376,7 @@ remove_queued_alarm (CompQueuedAlarms *cqa,
 
 	cqa->queued_alarms = g_slist_delete_link (cqa->queued_alarms, l);
 
-	if (remove_alarm) {
-		GError *error = NULL;
+	if (remove_alarm && !e_client_is_readonly (E_CLIENT (cqa->parent_client->cal_client))) {
 		ECalComponentId *id;
 
 		id = e_cal_component_get_id (cqa->alarms->comp);
@@ -388,16 +388,6 @@ remove_queued_alarm (CompQueuedAlarms *cqa,
 				alarm_queue_discard_alarm_cb, NULL);
 			cqa->expecting_update = FALSE;
 
-			if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_NOT_SUPPORTED)) {
-				g_error_free (error);
-
-			} else if (error != NULL) {
-				g_warning (
-					"%s: Failed to discard alarm: %s",
-					G_STRFUNC, error->message);
-				g_error_free (error);
-			}
-
 			e_cal_component_free_id (id);
 		}
 	}
diff --git a/calendar/gui/comp-util.c b/calendar/gui/comp-util.c
index 16dfd5d..77b31b4 100644
--- a/calendar/gui/comp-util.c
+++ b/calendar/gui/comp-util.c
@@ -150,8 +150,11 @@ cal_comp_util_compare_event_timezones (ECalComponent *comp,
 		/* If the TZIDs differ, we have to compare the UTC offsets
 		 * of the start and end times, using their own timezones and
 		 * the given timezone. */
-		e_cal_client_get_timezone_sync (
-			client, start_datetime.tzid, &start_zone, NULL, NULL);
+		if (start_datetime.tzid)
+			e_cal_client_get_timezone_sync (client, start_datetime.tzid, &start_zone, NULL, NULL);
+		else
+			start_zone = NULL;
+
 		if (start_zone == NULL)
 			goto out;
 
@@ -168,8 +171,11 @@ cal_comp_util_compare_event_timezones (ECalComponent *comp,
 				goto out;
 		}
 
-		e_cal_client_get_timezone_sync (
-			client, end_datetime.tzid, &end_zone, NULL, NULL);
+		if (end_datetime.tzid)
+			e_cal_client_get_timezone_sync (client, end_datetime.tzid, &end_zone, NULL, NULL);
+		else
+			end_zone = NULL;
+
 		if (end_zone == NULL)
 			goto out;
 
diff --git a/calendar/gui/e-cal-model-calendar.c b/calendar/gui/e-cal-model-calendar.c
index b3099cd..b211f4c 100644
--- a/calendar/gui/e-cal-model-calendar.c
+++ b/calendar/gui/e-cal-model-calendar.c
@@ -94,7 +94,7 @@ get_dtend (ECalModelCalendar *model,
 			comp_data->dtend->zone = NULL;
 	}
 
-	return comp_data->dtend;
+	return e_cal_model_copy_cell_date_value (comp_data->dtend);
 }
 
 static gpointer
@@ -400,16 +400,7 @@ cal_model_calendar_duplicate_value (ETableModel *etm,
 
 	switch (col) {
 	case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
-		if (value) {
-			ECellDateEditValue *dv, *orig_dv;
-
-			orig_dv = (ECellDateEditValue *) value;
-			dv = g_new0 (ECellDateEditValue, 1);
-			*dv = *orig_dv;
-
-			return dv;
-		}
-		break;
+		return e_cal_model_copy_cell_date_value (value);
 	case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
 	case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
 		return g_strdup (value);
@@ -432,6 +423,9 @@ cal_model_calendar_free_value (ETableModel *etm,
 
 	switch (col) {
 	case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
+		if (value)
+			g_free (value);
+		break;
 	case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
 	case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
 		break;
diff --git a/calendar/gui/e-cal-model-tasks.c b/calendar/gui/e-cal-model-tasks.c
index f07d9bf..ee6123c 100644
--- a/calendar/gui/e-cal-model-tasks.c
+++ b/calendar/gui/e-cal-model-tasks.c
@@ -207,7 +207,7 @@ get_completed (ECalModelComponent *comp_data)
 			comp_data->completed->zone = NULL;
 	}
 
-	return comp_data->completed;
+	return e_cal_model_copy_cell_date_value (comp_data->completed);
 }
 
 static ECellDateEditValue *
@@ -237,7 +237,7 @@ get_due (ECalModelComponent *comp_data)
 			comp_data->due->zone = NULL;
 	}
 
-	return comp_data->due;
+	return e_cal_model_copy_cell_date_value (comp_data->due);
 }
 
 static gpointer
@@ -1027,16 +1027,7 @@ cal_model_tasks_duplicate_value (ETableModel *etm,
 		return g_strdup (value);
 	case E_CAL_MODEL_TASKS_FIELD_COMPLETED :
 	case E_CAL_MODEL_TASKS_FIELD_DUE :
-		if (value) {
-			ECellDateEditValue *dv, *orig_dv;
-
-			orig_dv = (ECellDateEditValue *) value;
-			dv = g_new0 (ECellDateEditValue, 1);
-			*dv = *orig_dv;
-
-			return dv;
-		}
-		break;
+		return e_cal_model_copy_cell_date_value (value);
 
 	case E_CAL_MODEL_TASKS_FIELD_COMPLETE :
 	case E_CAL_MODEL_TASKS_FIELD_PERCENT :
@@ -1062,6 +1053,9 @@ cal_model_tasks_free_value (ETableModel *etm,
 	switch (col) {
 	case E_CAL_MODEL_TASKS_FIELD_COMPLETED :
 	case E_CAL_MODEL_TASKS_FIELD_DUE :
+		if (value)
+			g_free (value);
+		break;
 	case E_CAL_MODEL_TASKS_FIELD_GEO :
 	case E_CAL_MODEL_TASKS_FIELD_PRIORITY :
 	case E_CAL_MODEL_TASKS_FIELD_STATUS :
diff --git a/calendar/gui/e-cal-model.c b/calendar/gui/e-cal-model.c
index f7f3d6e..05ffef5 100644
--- a/calendar/gui/e-cal-model.c
+++ b/calendar/gui/e-cal-model.c
@@ -540,7 +540,7 @@ get_dtstart (ECalModel *model,
 			comp_data->dtstart->zone = NULL;
 	}
 
-	return comp_data->dtstart;
+	return e_cal_model_copy_cell_date_value (comp_data->dtstart);
 }
 
 static ECellDateEditValue *
@@ -548,40 +548,39 @@ get_datetime_from_utc (ECalModel *model,
                        ECalModelComponent *comp_data,
                        icalproperty_kind propkind,
                        struct icaltimetype (*get_value) (const icalproperty *prop),
-                                                         ECellDateEditValue **buffer)
+		       ECellDateEditValue **buffer)
 {
-	ECalModelPrivate *priv;
-	struct icaltimetype tt_value;
-	icalproperty *prop;
-	ECellDateEditValue *res;
+	g_return_val_if_fail (buffer != NULL, NULL);
 
-	g_return_val_if_fail (buffer!= NULL, NULL);
-
-	if (*buffer)
-		return *buffer;
+	if (!*buffer) {
+		ECalModelPrivate *priv;
+		struct icaltimetype tt_value;
+		icalproperty *prop;
+		ECellDateEditValue *res;
 
-	priv = model->priv;
+		priv = model->priv;
 
-	prop = icalcomponent_get_first_property (comp_data->icalcomp, propkind);
-	if (!prop)
-		return NULL;
+		prop = icalcomponent_get_first_property (comp_data->icalcomp, propkind);
+		if (!prop)
+			return NULL;
 
-	tt_value = get_value (prop);
+		tt_value = get_value (prop);
 
-	/* these are always in UTC, thus convert to default zone, if any and done */
-	if (priv->zone)
-		icaltimezone_convert_time (&tt_value, icaltimezone_get_utc_timezone (), priv->zone);
+		/* these are always in UTC, thus convert to default zone, if any and done */
+		if (priv->zone)
+			icaltimezone_convert_time (&tt_value, icaltimezone_get_utc_timezone (), priv->zone);
 
-	if (!icaltime_is_valid_time (tt_value) || icaltime_is_null_time (tt_value))
-		return NULL;
+		if (!icaltime_is_valid_time (tt_value) || icaltime_is_null_time (tt_value))
+			return NULL;
 
-	res = g_new0 (ECellDateEditValue, 1);
-	res->tt = tt_value;
-	res->zone = NULL;
+		res = g_new0 (ECellDateEditValue, 1);
+		res->tt = tt_value;
+		res->zone = NULL;
 
-	*buffer = res;
+		*buffer = res;
+	}
 
-	return res;
+	return e_cal_model_copy_cell_date_value (*buffer);
 }
 
 static gpointer
@@ -1515,16 +1514,7 @@ cal_model_duplicate_value (ETableModel *etm,
 	case E_CAL_MODEL_FIELD_DTSTART :
 	case E_CAL_MODEL_FIELD_CREATED :
 	case E_CAL_MODEL_FIELD_LASTMODIFIED :
-		if (value) {
-			ECellDateEditValue *dv, *orig_dv;
-
-			orig_dv = (ECellDateEditValue *) value;
-			dv = g_new0 (ECellDateEditValue, 1);
-			*dv = *orig_dv;
-
-			return dv;
-		}
-		break;
+		return e_cal_model_copy_cell_date_value (value);
 	}
 
 	return NULL;
@@ -1548,8 +1538,8 @@ cal_model_free_value (ETableModel *etm,
 	case E_CAL_MODEL_FIELD_HAS_ALARMS :
 	case E_CAL_MODEL_FIELD_ICON :
 	case E_CAL_MODEL_FIELD_COLOR :
-	case E_CAL_MODEL_FIELD_DTSTART:
 		break;
+	case E_CAL_MODEL_FIELD_DTSTART:
 	case E_CAL_MODEL_FIELD_CREATED :
 	case E_CAL_MODEL_FIELD_LASTMODIFIED :
 		if (value)
@@ -4357,3 +4347,20 @@ e_cal_model_set_default_time_func (ECalModel *model,
 	model->priv->get_default_time = func;
 	model->priv->get_default_time_user_data = user_data;
 }
+
+
+ECellDateEditValue *
+e_cal_model_copy_cell_date_value (const ECellDateEditValue *value)
+{
+	ECellDateEditValue *copy;
+
+	if (!value)
+		return NULL;
+
+
+	copy = g_new0 (ECellDateEditValue, 1);
+	copy->tt = value->tt;
+	copy->zone = value->zone;
+
+	return copy;
+}
diff --git a/calendar/gui/e-cal-model.h b/calendar/gui/e-cal-model.h
index 6711c81..98130ed 100644
--- a/calendar/gui/e-cal-model.h
+++ b/calendar/gui/e-cal-model.h
@@ -326,6 +326,10 @@ void		e_cal_model_update_status_message
 						 const gchar *message,
 						 gdouble percent);
 
+ECellDateEditValue *
+		e_cal_model_copy_cell_date_value
+						(const ECellDateEditValue *value);
+
 G_END_DECLS
 
 #endif /* E_CAL_MODEL_H */
diff --git a/calendar/gui/e-cell-date-edit-text.c b/calendar/gui/e-cell-date-edit-text.c
index 1d13953..103e27d 100644
--- a/calendar/gui/e-cell-date-edit-text.c
+++ b/calendar/gui/e-cell-date-edit-text.c
@@ -115,6 +115,7 @@ cell_date_edit_text_get_text (ECellText *cell,
 	ECellDateEditValue *dv = e_table_model_value_at (model, col, row);
 	icaltimezone *timezone;
 	struct tm tmp_tm;
+	gchar *res;
 
 	if (!dv)
 		return g_strdup ("");
@@ -127,9 +128,13 @@ cell_date_edit_text_get_text (ECellText *cell,
 	 * it will be set to the current timezone. See set_value (). */
 	tmp_tm = icaltimetype_to_tm_with_zone (&dv->tt, dv->zone, timezone);
 
-	return e_datetime_format_format_tm (
+	res = e_datetime_format_format_tm (
 		"calendar", "table", dv->tt.is_date ?
 		DTFormatKindDate : DTFormatKindDateTime, &tmp_tm);
+
+	e_table_model_free_value (model, col, dv);
+
+	return res;
 }
 
 static void
diff --git a/calendar/gui/e-month-view.c b/calendar/gui/e-month-view.c
index a159190..265d974 100644
--- a/calendar/gui/e-month-view.c
+++ b/calendar/gui/e-month-view.c
@@ -81,7 +81,7 @@ month_view_cursor_key_down (EWeekView *week_view)
 		if (e_calendar_view_get_selected_time_range (
 			E_CALENDAR_VIEW (week_view), &current, NULL)) {
 
-			current = time_add_week (current, -1);
+			current = time_add_week (current, 1);
 			e_week_view_scroll_a_step (
 				week_view, E_CAL_VIEW_MOVE_PAGE_DOWN);
 			e_week_view_set_selected_time_range_visible (
diff --git a/calendar/gui/ea-calendar-helpers.c b/calendar/gui/ea-calendar-helpers.c
index fec0849..a60751d 100644
--- a/calendar/gui/ea-calendar-helpers.c
+++ b/calendar/gui/ea-calendar-helpers.c
@@ -89,6 +89,10 @@ ea_calendar_helpers_get_cal_view_from (GnomeCanvasItem *canvas_item)
 	/* parent of canvas_item->canvas is the EDayView or EWeekView widget */
 	canvas = canvas_item->canvas;
 	view_widget = gtk_widget_get_parent (GTK_WIDGET (canvas));
+
+	if (view_widget && GTK_IS_BOX (view_widget))
+		view_widget = gtk_widget_get_parent (view_widget);
+
 	if (!view_widget || !E_IS_CALENDAR_VIEW (view_widget))
 		return NULL;
 
diff --git a/calendar/gui/itip-utils.c b/calendar/gui/itip-utils.c
index 7190c05..8620f7e 100644
--- a/calendar/gui/itip-utils.c
+++ b/calendar/gui/itip-utils.c
@@ -132,7 +132,7 @@ itip_get_user_identities (ESourceRegistry *registry)
 
 	extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
 
-	list = e_source_registry_list_sources (registry, extension_name);
+	list = e_source_registry_list_enabled (registry, extension_name);
 
 	identities = g_new0 (gchar *, g_list_length (list) + 1);
 
diff --git a/composer/e-composer-private.c b/composer/e-composer-private.c
index 59e1625..d3b5a74 100644
--- a/composer/e-composer-private.c
+++ b/composer/e-composer-private.c
@@ -192,6 +192,7 @@ e_composer_private_constructed (EMsgComposer *composer)
 	priv->charset = e_composer_get_default_charset ();
 
 	priv->is_from_message = FALSE;
+	priv->disable_signature = FALSE;
 
 	e_composer_actions_init (composer);
 
@@ -883,6 +884,9 @@ composer_load_signature_cb (EMailSignatureComboBox *combo_box,
 		goto exit;
 	}
 
+	if (composer->priv->disable_signature)
+		goto exit;
+
 	/* "Edit as New Message" sets "priv->is_from_message".
 	 * Always put the signature at the bottom for that case. */
 	top_signature =
@@ -1036,8 +1040,9 @@ e_composer_update_signature (EMsgComposer *composer)
 
 	g_return_if_fail (E_IS_MSG_COMPOSER (composer));
 
-	/* Do nothing if we're redirecting a message. */
-	if (composer->priv->redirect)
+	/* Do nothing if we're redirecting a message or we disabled
+	 * the signature on purpose */
+	if (composer->priv->redirect || composer->priv->disable_signature)
 		return;
 
 	table = e_msg_composer_get_header_table (composer);
diff --git a/composer/e-composer-private.h b/composer/e-composer-private.h
index b09e025..5dde038 100644
--- a/composer/e-composer-private.h
+++ b/composer/e-composer-private.h
@@ -98,6 +98,7 @@ struct _EMsgComposerPrivate {
 	CamelMimeMessage *redirect;
 
 	gboolean is_from_message;
+	gboolean disable_signature;
 
 	gchar *selected_signature_uid;
 };
diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c
index 74ca819..f926311 100644
--- a/composer/e-msg-composer.c
+++ b/composer/e-msg-composer.c
@@ -4276,6 +4276,9 @@ e_msg_composer_set_body (EMsgComposer *composer,
 
 	table = e_msg_composer_get_header_table (composer);
 
+	/* Disable signature */
+	priv->disable_signature = TRUE;
+
 	identity_uid = e_composer_header_table_get_identity_uid (table);
 	source = e_composer_header_table_ref_source (table, identity_uid);
 
diff --git a/configure.ac b/configure.ac
index b338750..e9e07a7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,7 +1,7 @@
 dnl Evolution Versions
 m4_define([evo_major_version], [3])
 m4_define([evo_minor_version], [12])
-m4_define([evo_micro_version], [7])
+m4_define([evo_micro_version], [9])
 m4_define([evo_version],
 	[evo_major_version.evo_minor_version.evo_micro_version])
 m4_define([evo_stable_version],
@@ -60,7 +60,6 @@ m4_define([libpst_minimum_version], [0.6.54])
 dnl Optional Packages
 m4_define([champlain_minimum_version], [0.12])
 m4_define([clutter_gtk_minimum_version], [0.90])
-m4_define([geoclue_minimum_version], [0.12.0])
 m4_define([geocode_glib_minimum_version], [3.10])
 m4_define([gladeui_minimum_version], [3.10.0])
 m4_define([gweather_minimum_version], [3.8])
@@ -215,7 +214,6 @@ case "$host" in
 	DL_LIB=''
 	SOFTOKN3_LIB=''
 	CHAMPLAIN_REQUIREMENT=''
-	GEOCLUE_REQUIREMENT=''
 	;;
 *openbsd*|*freebsd*)
 	os_win32=no
@@ -1276,7 +1274,7 @@ fi
 AM_CONDITIONAL(ENABLE_WEATHER, [test "x$enable_weather" != "xno"])
 
 dnl ********************************************************************
-dnl maps in contacts preview requires champlain-gtk, geoclue and clutter
+dnl maps in contacts preview requires champlain-gtk and clutter
 dnl ********************************************************************
 AC_ARG_ENABLE([contact-maps],
 	[AS_HELP_STRING([--enable-contact-maps],
@@ -1298,11 +1296,10 @@ if test "x$enable_contact_maps" = "xyes"; then
 
 	PKG_CHECK_MODULES(
 		[GEO],
-		[geoclue >= geoclue_minimum_version
-		 geocode-glib-1.0 >= geocode_glib_minimum_version],,
+		[geocode-glib-1.0 >= geocode_glib_minimum_version],,
 		[AC_MSG_ERROR([
 
-	geoclue and/or geocode-glib not found.
+	geocode-glib not found.
 
 	If you want to disable the contact maps feature,
 	please append --disable-contact-maps to configure.
diff --git a/e-util/e-activity-proxy.c b/e-util/e-activity-proxy.c
index d0805b2..8ebaed1 100644
--- a/e-util/e-activity-proxy.c
+++ b/e-util/e-activity-proxy.c
@@ -62,11 +62,46 @@ G_DEFINE_TYPE (
 	e_activity_proxy,
 	GTK_TYPE_FRAME)
 
+typedef struct {
+	EActivityProxy *proxy; /* Not referenced */
+	EActivity *activity;   /* Referenced */
+} UnsetTimeoutData;
+
+static void
+unset_timeout_data_free (gpointer ptr)
+{
+	UnsetTimeoutData *utd = ptr;
+
+	if (utd) {
+		g_object_unref (utd->activity);
+		g_free (utd);
+	}
+}
+
+static gboolean
+activity_proxy_unset_timeout_id (gpointer user_data)
+{
+	UnsetTimeoutData *utd = user_data;
+
+	g_return_val_if_fail (utd != NULL, FALSE);
+
+	if (g_source_is_destroyed (g_main_current_source ()))
+		return FALSE;
+
+	g_return_val_if_fail (E_IS_ACTIVITY_PROXY (utd->proxy), FALSE);
+
+	if (g_source_get_id (g_main_current_source ()) == utd->proxy->priv->timeout_id)
+		utd->proxy->priv->timeout_id = 0;
+
+	return FALSE;
+}
+
 static void
 activity_proxy_feedback (EActivityProxy *proxy)
 {
 	EActivity *activity;
 	EActivityState state;
+	UnsetTimeoutData *utd;
 
 	activity = e_activity_proxy_get_activity (proxy);
 	g_return_if_fail (E_IS_ACTIVITY (activity));
@@ -78,11 +113,15 @@ activity_proxy_feedback (EActivityProxy *proxy)
 	if (proxy->priv->timeout_id > 0)
 		g_source_remove (proxy->priv->timeout_id);
 
+	utd = g_new0 (UnsetTimeoutData, 1);
+	utd->proxy = proxy;
 	/* Hold a reference on the EActivity for a short
 	 * period so the activity proxy stays visible. */
+	utd->activity = g_object_ref (activity);
+
 	proxy->priv->timeout_id = e_named_timeout_add_seconds_full (
-		G_PRIORITY_LOW, FEEDBACK_PERIOD, (GSourceFunc) gtk_false,
-		g_object_ref (activity), (GDestroyNotify) g_object_unref);
+		G_PRIORITY_LOW, FEEDBACK_PERIOD, activity_proxy_unset_timeout_id,
+		utd, unset_timeout_data_free);
 }
 
 static void
diff --git a/e-util/e-alert-bar.c b/e-util/e-alert-bar.c
index 233de93..66fbb34 100644
--- a/e-util/e-alert-bar.c
+++ b/e-util/e-alert-bar.c
@@ -202,9 +202,22 @@ alert_bar_response_cb (EAlert *alert,
 	if (g_queue_remove (queue, alert))
 		g_object_unref (alert);
 
-	if (g_queue_is_empty (queue))
+	if (g_queue_is_empty (queue)) {
+		GtkWidget *action_area;
+		GList *children;
+
 		gtk_widget_hide (GTK_WIDGET (alert_bar));
-	else if (was_head) {
+
+		action_area = gtk_info_bar_get_action_area (GTK_INFO_BAR (alert_bar));
+
+		/* Remove all buttons from the previous alert. */
+		children = gtk_container_get_children (GTK_CONTAINER (action_area));
+		while (children != NULL) {
+			GtkWidget *child = GTK_WIDGET (children->data);
+			gtk_container_remove (GTK_CONTAINER (action_area), child);
+			children = g_list_delete_link (children, children);
+		}
+	} else if (was_head) {
 		GtkInfoBar *info_bar = GTK_INFO_BAR (alert_bar);
 		gtk_info_bar_response (info_bar, response_id);
 		alert_bar_show_alert (alert_bar);
diff --git a/e-util/e-alert-dialog.c b/e-util/e-alert-dialog.c
index a85c7fe..e072775 100644
--- a/e-util/e-alert-dialog.c
+++ b/e-util/e-alert-dialog.c
@@ -240,6 +240,8 @@ alert_dialog_constructed (GObject *object)
 	gtk_label_set_attributes (GTK_LABEL (widget), list);
 	gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
 	gtk_label_set_selectable (GTK_LABEL (widget), TRUE);
+	gtk_label_set_width_chars (GTK_LABEL (widget), 40);
+	gtk_label_set_max_width_chars (GTK_LABEL (widget), 60);
 	gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0);
 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
 	gtk_widget_set_can_focus (widget, FALSE);
@@ -248,6 +250,8 @@ alert_dialog_constructed (GObject *object)
 	widget = gtk_label_new (secondary);
 	gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
 	gtk_label_set_selectable (GTK_LABEL (widget), TRUE);
+	gtk_label_set_width_chars (GTK_LABEL (widget), 60);
+	gtk_label_set_max_width_chars (GTK_LABEL (widget), 80);
 	gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0);
 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
 	gtk_widget_set_can_focus (widget, FALSE);
diff --git a/e-util/e-alert.c b/e-util/e-alert.c
index e98895b..438f523 100644
--- a/e-util/e-alert.c
+++ b/e-util/e-alert.c
@@ -429,7 +429,15 @@ alert_set_tag (EAlert *alert,
 static gboolean
 alert_timeout_cb (gpointer user_data)
 {
-	EAlert *alert = E_ALERT (user_data);
+	EAlert *alert = user_data;
+
+	if (g_source_is_destroyed (g_main_current_source ()))
+		return FALSE;
+
+	g_return_val_if_fail (E_IS_ALERT (alert), FALSE);
+
+	if (g_source_get_id (g_main_current_source ()) == alert->priv->timeout_id)
+		alert->priv->timeout_id = 0;
 
 	e_alert_response (alert, alert->priv->default_response);
 
diff --git a/e-util/e-calendar-item.c b/e-util/e-calendar-item.c
index a8159b0..8d3d2b8 100644
--- a/e-util/e-calendar-item.c
+++ b/e-util/e-calendar-item.c
@@ -1054,7 +1054,7 @@ e_calendar_item_draw (GnomeCanvasItem *canvas_item,
 	ECalendarItem *calitem;
 	GtkWidget *widget;
 	GtkStyleContext *style_context;
-	gint char_height, row, col, row_y, bar_height, col_x;
+	gint char_height, row, col, row_y, bar_height;
 	PangoContext *pango_context;
 	PangoFontMetrics *font_metrics;
 	GdkRGBA bg_color;
@@ -1148,26 +1148,6 @@ e_calendar_item_draw (GnomeCanvasItem *canvas_item,
 		gtk_style_context_restore (style_context);
 
 		for (col = 0; col < calitem->cols; col++) {
-			if (col != 0) {
-				col_x = calitem->x1 + calitem->x_offset
-					+ calitem->month_width * col;
-
-				gtk_style_context_save (style_context);
-				gtk_style_context_add_class (
-					style_context,
-					GTK_STYLE_CLASS_SEPARATOR);
-				cairo_save (cr);
-				gtk_render_line (
-					style_context, cr,
-					(gdouble) col_x - 1 - x,
-					(gdouble) row_y + border.top + 1 - y,
-					(gdouble) row_y + bar_height -
-						border.bottom - 2 - y,
-					(gdouble) col_x - x);
-				cairo_restore (cr);
-				gtk_style_context_restore (style_context);
-			}
-
 			e_calendar_item_draw_month (
 				calitem, cr, x, y,
 				width, height, row, col);
diff --git a/e-util/e-name-selector-entry.c b/e-util/e-name-selector-entry.c
index e0382da..9c6e3ef 100644
--- a/e-util/e-name-selector-entry.c
+++ b/e-util/e-name-selector-entry.c
@@ -63,6 +63,8 @@ struct _ENameSelectorEntryPrivate {
 
 	/* For asynchronous operations. */
 	GQueue cancellables;
+
+	GHashTable *known_contacts; /* gchar * ~> 1 */
 };
 
 enum {
@@ -207,6 +209,11 @@ name_selector_entry_dispose (GObject *object)
 		priv->contact_store = NULL;
 	}
 
+	if (priv->known_contacts) {
+		g_hash_table_destroy (priv->known_contacts);
+		priv->known_contacts = NULL;
+	}
+
 	g_slist_foreach (priv->user_query_fields, (GFunc) g_free, NULL);
 	g_slist_free (priv->user_query_fields);
 	priv->user_query_fields = NULL;
@@ -373,6 +380,77 @@ e_name_selector_entry_class_init (ENameSelectorEntryClass *class)
 		G_TYPE_NONE, 1, G_TYPE_POINTER);
 }
 
+static gchar *
+describe_contact (EContact *contact)
+{
+	GString *description;
+	const gchar *str;
+	GList *emails, *link;
+
+	g_return_val_if_fail (E_IS_CONTACT (contact), NULL);
+
+	emails = e_contact_get (contact, E_CONTACT_EMAIL);
+	/* Cannot merge one contact with multiple addresses with another contact */
+	if (!e_contact_get (contact, E_CONTACT_IS_LIST) && emails && emails->next) {
+		deep_free_list (emails);
+		return NULL;
+	}
+
+	description = g_string_new ("");
+
+	if (e_contact_get (contact, E_CONTACT_IS_LIST)) {
+		g_string_append (description, "list\n");
+	} else {
+		g_string_append (description, "indv\n");
+	}
+
+	str = e_contact_get_const (contact, E_CONTACT_FILE_AS);
+	g_string_append (description, str ? str : "");
+	g_string_append (description, "\n");
+
+	str = e_contact_get_const (contact, E_CONTACT_FULL_NAME);
+	g_string_append (description, str ? str : "");
+	g_string_append (description, "\n");
+
+	emails = e_contact_get (contact, E_CONTACT_EMAIL);
+	emails = g_list_sort (emails, (GCompareFunc) g_ascii_strcasecmp);
+	for (link = emails; link; link = g_list_next (link)) {
+		str = link->data;
+
+		g_string_append (description, str ? str : "");
+		g_string_append (description, "\n");
+	}
+
+	deep_free_list (emails);
+
+	return g_string_free (description, FALSE);
+}
+
+static gboolean
+is_duplicate_contact_and_remember (ENameSelectorEntry *nsentry,
+				   EContact *contact)
+{
+	gchar *description;
+
+	g_return_val_if_fail (E_IS_NAME_SELECTOR_ENTRY (nsentry), FALSE);
+	g_return_val_if_fail (E_IS_CONTACT (contact), FALSE);
+
+	description = describe_contact (contact);
+	if (!description) {
+		/* Might be a contact with multiple addresses */
+		return FALSE;
+	}
+
+	if (g_hash_table_lookup (nsentry->priv->known_contacts, description)) {
+		g_free (description);
+		return TRUE;
+	}
+
+	g_hash_table_insert (nsentry->priv->known_contacts, description, GINT_TO_POINTER (1));
+
+	return FALSE;
+}
+
 /* Remove unquoted commas and control characters from string */
 static gchar *
 sanitize_string (const gchar *string)
@@ -1161,6 +1239,7 @@ clear_completion_model (ENameSelectorEntry *name_selector_entry)
 		return;
 
 	e_contact_store_set_query (name_selector_entry->priv->contact_store, NULL);
+	g_hash_table_remove_all (name_selector_entry->priv->known_contacts);
 	priv->is_completing = FALSE;
 }
 
@@ -1184,6 +1263,8 @@ update_completion_model (ENameSelectorEntry *name_selector_entry)
 		cue_str = get_entry_substring (name_selector_entry, range_start, range_end);
 		set_completion_query (name_selector_entry, cue_str);
 		g_free (cue_str);
+
+		g_hash_table_remove_all (name_selector_entry->priv->known_contacts);
 	} else {
 		/* N/A; Clear completion model */
 		clear_completion_model (name_selector_entry);
@@ -2170,6 +2251,9 @@ generate_contact_rows (EContactStore *contact_store,
 	if (!contact_uid)
 		return 0;  /* Can happen with broken databases */
 
+	if (is_duplicate_contact_and_remember (name_selector_entry, contact))
+		return 0;
+
 	if (e_contact_get (contact, E_CONTACT_IS_LIST))
 		return 1;
 
@@ -3231,6 +3315,7 @@ e_name_selector_entry_init (ENameSelectorEntry *name_selector_entry)
 
 	name_selector_entry->priv->minimum_query_length = 3;
 	name_selector_entry->priv->show_address = FALSE;
+	name_selector_entry->priv->known_contacts = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
 
 	/* Edit signals */
 
diff --git a/e-util/e-poolv.c b/e-util/e-poolv.c
index 701e6c2..1207d08 100644
--- a/e-util/e-poolv.c
+++ b/e-util/e-poolv.c
@@ -26,14 +26,9 @@
 
 struct _EPoolv {
 	guchar length;
-	gchar *s[1];
+	const gchar *s[1];
 };
 
-static GHashTable *poolv_pool;
-static CamelMemPool *poolv_mempool;
-
-G_LOCK_DEFINE_STATIC (poolv);
-
 /**
  * e_poolv_new:
  * @size: The number of elements in the poolv, maximum of 254 elements.
@@ -57,17 +52,6 @@ e_poolv_new (guint size)
 	poolv = g_malloc0 (sizeof (*poolv) + (size - 1) * sizeof (gchar *));
 	poolv->length = size;
 
-	G_LOCK (poolv);
-
-	if (!poolv_pool)
-		poolv_pool = g_hash_table_new (g_str_hash, g_str_equal);
-
-	if (!poolv_mempool)
-		poolv_mempool = camel_mempool_new (
-			32 * 1024, 512, CAMEL_MEMPOOL_ALIGN_BYTE);
-
-	G_UNLOCK (poolv);
-
 	return poolv;
 }
 
@@ -91,26 +75,21 @@ e_poolv_set (EPoolv *poolv,
              gchar *str,
              gint freeit)
 {
+	const gchar *old_str;
+
 	g_return_val_if_fail (poolv != NULL, NULL);
 	g_return_val_if_fail (index >= 0 && index < poolv->length, NULL);
 
 	if (!str) {
+		camel_pstring_free (poolv->s[index]);
 		poolv->s[index] = NULL;
 		return poolv;
 	}
 
-	G_LOCK (poolv);
+	old_str = poolv->s[index];
+	poolv->s[index] = (gchar *) camel_pstring_add (str, freeit);
 
-	if ((poolv->s[index] = g_hash_table_lookup (poolv_pool, str)) != NULL) {
-	} else {
-		poolv->s[index] = camel_mempool_strdup (poolv_mempool, str);
-		g_hash_table_insert (poolv_pool, poolv->s[index], poolv->s[index]);
-	}
-
-	G_UNLOCK (poolv);
-
-	if (freeit)
-		g_free (str);
+	camel_pstring_free (old_str);
 
 	return poolv;
 }
@@ -147,7 +126,13 @@ e_poolv_get (EPoolv *poolv,
 void
 e_poolv_destroy (EPoolv *poolv)
 {
+	gint ii;
+
 	g_return_if_fail (poolv != NULL);
 
+	for (ii = 0; ii < poolv->length; ii++) {
+		camel_pstring_free (poolv->s[ii]);
+	}
+
 	g_free (poolv);
 }
diff --git a/e-util/e-spell-entry.c b/e-util/e-spell-entry.c
index 75c7a6a..00e27f2 100644
--- a/e-util/e-spell-entry.c
+++ b/e-util/e-spell-entry.c
@@ -66,6 +66,8 @@ word_misspelled (ESpellEntry *entry,
 	const gchar *text;
 	gchar *word;
 	gboolean result = TRUE;
+	GSList *li;
+	gssize wlen;
 
 	if (start == end)
 		return FALSE;
@@ -75,16 +77,13 @@ word_misspelled (ESpellEntry *entry,
 
 	g_strlcpy (word, text + start, end - start + 1);
 
-	if (g_unichar_isalpha (*word)) {
-		GSList *li;
-		gssize wlen = strlen (word);
+	wlen = strlen (word);
 
-		for (li = entry->priv->checkers; li; li = g_slist_next (li)) {
-			GtkhtmlSpellChecker *checker = li->data;
-			if (gtkhtml_spell_checker_check_word (checker, word, wlen)) {
-				result = FALSE;
-				break;
-			}
+	for (li = entry->priv->checkers; li; li = g_slist_next (li)) {
+		GtkhtmlSpellChecker *checker = li->data;
+		if (gtkhtml_spell_checker_check_word (checker, word, wlen)) {
+			result = FALSE;
+			break;
 		}
 	}
 
diff --git a/e-util/e-table-extras.c b/e-util/e-table-extras.c
index 07f81ba..43fca94 100644
--- a/e-util/e-table-extras.c
+++ b/e-util/e-table-extras.c
@@ -113,7 +113,11 @@ e_int64ptr_compare (gconstpointer data1,
 {
 	const gint64 *pa = data1, *pb = data2;
 
-	return (*pa == *pb) ? 0 : (*pa < *pb) ? -1 : 1;
+	if (pa && pb)
+		return (*pa == *pb) ? 0 : (*pa < *pb) ? -1 : 1;
+
+	/* sort unset values before set */
+	return (!pa && !pb) ? 0 : (pa ? 1 : -1);
 }
 
 /* UTF-8 strncasecmp - not optimized */
diff --git a/e-util/gal-a11y-e-table-click-to-add.c b/e-util/gal-a11y-e-table-click-to-add.c
index 6fabe31..6386ebb 100644
--- a/e-util/gal-a11y-e-table-click-to-add.c
+++ b/e-util/gal-a11y-e-table-click-to-add.c
@@ -145,7 +145,13 @@ etcta_get_name (AtkObject *obj)
 static gint
 etcta_get_n_children (AtkObject *accessible)
 {
-	return 1;
+	ETableClickToAdd * etcta;
+
+	etcta = E_TABLE_CLICK_TO_ADD (
+		atk_gobject_accessible_get_object (
+		ATK_GOBJECT_ACCESSIBLE (accessible)));
+
+	return (etcta->rect || etcta->row) ? 1 : 0;
 }
 
 static AtkObject *
diff --git a/e-util/gal-a11y-e-table-item.c b/e-util/gal-a11y-e-table-item.c
index a650d68..6990d4d 100644
--- a/e-util/gal-a11y-e-table-item.c
+++ b/e-util/gal-a11y-e-table-item.c
@@ -1115,7 +1115,7 @@ gal_a11y_e_table_item_new (ETableItem *item)
 	AtkObject *parent;
 	const gchar *name;
 
-	g_return_val_if_fail (item && item->cols >= 0 && item->rows >= 0, NULL);
+	g_return_val_if_fail (item && item->cols >= 0, NULL);
 	a11y = g_object_new (gal_a11y_e_table_item_get_type (), NULL);
 
 	atk_object_initialize (ATK_OBJECT (a11y), item);
@@ -1133,7 +1133,7 @@ gal_a11y_e_table_item_new (ETableItem *item)
 	GET_PRIVATE (a11y)->item = item;
 	/* Initialize cell data. */
 	GET_PRIVATE (a11y)->cols = item->cols;
-	GET_PRIVATE (a11y)->rows = item->rows;
+	GET_PRIVATE (a11y)->rows = item->rows >= 0 ? item->rows : 0;
 
 	GET_PRIVATE (a11y)->columns = e_table_header_get_columns (item->header);
 	if (GET_PRIVATE (a11y)->columns == NULL)
diff --git a/e-util/gal-a11y-e-table.c b/e-util/gal-a11y-e-table.c
index 26bcc03..e766b18 100644
--- a/e-util/gal-a11y-e-table.c
+++ b/e-util/gal-a11y-e-table.c
@@ -132,9 +132,10 @@ et_get_n_children (AtkObject *accessible)
 	et = E_TABLE (gtk_accessible_get_widget (GTK_ACCESSIBLE (a11y)));
 
 	if (et && et->group) {
-		if (E_IS_TABLE_GROUP_LEAF (et->group))
-			n = 1;
-		else if (E_IS_TABLE_GROUP_CONTAINER (et->group)) {
+		if (E_IS_TABLE_GROUP_LEAF (et->group)) {
+			if (find_first_table_item (et->group))
+				n++;
+		} else if (E_IS_TABLE_GROUP_CONTAINER (et->group)) {
 			ETableGroupContainer *etgc = (ETableGroupContainer *) et->group;
 			n = g_list_length (etgc->children);
 		}
@@ -162,11 +163,13 @@ et_ref_child (AtkObject *accessible,
 	if (i == 0 || i < child_no - 1) {
 		if (E_IS_TABLE_GROUP_LEAF (et->group)) {
 			ETableItem *eti = find_first_table_item (et->group);
-			AtkObject *aeti = eti_get_accessible (eti, accessible);
-			if (aeti)
-				g_object_ref (aeti);
-			return aeti;
-
+			AtkObject *aeti;
+			if (eti) {
+				aeti = eti_get_accessible (eti, accessible);
+				if (aeti)
+					g_object_ref (aeti);
+				return aeti;
+			}
 		} else if (E_IS_TABLE_GROUP_CONTAINER (et->group)) {
 			ETableGroupContainer *etgc = (ETableGroupContainer *) et->group;
 			ETableGroupContainerChildNode *child_node = g_list_nth_data (etgc->children, i);
@@ -179,7 +182,9 @@ et_ref_child (AtkObject *accessible,
 				return aeti;
 			}
 		}
-	} else if (i == child_no -1) {
+	}
+
+	if (i == child_no -1) {
 		ETableClickToAdd * etcta;
 
 		if (et && et->use_click_to_add && et->click_to_add) {
diff --git a/em-format/e-mail-parser-multipart-mixed.c b/em-format/e-mail-parser-multipart-mixed.c
index ad94895..432fef4 100644
--- a/em-format/e-mail-parser-multipart-mixed.c
+++ b/em-format/e-mail-parser-multipart-mixed.c
@@ -69,12 +69,13 @@ empe_mp_mixed_parse (EMailParserExtension *extension,
 		EMailPart *mail_part;
 		CamelMimePart *subpart;
 		CamelContentType *ct;
+		gboolean handled;
 
 		subpart = camel_multipart_get_part (mp, i);
 
 		g_string_append_printf (part_id, ".mixed.%d", i);
 
-		e_mail_parser_parse_part (
+		handled = e_mail_parser_parse_part (
 			parser, subpart, part_id, cancellable, &work_queue);
 
 		mail_part = g_queue_peek_head (&work_queue);
@@ -95,7 +96,7 @@ empe_mp_mixed_parse (EMailParserExtension *extension,
 				parser, subpart, part_id, &work_queue);
 
 		/* Force messages to be expandable */
-		} else if (mail_part == NULL ||
+		} else if ((mail_part == NULL && !handled) ||
 		    (camel_content_type_is (ct, "message", "*") &&
 		     mail_part != NULL &&
 		     !e_mail_part_get_is_attachment (mail_part))) {
diff --git a/em-format/e-mail-parser-text-plain.c b/em-format/e-mail-parser-text-plain.c
index 26e459c..7fbc59c 100644
--- a/em-format/e-mail-parser-text-plain.c
+++ b/em-format/e-mail-parser-text-plain.c
@@ -45,29 +45,6 @@ static const gchar *parser_mime_types[] = {
 };
 
 static gboolean
-part_is_empty (CamelMimePart *part)
-{
-	CamelDataWrapper *dw;
-	GByteArray *ba;
-	guint i;
-
-	dw = camel_medium_get_content (CAMEL_MEDIUM (part));
-	ba = camel_data_wrapper_get_byte_array (dw);
-
-	if (!ba)
-		return TRUE;
-
-	for (i = 0; i < ba->len; i++) {
-
-		/* Checks for \n, \t, \f, \r, \v and space */
-		if (!isspace (ba->data[i]))
-			return FALSE;
-	}
-
-	return TRUE;
-}
-
-static gboolean
 process_part (EMailParser *parser,
               GString *part_id,
               gint part_number,
@@ -80,9 +57,6 @@ process_part (EMailParser *parser,
 	EMailPart *mail_part;
 	gint s_len = part_id->len;
 
-	if (part_is_empty (part))
-		return TRUE;
-
 	type = camel_mime_part_get_content_type (part);
 	if (!camel_content_type_is (type, "text", "*")) {
 		e_mail_parser_parse_part (
diff --git a/evolution.doap b/evolution.doap
index 70f1a05..dcdd89b 100644
--- a/evolution.doap
+++ b/evolution.doap
@@ -7,6 +7,7 @@
 
   <name xml:lang="en">evolution</name>
   <shortdesc xml:lang="en">Manage your email, contacts and schedule</shortdesc>
+  <description>Manage your email, contacts and schedule</description>
   <homepage rdf:resource="http://live.gnome.org/Apps/Evolution"; />
   <mailing-list rdf:resource="http://mail.gnome.org/mailman/listinfo/evolution-list"; />
   <download-page rdf:resource="http://download.gnome.org/sources/evolution"; />
@@ -15,18 +16,6 @@
   <programming-language>C</programming-language>
   <programming-language>XML</programming-language>
 
-  <!-- Project Leads -->
-
-  <maintainer>
-    <foaf:Person>
-      <foaf:name>Matthew Barnes</foaf:name>
-      <foaf:mbox rdf:resource="mailto:mbarnes@redhat.com"; />
-      <gnome:userid>mbarnes</gnome:userid>
-    </foaf:Person>
-  </maintainer>
-
-  <!-- Alphabetically -->
-
   <maintainer>
     <foaf:Person>
       <foaf:name>Milan Crha</foaf:name>
diff --git a/help/Makefile.am b/help/Makefile.am
index a0777a0..353a1ad 100644
--- a/help/Makefile.am
+++ b/help/Makefile.am
@@ -238,6 +238,6 @@ HELP_FILES = \
 	xinclude-mail-account-identity.xml \
 	xinclude-searching.xml
 
-HELP_LINGUAS = cs de el en_GB es eu fr gl hu mk oc ru sl sv te zh_CN
+HELP_LINGUAS = cs de el en_GB es eu fr gl hu ja mk oc ru sl sv te zh_CN
 
 -include $(top_srcdir)/git.mk
diff --git a/help/ja/ja.po b/help/ja/ja.po
new file mode 100644
index 0000000..e94558e
diff --git a/libemail-engine/e-mail-session-utils.c b/libemail-engine/e-mail-session-utils.c
index 524b09d..a248eac 100644
--- a/libemail-engine/e-mail-session-utils.c
+++ b/libemail-engine/e-mail-session-utils.c
@@ -878,7 +878,8 @@ e_mail_session_send_to (EMailSession *session,
 		NULL, CAMEL_MIME_PART (message)->headers);
 	((CamelMessageInfoBase *) info)->size =
 		get_message_size (message, cancellable);
-	camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN, ~0);
+	camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN |
+		(camel_mime_message_has_attachment (message) ? CAMEL_MESSAGE_ATTACHMENTS : 0), ~0);
 
 	/* expand, or remove empty, group addresses */
 	em_utils_expand_groups (CAMEL_INTERNET_ADDRESS (recipients));
diff --git a/libemail-engine/mail-ops.c b/libemail-engine/mail-ops.c
index df0b6d0..969fbcb 100644
--- a/libemail-engine/mail-ops.c
+++ b/libemail-engine/mail-ops.c
@@ -569,6 +569,22 @@ static void	report_status		(struct _send_queue_msg *m,
 					 const gchar *desc,
 					 ...);
 
+static guint32
+get_message_size (CamelMimeMessage *message,
+                  GCancellable *cancellable)
+{
+	CamelStream *null;
+	guint32 size;
+
+	null = camel_stream_null_new ();
+	camel_data_wrapper_write_to_stream_sync (
+		CAMEL_DATA_WRAPPER (message), null, cancellable, NULL);
+	size = CAMEL_STREAM_NULL (null)->written;
+	g_object_unref (null);
+
+	return size;
+}
+
 /* send 1 message to a specific transport */
 static void
 mail_send_message (struct _send_queue_msg *m,
@@ -666,7 +682,9 @@ mail_send_message (struct _send_queue_msg *m,
 
 	/* Now check for posting, failures are ignored */
 	info = camel_message_info_new (NULL);
-	camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN, ~0);
+	((CamelMessageInfoBase *) info)->size = get_message_size (message, cancellable);
+	camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN |
+		(camel_mime_message_has_attachment (message) ? CAMEL_MESSAGE_ATTACHMENTS : 0), ~0);
 
 	for (header = xev; header && !local_error; header = header->next) {
 		gchar *uri;
diff --git a/libgnomecanvas/gnome-canvas-pixbuf.c b/libgnomecanvas/gnome-canvas-pixbuf.c
index 1250897..87c3c26 100644
--- a/libgnomecanvas/gnome-canvas-pixbuf.c
+++ b/libgnomecanvas/gnome-canvas-pixbuf.c
@@ -272,6 +272,9 @@ gnome_canvas_pixbuf_draw (GnomeCanvasItem *item,
 
 	gnome_canvas_item_i2c_matrix (item, &matrix);
 
+	matrix.x0 -= x;
+	matrix.y0 -= y;
+
 	cairo_save (cr);
 	cairo_transform (cr, &matrix);
 
diff --git a/mail/e-mail-printer.c b/mail/e-mail-printer.c
index 3d93196..6205a50 100644
--- a/mail/e-mail-printer.c
+++ b/mail/e-mail-printer.c
@@ -367,7 +367,8 @@ mail_printer_new_web_view (const gchar *charset,
 		G_OBJECT (web_settings),
 		"enable-frame-flattening", FALSE, NULL);
 
-	e_mail_display_set_force_load_images (E_MAIL_DISPLAY (web_view), TRUE);
+	/* Do not load remote images, print what user sees in the preview panel */
+	e_mail_display_set_force_load_images (E_MAIL_DISPLAY (web_view), FALSE);
 
 	formatter = e_mail_display_get_formatter (E_MAIL_DISPLAY (web_view));
 	if (charset != NULL && *charset != '\0')
diff --git a/mail/e-mail-ui-session.c b/mail/e-mail-ui-session.c
index 96db4bb..3f12abc 100644
--- a/mail/e-mail-ui-session.c
+++ b/mail/e-mail-ui-session.c
@@ -631,12 +631,16 @@ mail_ui_session_user_alert (CamelSession *session,
 	g_free (display_name);
 }
 
+extern gint camel_application_is_exiting;
+
 static void
 mail_ui_session_refresh_service (EMailSession *session,
                                  CamelService *service)
 {
-	if (camel_session_get_online (CAMEL_SESSION (session)))
+	if (!camel_application_is_exiting &&
+	    camel_session_get_online (CAMEL_SESSION (session))) {
 		mail_receive_service (service);
+	}
 }
 
 static EMVFolderContext *
diff --git a/mail/em-composer-utils.c b/mail/em-composer-utils.c
index fb6d19a..98b392f 100644
--- a/mail/em-composer-utils.c
+++ b/mail/em-composer-utils.c
@@ -795,8 +795,8 @@ composer_save_to_drafts_append_mail (AsyncContext *async_context,
 
 	info = camel_message_info_new (NULL);
 
-	camel_message_info_set_flags (
-		info, CAMEL_MESSAGE_DRAFT | CAMEL_MESSAGE_SEEN, ~0);
+	camel_message_info_set_flags (info, CAMEL_MESSAGE_DRAFT | CAMEL_MESSAGE_SEEN |
+		(camel_mime_message_has_attachment (async_context->message) ? CAMEL_MESSAGE_ATTACHMENTS : 0), ~0);
 
 	camel_medium_remove_header (
 		CAMEL_MEDIUM (async_context->message),
@@ -1758,6 +1758,12 @@ forward_non_attached (EMailBackend *backend,
 	shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
 
 	forward = quoting_text (QUOTING_FORWARD);
+	if (style == E_MAIL_FORWARD_STYLE_INLINE && forward) {
+		gchar *tmp = forward;
+		forward = g_strconcat (forward, "<br>", NULL);
+		g_free (tmp);
+	}
+
 	text = em_utils_message_to_html (
 		CAMEL_SESSION (session), message,
 		forward, flags, NULL, NULL, &validity_found);
@@ -2118,7 +2124,7 @@ reply_get_composer (EShell *shell,
 	if ((subject = (gchar *) camel_mime_message_get_subject (message))) {
 		gboolean skip_len = -1;
 
-		if (em_utils_is_re_in_subject (subject, &skip_len) && skip_len > 0)
+		if (em_utils_is_re_in_subject (subject, &skip_len, NULL) && skip_len > 0)
 			subject = subject + skip_len;
 
 		subject = g_strdup_printf ("Re: %s", subject);
diff --git a/mail/em-utils.c b/mail/em-utils.c
index 2291e08..eb8324f 100644
--- a/mail/em-utils.c
+++ b/mail/em-utils.c
@@ -1446,10 +1446,10 @@ check_prefix (const gchar *subject,
 
 gboolean
 em_utils_is_re_in_subject (const gchar *subject,
-                           gint *skip_len)
+                           gint *skip_len,
+			   const gchar * const *use_prefixes_strv)
 {
-	GSettings *settings;
-	gchar *prefixes, **prefixes_strv;
+	gchar **prefixes_strv;
 	gboolean res;
 	gint ii;
 
@@ -1464,18 +1464,25 @@ em_utils_is_re_in_subject (const gchar *subject,
 	if (check_prefix (subject, "Re", skip_len))
 		return TRUE;
 
-	settings = g_settings_new ("org.gnome.evolution.mail");
-	prefixes = g_settings_get_string (settings, "composer-localized-re");
-	g_object_unref (settings);
+	if (use_prefixes_strv) {
+		prefixes_strv = (gchar **) use_prefixes_strv;
+	} else {
+		GSettings *settings;
+		gchar *prefixes;
 
-	if (!prefixes || !*prefixes) {
+		settings = g_settings_new ("org.gnome.evolution.mail");
+		prefixes = g_settings_get_string (settings, "composer-localized-re");
+		g_object_unref (settings);
+
+		if (!prefixes || !*prefixes) {
+			g_free (prefixes);
+			return FALSE;
+		}
+
+		prefixes_strv = g_strsplit (prefixes, ",", -1);
 		g_free (prefixes);
-		return FALSE;
 	}
 
-	prefixes_strv = g_strsplit (prefixes, ",", -1);
-	g_free (prefixes);
-
 	if (!prefixes_strv)
 		return FALSE;
 
@@ -1488,7 +1495,8 @@ em_utils_is_re_in_subject (const gchar *subject,
 			res = check_prefix (subject, prefix, skip_len);
 	}
 
-	g_strfreev (prefixes_strv);
+	if (!use_prefixes_strv)
+		g_strfreev (prefixes_strv);
 
 	return res;
 }
diff --git a/mail/em-utils.h b/mail/em-utils.h
index 6725a06..3127145 100644
--- a/mail/em-utils.h
+++ b/mail/em-utils.h
@@ -76,7 +76,8 @@ gchar *em_utils_url_unescape_amp (const gchar *url);
 void emu_restore_folder_tree_state (EMFolderTree *folder_tree);
 
 gboolean	em_utils_is_re_in_subject	(const gchar *subject,
-						 gint *skip_len);
+						 gint *skip_len,
+						 const gchar * const *use_prefixes_strv);
 
 G_END_DECLS
 
diff --git a/mail/message-list.c b/mail/message-list.c
index 995dac5..864e1ec 100644
--- a/mail/message-list.c
+++ b/mail/message-list.c
@@ -116,6 +116,10 @@ struct _MessageListPrivate {
 	const gchar *newest_read_uid;
 	time_t oldest_unread_date;
 	const gchar *oldest_unread_uid;
+
+	GSettings *mail_settings;
+	gchar **re_prefixes;
+	GMutex re_prefixes_lock;
 };
 
 /* XXX Plain GNode suffers from O(N) tail insertions, and that won't
@@ -776,8 +780,11 @@ get_normalised_string (MessageList *message_list,
 
 		subject = string;
 		while (found_re) {
+			g_mutex_lock (&message_list->priv->re_prefixes_lock);
 			found_re = em_utils_is_re_in_subject (
-				subject, &skip_len) && skip_len > 0;
+				subject, &skip_len, (const gchar * const *) message_list->priv->re_prefixes) && skip_len > 0;
+			g_mutex_unlock (&message_list->priv->re_prefixes_lock);
+
 			if (found_re)
 				subject += skip_len;
 
@@ -1529,7 +1536,8 @@ add_all_labels_foreach (ETreeModel *etm,
 }
 
 static const gchar *
-get_trimmed_subject (CamelMessageInfo *info)
+get_trimmed_subject (CamelMessageInfo *info,
+		     MessageList *message_list)
 {
 	const gchar *subject;
 	const gchar *mlist;
@@ -1561,8 +1569,10 @@ get_trimmed_subject (CamelMessageInfo *info)
 		while (found_re) {
 			found_re = FALSE;
 
+			g_mutex_lock (&message_list->priv->re_prefixes_lock);
 			found_re = em_utils_is_re_in_subject (
-				subject, &skip_len) && skip_len > 0;
+				subject, &skip_len, (const gchar * const *) message_list->priv->re_prefixes) && skip_len > 0;
+			g_mutex_unlock (&message_list->priv->re_prefixes_lock);
 			if (found_re)
 				subject += skip_len;
 
@@ -1677,7 +1687,7 @@ ml_tree_value_at_ex (ETreeModel *etm,
 		str = camel_message_info_subject (msg_info);
 		return (gpointer)(str ? str : "");
 	case COL_SUBJECT_TRIMMED:
-		str = get_trimmed_subject (msg_info);
+		str = get_trimmed_subject (msg_info, message_list);
 		return (gpointer)(str ? str : "");
 	case COL_SUBJECT_NORM:
 		return (gpointer) get_normalised_string (message_list, msg_info, col);
@@ -2726,6 +2736,7 @@ message_list_dispose (GObject *object)
 	g_clear_object (&priv->session);
 	g_clear_object (&priv->folder);
 	g_clear_object (&priv->invisible);
+	g_clear_object (&priv->mail_settings);
 
 	g_clear_object (&message_list->extras);
 
@@ -2757,9 +2768,11 @@ message_list_finalize (GObject *object)
 	g_free (message_list->search);
 	g_free (message_list->frozen_search);
 	g_free (message_list->cursor_uid);
+	g_strfreev (message_list->priv->re_prefixes);
 
 	g_mutex_clear (&message_list->priv->regen_lock);
 	g_mutex_clear (&message_list->priv->thread_tree_lock);
+	g_mutex_clear (&message_list->priv->re_prefixes_lock);
 
 	clear_selection (message_list, &message_list->priv->clipboard);
 
@@ -3366,6 +3379,7 @@ message_list_init (MessageList *message_list)
 
 	g_mutex_init (&message_list->priv->regen_lock);
 	g_mutex_init (&message_list->priv->thread_tree_lock);
+	g_mutex_init (&message_list->priv->re_prefixes_lock);
 
 	/* TODO: Should this only get the selection if we're realised? */
 	p = message_list->priv;
@@ -3395,6 +3409,9 @@ message_list_init (MessageList *message_list)
 	/* FIXME This is currently unused. */
 	target_list = gtk_target_list_new (NULL, 0);
 	message_list->priv->paste_target_list = target_list;
+
+	message_list->priv->mail_settings = g_settings_new ("org.gnome.evolution.mail");
+	message_list->priv->re_prefixes = NULL;
 }
 
 static void
@@ -5866,6 +5883,7 @@ mail_regen_list (MessageList *message_list,
 	GCancellable *cancellable;
 	RegenData *new_regen_data;
 	RegenData *old_regen_data;
+	gchar *prefixes;
 
 	/* Report empty search as NULL, not as one/two-space string. */
 	if (search && (strcmp (search, " ") == 0 || strcmp (search, "  ") == 0))
@@ -5878,6 +5896,13 @@ mail_regen_list (MessageList *message_list,
 		return;
 	}
 
+	g_mutex_lock (&message_list->priv->re_prefixes_lock);
+	g_strfreev (message_list->priv->re_prefixes);
+	prefixes = g_settings_get_string (message_list->priv->mail_settings, "composer-localized-re");
+	message_list->priv->re_prefixes = g_strsplit (prefixes ? prefixes : "", ",", -1);
+	g_free (prefixes);
+	g_mutex_unlock (&message_list->priv->re_prefixes_lock);
+
 	g_mutex_lock (&message_list->priv->regen_lock);
 
 	old_regen_data = message_list->priv->regen_data;
diff --git a/modules/composer-autosave/e-composer-autosave.c b/modules/composer-autosave/e-composer-autosave.c
index 52c0cfb..7330ab6 100644
--- a/modules/composer-autosave/e-composer-autosave.c
+++ b/modules/composer-autosave/e-composer-autosave.c
@@ -171,7 +171,9 @@ composer_autosave_constructed (GObject *object)
 
 	extensible = e_extension_get_extensible (E_EXTENSION (object));
 
-	e_signal_connect_notify_swapped (
+	/* Do not use e_signal_connect_notify_swapped() here,
+	   this module relies on "false" change notifications. */
+	g_signal_connect_swapped (
 		extensible, "notify::changed",
 		G_CALLBACK (composer_autosave_changed_cb), object);
 }
diff --git a/modules/mail/e-mail-shell-view-actions.c b/modules/mail/e-mail-shell-view-actions.c
index a93191c..84f4c13 100644
--- a/modules/mail/e-mail-shell-view-actions.c
+++ b/modules/mail/e-mail-shell-view-actions.c
@@ -467,6 +467,9 @@ mark_all_read_thread (GSimpleAsyncResult *simple,
 
 		camel_folder_thaw (folder);
 
+		/* Save changes to the server immediately. */
+		camel_folder_synchronize_sync (folder, FALSE, cancellable, &error);
+
 		camel_folder_free_uids (folder, uids);
 		g_object_unref (folder);
 	}
diff --git a/modules/tnef-attachment/e-mail-parser-tnef-attachment.c b/modules/tnef-attachment/e-mail-parser-tnef-attachment.c
index 033c83d..b67f31f 100644
--- a/modules/tnef-attachment/e-mail-parser-tnef-attachment.c
+++ b/modules/tnef-attachment/e-mail-parser-tnef-attachment.c
@@ -71,7 +71,7 @@ G_DEFINE_DYNAMIC_TYPE (
 
 static const gchar *parser_mime_types[] = {
 	"application/vnd.ms-tnef",
-	"application/ms-tnefl",
+	"application/ms-tnef",
 	NULL
 };
 
diff --git a/plugins/mail-to-task/mail-to-task.c b/plugins/mail-to-task/mail-to-task.c
index 065df23..6de6729 100644
--- a/plugins/mail-to-task/mail-to-task.c
+++ b/plugins/mail-to-task/mail-to-task.c
@@ -824,7 +824,9 @@ do_manage_comp_idle (struct _manage_comp *mc)
 }
 
 typedef struct {
+	EClientCache *client_cache;
 	ESource *source;
+	const gchar *extension_name;
 	ECalClientSourceType source_type;
 	CamelFolder *folder;
 	GPtrArray *uids;
@@ -840,8 +842,8 @@ do_mail_to_event (AsyncData *data)
 	GPtrArray *uids = data->uids;
 	GError *error = NULL;
 
-	client = e_cal_client_connect_sync (
-		data->source, data->source_type, NULL, &error);
+	client = e_client_cache_get_client_sync (data->client_cache,
+		data->source, data->extension_name, NULL, &error);
 
 	/* Sanity check. */
 	g_return_val_if_fail (
@@ -1036,6 +1038,7 @@ do_mail_to_event (AsyncData *data)
 	g_ptr_array_unref (uids);
 	g_object_unref (folder);
 
+	g_object_unref (data->client_cache);
 	g_object_unref (data->source);
 	g_free (data->selected_text);
 	g_free (data);
@@ -1197,7 +1200,9 @@ mail_to_event (ECalClientSourceType source_type,
 
 		/* Fill the elements in AsynData */
 		data = g_new0 (AsyncData, 1);
+		data->client_cache = g_object_ref (e_shell_get_client_cache (shell));
 		data->source = g_object_ref (source);
+		data->extension_name = extension_name;
 		data->source_type = source_type;
 		data->folder = e_mail_reader_ref_folder (reader);
 		data->uids = g_ptr_array_ref (uids);
diff --git a/plugins/publish-calendar/publish-format-fb.c b/plugins/publish-calendar/publish-format-fb.c
index caa88c4..0a064a9 100644
--- a/plugins/publish-calendar/publish-format-fb.c
+++ b/plugins/publish-calendar/publish-format-fb.c
@@ -88,9 +88,11 @@ write_calendar (const gchar *uid,
 	source = e_source_registry_ref_source (registry, uid);
 
 	if (source != NULL) {
-		client = e_cal_client_connect_sync (
-			source, E_CAL_CLIENT_SOURCE_TYPE_EVENTS,
-			NULL, error);
+		EClientCache *client_cache;
+
+		client_cache = e_shell_get_client_cache (shell);
+		client = e_client_cache_get_client_sync (client_cache, source, E_SOURCE_EXTENSION_CALENDAR, NULL, error);
+
 		g_object_unref (source);
 	} else {
 		g_set_error (
diff --git a/plugins/publish-calendar/publish-format-ical.c b/plugins/publish-calendar/publish-format-ical.c
index 33cc45d..06215a6 100644
--- a/plugins/publish-calendar/publish-format-ical.c
+++ b/plugins/publish-calendar/publish-format-ical.c
@@ -91,9 +91,11 @@ write_calendar (const gchar *uid,
 	source = e_source_registry_ref_source (registry, uid);
 
 	if (source != NULL) {
-		client = e_cal_client_connect_sync (
-			source, E_CAL_CLIENT_SOURCE_TYPE_EVENTS,
-			NULL, error);
+		EClientCache *client_cache;
+
+		client_cache = e_shell_get_client_cache (shell);
+		client = e_client_cache_get_client_sync (client_cache, source, E_SOURCE_EXTENSION_CALENDAR, NULL, error);
+
 		g_object_unref (source);
 	} else {
 		g_set_error (
diff --git a/plugins/save-calendar/csv-format.c b/plugins/save-calendar/csv-format.c
index 650d01b..498f5e5 100644
--- a/plugins/save-calendar/csv-format.c
+++ b/plugins/save-calendar/csv-format.c
@@ -303,7 +303,7 @@ userstring_to_systemstring (const gchar *userstring)
 static void
 do_save_calendar_csv (FormatHandler *handler,
                       ESourceSelector *selector,
-                      ECalClientSourceType type,
+		      EClientCache *client_cache,
                       gchar *dest_uri)
 {
 
@@ -331,8 +331,8 @@ do_save_calendar_csv (FormatHandler *handler,
 
 	/* open source client */
 	primary_source = e_source_selector_ref_primary_selection (selector);
-	source_client = e_cal_client_connect_sync (
-		primary_source, type, NULL, &error);
+	source_client = e_client_cache_get_client_sync (client_cache,
+		primary_source, e_source_selector_get_extension_name (selector), NULL, &error);
 	g_object_unref (primary_source);
 
 	/* Sanity check. */
diff --git a/plugins/save-calendar/format-handler.h b/plugins/save-calendar/format-handler.h
index 88946e8..dd5ec64 100644
--- a/plugins/save-calendar/format-handler.h
+++ b/plugins/save-calendar/format-handler.h
@@ -37,7 +37,7 @@ struct _FormatHandler
 
 	void	(*save)		(FormatHandler *handler,
 				 ESourceSelector *selector,
-				 ECalClientSourceType type,
+				 EClientCache *client_cache,
 				 gchar *dest_uri);
 };
 
diff --git a/plugins/save-calendar/ical-format.c b/plugins/save-calendar/ical-format.c
index 617405f..fb79479 100644
--- a/plugins/save-calendar/ical-format.c
+++ b/plugins/save-calendar/ical-format.c
@@ -89,7 +89,7 @@ append_tz_to_comp (gpointer key,
 static void
 do_save_calendar_ical (FormatHandler *handler,
                        ESourceSelector *selector,
-                       ECalClientSourceType type,
+		       EClientCache *client_cache,
                        gchar *dest_uri)
 {
 	ESource *primary_source;
@@ -103,8 +103,8 @@ do_save_calendar_ical (FormatHandler *handler,
 
 	/* open source client */
 	primary_source = e_source_selector_ref_primary_selection (selector);
-	source_client = e_cal_client_connect_sync (
-		primary_source, type, NULL, &error);
+	source_client = e_client_cache_get_client_sync (client_cache,
+		primary_source, e_source_selector_get_extension_name (selector), NULL, &error);
 	g_object_unref (primary_source);
 
 	/* Sanity check. */
diff --git a/plugins/save-calendar/rdf-format.c b/plugins/save-calendar/rdf-format.c
index 50abdca..377b5df 100644
--- a/plugins/save-calendar/rdf-format.c
+++ b/plugins/save-calendar/rdf-format.c
@@ -173,7 +173,7 @@ add_string_to_rdf (xmlNodePtr node,
 static void
 do_save_calendar_rdf (FormatHandler *handler,
                       ESourceSelector *selector,
-                      ECalClientSourceType type,
+		      EClientCache *client_cache,
                       gchar *dest_uri)
 {
 
@@ -198,8 +198,8 @@ do_save_calendar_rdf (FormatHandler *handler,
 
 	/* open source client */
 	primary_source = e_source_selector_ref_primary_selection (selector);
-	source_client = e_cal_client_connect_sync (
-		primary_source, type, NULL, &error);
+	source_client = e_client_cache_get_client_sync (client_cache,
+		primary_source, e_source_selector_get_extension_name (selector), NULL, &error);
 	g_object_unref (primary_source);
 
 	/* Sanity check. */
diff --git a/plugins/save-calendar/save-calendar.c b/plugins/save-calendar/save-calendar.c
index c5d373e..723a1c2 100644
--- a/plugins/save-calendar/save-calendar.c
+++ b/plugins/save-calendar/save-calendar.c
@@ -110,7 +110,7 @@ format_handlers_foreach_free (gpointer data)
 
 static void
 ask_destination_and_save (ESourceSelector *selector,
-                          ECalClientSourceType type)
+			  EClientCache *client_cache)
 {
 	FormatHandler *handler = NULL;
 
@@ -219,7 +219,7 @@ ask_destination_and_save (ESourceSelector *selector,
 				dest_uri = temp;
 			}
 
-			handler->save (handler, selector, type, dest_uri);
+			handler->save (handler, selector, client_cache, dest_uri);
 		} else {
 			g_warn_if_reached ();
 		}
@@ -291,17 +291,20 @@ open_for_writing (GtkWindow *parent,
 }
 
 static void
-save_general (EShellView *shell_view,
-              ECalClientSourceType type)
+save_general (EShellView *shell_view)
 {
 	EShellSidebar *shell_sidebar;
+	EShellBackend *shell_backend;
+	EShell *shell;
 	ESourceSelector *selector = NULL;
 
+	shell_backend = e_shell_view_get_shell_backend (shell_view);
 	shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+	shell = e_shell_backend_get_shell (shell_backend);
 	g_object_get (shell_sidebar, "selector", &selector, NULL);
 	g_return_if_fail (selector != NULL);
 
-	ask_destination_and_save (selector, type);
+	ask_destination_and_save (selector, e_shell_get_client_cache (shell));
 
 	g_object_unref (selector);
 }
@@ -310,21 +313,21 @@ static void
 action_calendar_save_as_cb (GtkAction *action,
                             EShellView *shell_view)
 {
-	save_general (shell_view, E_CAL_CLIENT_SOURCE_TYPE_EVENTS);
+	save_general (shell_view);
 }
 
 static void
 action_memo_list_save_as_cb (GtkAction *action,
                              EShellView *shell_view)
 {
-	save_general (shell_view, E_CAL_CLIENT_SOURCE_TYPE_MEMOS);
+	save_general (shell_view);
 }
 
 static void
 action_task_list_save_as_cb (GtkAction *action,
                              EShellView *shell_view)
 {
-	save_general (shell_view, E_CAL_CLIENT_SOURCE_TYPE_TASKS);
+	save_general (shell_view);
 }
 
 gboolean
diff --git a/po/cs.po b/po/cs.po
index 8965467..a660d1c 100644
diff --git a/po/de.po b/po/de.po
index c66b8c1..254443b 100644
diff --git a/po/es.po b/po/es.po
index 043eee2..9247c0a 100644
diff --git a/po/fi.po b/po/fi.po
index d9d7ddb..0eb3c83 100644
diff --git a/po/fr.po b/po/fr.po
index f3a8abc..fc75467 100644
diff --git a/po/gl.po b/po/gl.po
index 0d5f552..a7bdb42 100644
diff --git a/po/lt.po b/po/lt.po
index b5d7139..d7f0d67 100644
diff --git a/po/nb.po b/po/nb.po
index 3644c63..8257359 100644
diff --git a/po/pt.po b/po/pt.po
index c5dd761..2c8d204 100644
diff --git a/shell/e-shell-switcher.c b/shell/e-shell-switcher.c
index a4d6394..a979919 100644
--- a/shell/e-shell-switcher.c
+++ b/shell/e-shell-switcher.c
@@ -53,6 +53,7 @@ struct _EShellSwitcherPrivate {
 	GtkSettings *settings;
 	gulong settings_handler_id;
 	gboolean toolbar_visible;
+	gint hpaned_handle_size;
 };
 
 enum {
@@ -115,7 +116,7 @@ shell_switcher_layout_actions (EShellSwitcher *switcher)
 	}
 
 	/* Figure out how many rows and columns we'll use. */
-	btns_per_row = MAX (1, allocation.width / (max_width + H_PADDING));
+	btns_per_row = MAX (1, (allocation.width - 1) / (max_width + H_PADDING + H_PADDING - switcher->priv->hpaned_handle_size));
 	if (!icons_only) {
 		/* If using text buttons, we want to try to have a
 		 * completely filled-in grid, but if we can't, we want
@@ -150,20 +151,22 @@ shell_switcher_layout_actions (EShellSwitcher *switcher)
 
 	/* Layout the buttons. */
 	for (i = row_last; i >= 0; i--) {
-		gint len, extra_width;
+		gint len, extra_width, left_width;
 
+		left_width = allocation.width - 1;
 		x = H_PADDING + allocation.x;
 		y -= max_height;
 		len = g_list_length (rows[i]);
-		if (!icons_only)
-			extra_width =
-				(allocation.width - (len * max_width) -
-				(len * H_PADDING)) / len;
-		else
-			extra_width = 0;
-		for (p = rows[i]; p != NULL; p = p->next) {
+		for (p = rows[i]; p != NULL; p = p->next, len--) {
 			GtkAllocation child_allocation;
 
+			if (!icons_only)
+				extra_width =
+					(left_width - (len * max_width) -
+					(len * H_PADDING + H_PADDING - switcher->priv->hpaned_handle_size)) / len;
+			else
+				extra_width = 0;
+
 			child_allocation.x = x;
 			child_allocation.y = y;
 			child_allocation.width = max_width + extra_width;
@@ -173,6 +176,7 @@ shell_switcher_layout_actions (EShellSwitcher *switcher)
 				GTK_WIDGET (p->data), &child_allocation);
 
 			x += child_allocation.width + H_PADDING;
+			left_width = left_width - child_allocation.width - H_PADDING;
 		}
 
 		y -= V_PADDING;
@@ -451,6 +455,31 @@ shell_switcher_style_changed (EShellSwitcher *switcher,
 	g_object_notify (G_OBJECT (switcher), "toolbar-style");
 }
 
+static void
+shell_switcher_read_handle_size (EShellSwitcher *switcher)
+{
+	GtkWidget *paned;
+
+	g_return_if_fail (E_IS_SHELL_SWITCHER (switcher));
+
+	paned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
+	gtk_widget_style_get (paned, "handle-size", &switcher->priv->hpaned_handle_size, NULL);
+	gtk_widget_destroy (paned);
+
+	if (switcher->priv->hpaned_handle_size < 0)
+		switcher->priv->hpaned_handle_size = 0;
+	else if (switcher->priv->hpaned_handle_size > H_PADDING)
+		switcher->priv->hpaned_handle_size = H_PADDING;
+}
+
+static void
+shell_switcher_style_updated_cb (EShellSwitcher *switcher)
+{
+	g_return_if_fail (E_IS_SHELL_SWITCHER (switcher));
+
+	shell_switcher_read_handle_size (switcher);
+}
+
 static GtkIconSize
 shell_switcher_get_icon_size (GtkToolShell *shell)
 {
@@ -568,6 +597,12 @@ e_shell_switcher_init (EShellSwitcher *switcher)
 	gtk_widget_set_has_window (GTK_WIDGET (switcher), FALSE);
 
 	e_extensible_load_extensions (E_EXTENSIBLE (switcher));
+
+	switcher->priv->hpaned_handle_size = 5;
+
+	shell_switcher_read_handle_size (switcher);
+
+	g_signal_connect (switcher, "style-updated", G_CALLBACK (shell_switcher_style_updated_cb), NULL);
 }
 
 static void
diff --git a/shell/e-shell-window-actions.c b/shell/e-shell-window-actions.c
index 9146b54..7b5bfea 100644
--- a/shell/e-shell-window-actions.c
+++ b/shell/e-shell-window-actions.c
@@ -40,7 +40,6 @@
 static const gchar *authors[] = {
 	"The Evolution Team",
 	"",
-	"Matthew Barnes <mbarnes@redhat.com>",
 	"Milan Crha <mcrha@redhat.com>",
 	"Fabiano Fid\xC3\xAAncio <fabiano@fidencio.org>",
 	"",

Reply to: