diff --git a/src/empathy-misc.c b/src/empathy-misc.c
index a1a0847..94f43ea 100644
--- a/src/empathy-misc.c
+++ b/src/empathy-misc.c
@@ -26,6 +26,117 @@
 #include <libempathy/empathy-utils.h>
 #include <libempathy-gtk/empathy-ui-utils.h>
 #include <libempathy-gtk/empathy-conf.h>
+#include <libnotify/notify.h>
+
+#define ACTIONS          "actions"
+#define BODY             "body"
+#define BODY_HYPERLINKS  "body-hyperlinks"
+#define BODY_IMAGES      "body-images"
+#define BODY_MARKUP      "body-markup"
+#define ICON_MULTI       "icon-multi"
+#define ICON_STATIC      "icon-static"
+#define SOUND            "sound"
+#define IMAGE_SVG        "image/svg+xml"
+#define SYNCHRONOUS      "x-canonical-synchronous"
+#define APPEND           "x-canonical-append"
+#define LAYOUT_ICON_ONLY "x-canonical-icon-only"
+
+static gboolean g_capabilities[CAP_MAX] = {
+	FALSE, /* array init       */
+	FALSE, /* actions          */
+	FALSE, /* body             */
+	FALSE, /* body-hyperlinks  */
+	FALSE, /* body-imges       */
+	FALSE, /* body-markup      */
+	FALSE, /* icon-multi       */
+	FALSE, /* icon-static      */
+	FALSE, /* sound            */
+	FALSE, /* image/svg+xml    */
+	FALSE, /* synchronous-hint */
+	FALSE, /* append-hint      */
+	FALSE  /* icon-only-hint   */
+};
+
+static int have_notify_osd = -1;
+
+static void
+set_cap (gpointer data,
+         gpointer user_data)
+{
+	/* test for "actions" */
+	if (!g_strcmp0 (ACTIONS, (gchar*) data)) {
+		g_capabilities[CAP_ACTIONS] = TRUE;
+	}
+
+	/* test for "body" */
+	if (!g_strcmp0 (BODY, (gchar*) data)) {
+		g_capabilities[CAP_BODY] = TRUE;
+	}
+
+	/* test for "body-hyperlinks" */
+	if (!g_strcmp0 (BODY_HYPERLINKS, (gchar*) data)) {
+		g_capabilities[CAP_BODY_HYPERLINKS] = TRUE;
+	}
+
+	/* test for "body-images" */
+	if (!g_strcmp0 (BODY_IMAGES, (gchar*) data)) {
+		g_capabilities[CAP_BODY_IMAGES] = TRUE;
+	}
+
+	/* test for "body-markup" */
+	if (!g_strcmp0 (BODY_MARKUP, (gchar*) data)) {
+		g_capabilities[CAP_BODY_MARKUP] = TRUE;
+	}
+
+	/* test for "icon-multi" */
+	if (!g_strcmp0 (ICON_MULTI, (gchar*) data)) {
+		g_capabilities[CAP_ICON_MULTI] = TRUE;
+	}
+
+	/* test for "icon-static" */
+	if (!g_strcmp0 (ICON_STATIC, (gchar*) data)) {
+		g_capabilities[CAP_ICON_STATIC] = TRUE;
+	}
+
+	/* test for "sound" */
+	if (!g_strcmp0 (SOUND, (gchar*) data)) {
+		g_capabilities[CAP_SOUND] = TRUE;
+	}
+
+	/* test for "image/svg+xml" */
+	if (!g_strcmp0 (IMAGE_SVG, (gchar*) data)) {
+		g_capabilities[CAP_IMAGE_SVG] = TRUE;
+	}
+
+	/* test for "canonical-private-1" */
+	if (!g_strcmp0 (SYNCHRONOUS, (gchar*) data)) {
+		g_capabilities[CAP_SYNCHRONOUS] = TRUE;
+	}
+
+	/* test for "canonical-private-2" */
+	if (!g_strcmp0 (APPEND, (gchar*) data)) {
+		g_capabilities[CAP_APPEND] = TRUE;
+	}
+
+	/* test for "canonical-private-3" */
+	if (!g_strcmp0 (LAYOUT_ICON_ONLY, (gchar*) data)) {
+		g_capabilities[CAP_LAYOUT_ICON_ONLY] = TRUE;
+	}
+}
+
+static void
+init_caps (void)
+{
+	GList* caps_list;
+
+	caps_list = notify_get_server_caps ();
+	if (caps_list)
+	{
+		g_list_foreach (caps_list, set_cap, NULL);
+		g_list_foreach (caps_list, (GFunc) g_free, NULL);
+		g_list_free (caps_list);
+	}
+}
 
 /* public methods */
 
@@ -34,17 +145,44 @@ empathy_misc_get_pixbuf_for_notification (EmpathyContact *contact,
 					  const char *icon_name)
 {
 	GdkPixbuf *pixbuf = NULL;
+	gint       size;
+	gchar     *server_name = NULL;
+
+	if (have_notify_osd == -1) {
+		notify_get_server_info (&server_name, NULL, NULL, NULL);
+		if (!g_strcmp0 ("notify-osd", server_name)) {
+			have_notify_osd = TRUE;
+		}
+		else {
+			have_notify_osd = FALSE;
+		}
+	}
+
+	if (have_notify_osd) {
+		size = 128;
+
+		/* change the default new message icon with
+		the one shipped by notify-osd */
+		if (!g_strcmp0 (icon_name, "im-message-new")) {
+			icon_name = "notification-message-im";
+		}
+	}
+	else {
+		size = 48;
+	}
 
 	if (contact != NULL) {
 		pixbuf = empathy_pixbuf_avatar_from_contact_scaled (contact,
-								    48, 48);
+								    size, size);
 	}
 
 	if (!pixbuf) {
 		pixbuf = empathy_pixbuf_from_icon_name_sized
-					(icon_name, 48);
+					(icon_name, size);
 	}
 
+	g_free (server_name);
+
 	return pixbuf;
 }
 
@@ -75,3 +213,11 @@ empathy_notification_is_enabled (void)
 	return TRUE;
 }
 
+gboolean
+empathy_notification_supports (EmpathyNotificationCapability cap)
+{
+	if (!g_capabilities[0]) {
+		init_caps ();
+	}
+	return g_capabilities[cap];
+}
\ No newline at end of file
diff --git a/src/empathy-misc.h b/src/empathy-misc.h
index b3fe8fd..e67d87b 100644
--- a/src/empathy-misc.h
+++ b/src/empathy-misc.h
@@ -40,7 +40,24 @@ typedef enum {
 	EMPATHY_NOTIFICATION_CLOSED_RESERVED = 4
 } EmpathyNotificationClosedReason;
 
+typedef enum {
+    CAP_ACTIONS = 1,
+    CAP_BODY,
+    CAP_BODY_HYPERLINKS,
+    CAP_BODY_IMAGES,
+    CAP_BODY_MARKUP,
+    CAP_ICON_MULTI,
+    CAP_ICON_STATIC,
+    CAP_SOUND,
+    CAP_IMAGE_SVG,
+    CAP_SYNCHRONOUS,
+    CAP_APPEND,
+    CAP_LAYOUT_ICON_ONLY,
+    CAP_MAX
+} EmpathyNotificationCapability;
+
 gboolean    empathy_notification_is_enabled  (void);
+gboolean    empathy_notification_supports (EmpathyNotificationCapability cap);
 GdkPixbuf * empathy_misc_get_pixbuf_for_notification (EmpathyContact *contact,
                                                       const char *icon_name);
 
diff --git a/src/empathy-status-icon.c b/src/empathy-status-icon.c
index f6c63c5..ee09f9c 100644
--- a/src/empathy-status-icon.c
+++ b/src/empathy-status-icon.c
@@ -89,15 +89,20 @@ status_icon_notification_closed_cb (NotifyNotification *notification,
 #ifdef notify_notification_get_closed_reason
 	reason = notify_notification_get_closed_reason (notification);
 #endif
-	if (priv->notification) {
-		g_object_unref (priv->notification);
-		priv->notification = NULL;
-	}
+
+	g_object_unref (notification);
 
 	if (!priv->event) {
 		return;
 	}
 
+	/* there's another pending notification caused by an append */
+	if (notification != priv->notification) {
+		return;
+	}
+
+	priv->notification = NULL;
+
 	/* the notification has been closed by the user, see the
 	 * DesktopNotification spec.
 	 */
@@ -139,20 +144,32 @@ status_icon_update_notification (EmpathyStatusIcon *icon)
 		pixbuf = empathy_misc_get_pixbuf_for_notification (priv->event->contact,
 								   priv->event->icon_name);
 
-		if (priv->notification) {
+		/* replace only if append is not supported
+		and if having a previous notification */
+		if (!empathy_notification_supports (CAP_APPEND) &&
+		    priv->notification != NULL) {
 			notify_notification_update (priv->notification,
 						    priv->event->header, priv->event->message,
 						    NULL);
 		} else {
 			priv->notification = notify_notification_new_with_status_icon
 				(priv->event->header, priv->event->message, NULL, priv->icon);
+
+			/* set the append hint if it is supported */
+			if (empathy_notification_supports (CAP_APPEND)) {
+				notify_notification_set_hint_string (priv->notification,
+				                                     "x-canonical-append",
+				                                     "allowed");
+			}
+
+			/* set the expires timeout */
 			notify_notification_set_timeout (priv->notification,
 							 NOTIFY_EXPIRES_DEFAULT);
 
 			g_signal_connect (priv->notification, "closed",
 					  G_CALLBACK (status_icon_notification_closed_cb), icon);
 
- 		}
+		}
 		/* if icon doesn't exist libnotify will crash */
 		if (pixbuf != NULL)
 			notify_notification_set_icon_from_pixbuf (priv->notification,
