diff --git a/libempathy-gtk/empathy-cell-renderer-text.c b/libempathy-gtk/empathy-cell-renderer-text.c
index d48de32..084be05 100644
--- a/libempathy-gtk/empathy-cell-renderer-text.c
+++ b/libempathy-gtk/empathy-cell-renderer-text.c
@@ -57,6 +57,14 @@ static void cell_renderer_text_get_size          (GtkCellRenderer             *c
 						  gint                        *y_offset,
 						  gint                        *width,
 						  gint                        *height);
+static GtkCellEditable* 
+	    cell_renderer_start_editing		 (GtkCellRenderer             *cell,
+						  GdkEvent                    *event,						     
+						  GtkWidget                   *widget,						     
+						  const gchar                 *path,
+						  GdkRectangle                *background_area,
+						  GdkRectangle                *cell_area,
+						  GtkCellRendererState         flags);
 static void cell_renderer_text_render            (GtkCellRenderer             *cell,
 						  GdkDrawable                 *window,
 						  GtkWidget                   *widget,
@@ -95,6 +103,7 @@ empathy_cell_renderer_text_class_init (EmpathyCellRendererTextClass *klass)
 
 	cell_class->get_size = cell_renderer_text_get_size;
 	cell_class->render = cell_renderer_text_render;
+	cell_class->start_editing = cell_renderer_start_editing;
 
 	g_object_class_install_property (object_class,
 					 PROP_NAME,
@@ -256,6 +265,31 @@ cell_renderer_text_get_size (GtkCellRenderer *cell,
 										      width, height);
 }
 
+static GtkCellEditable*
+cell_renderer_start_editing (GtkCellRenderer      *cell,
+			     GdkEvent             *event,
+			     GtkWidget            *widget,
+			     const gchar          *path,
+			     GdkRectangle         *background_area,
+			     GdkRectangle         *cell_area,
+			     GtkCellRendererState  flags)
+{
+	EmpathyCellRendererText *celltext;
+	
+	celltext = EMPATHY_CELL_RENDERER_TEXT (cell);
+	
+	cell_renderer_text_update_text (celltext,
+					widget,
+					(flags & GTK_CELL_RENDERER_SELECTED));
+	
+	return (GTK_CELL_RENDERER_CLASS 
+			(empathy_cell_renderer_text_parent_class)->start_editing) (
+				cell, event,
+				widget, path,
+				background_area, cell_area,
+				flags);
+}
+
 static void
 cell_renderer_text_render (GtkCellRenderer      *cell,
 			   GdkWindow            *window,
diff --git a/libempathy-gtk/empathy-contact-list-view.c b/libempathy-gtk/empathy-contact-list-view.c
index 9b6a98a..db3dc5f 100644
--- a/libempathy-gtk/empathy-contact-list-view.c
+++ b/libempathy-gtk/empathy-contact-list-view.c
@@ -68,11 +68,17 @@
 
 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EMPATHY_TYPE_CONTACT_LIST_VIEW, EmpathyContactListViewPriv))
 
+static GObjectClass *parent_class = NULL;
+static gchar *edited_group = NULL;
+
 struct _EmpathyContactListViewPriv {
 	EmpathyContactListStore *store;
 	GtkUIManager            *ui;
 	GtkTreeRowReference     *drag_row;
 	gboolean                 interactive;
+	
+	GtkCellRenderer	        *editable_renderer;
+	GtkTreeViewColumn       *editable_column;
 };
 
 typedef struct {
@@ -187,6 +193,10 @@ static void        contact_list_view_action_activated          (EmpathyContactLi
 								EmpathyContact              *contact);
 static void        contact_list_view_voip_activated            (EmpathyContactListView      *view,
 								EmpathyContact              *contact);
+static void        editable_renderer_edited_cb                 (GtkCellRendererText *cell,
+								gchar *path_str,
+								gchar *new_group,
+								EmpathyContactListView *view);
 
 enum {
 	PROP_0,
@@ -300,6 +310,8 @@ empathy_contact_list_view_class_init (EmpathyContactListViewClass *klass)
 {
 	GObjectClass   *object_class = G_OBJECT_CLASS (klass);
 	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+	
+	parent_class = g_type_class_peek_parent (klass);
 
 	object_class->finalize = contact_list_view_finalize;
 	object_class->get_property = contact_list_view_get_property;
@@ -582,6 +594,15 @@ empathy_contact_list_view_get_contact_menu (EmpathyContactListView *view,
 }
 
 static void
+editable_renderer_editing_canceled_cb (GtkCellRenderer *renderer,
+				       EmpathyContactListView *view)
+{
+	g_object_set (G_OBJECT (renderer),
+		      "editable",
+		      FALSE, NULL);
+}
+
+static void
 contact_list_view_setup (EmpathyContactListView *view)
 {
 	EmpathyContactListViewPriv *priv;
@@ -638,6 +659,18 @@ contact_list_view_setup (EmpathyContactListView *view)
 					    "status", EMPATHY_CONTACT_LIST_STORE_COL_STATUS);
 	gtk_tree_view_column_add_attribute (col, cell,
 					    "is_group", EMPATHY_CONTACT_LIST_STORE_COL_IS_GROUP);
+	
+	priv->editable_renderer = cell;
+	priv->editable_column = col;
+	
+	g_signal_connect (cell,
+			  "edited",
+			  G_CALLBACK (editable_renderer_edited_cb),
+			  view);
+	g_signal_connect (cell,
+			  "editing-canceled",
+			  G_CALLBACK (editable_renderer_editing_canceled_cb),
+			  view);
 
 #ifdef HAVE_VOIP
 	/* Voip Capability Icon */
@@ -1234,60 +1267,76 @@ contact_list_view_button_press_event_cb (EmpathyContactListView *view,
 					 gpointer               user_data)
 {
 	EmpathyContactListViewPriv *priv;
-	EmpathyContact             *contact;
-	GtkTreePath               *path;
-	GtkTreeSelection          *selection;
-	GtkTreeModel              *model;
-	GtkTreeIter                iter;
-	gboolean                   row_exists;
-	GtkWidget                 *menu;
+	GtkTreePath *path = NULL;
+	GtkTreeSelection *selection;
+	gboolean call_parent = TRUE, path_is_selected;
 
 	priv = GET_PRIV (view);
-
-	if (!priv->interactive || event->button != 3) {
-		return FALSE;
-	}
-
 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
-	model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
-
-	gtk_widget_grab_focus (GTK_WIDGET (view));
-
-	row_exists = gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (view),
-						    event->x, event->y,
-						    &path,
-						    NULL, NULL, NULL);
-	if (!row_exists) {
-		return FALSE;
-	}
+	
+	if (!priv->interactive) return FALSE;
+
+	if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (view),
+					   event->x,
+					   event->y,
+					   &path,
+					   NULL, NULL, NULL))
+	{
+		path_is_selected = gtk_tree_selection_path_is_selected (selection, path);
+
+		if (!gtk_widget_is_focus (GTK_WIDGET (view)))
+		{
+			gtk_widget_grab_focus (GTK_WIDGET (view));
+		}
 
-	gtk_tree_selection_unselect_all (selection);
-	gtk_tree_selection_select_path (selection, path);
+		if (event->button == 3 && path_is_selected)
+		{
+			call_parent = FALSE;
+		}
 
-	gtk_tree_model_get_iter (model, &iter, path);
-	gtk_tree_path_free (path);
+		if (call_parent)
+		{
+			GTK_WIDGET_CLASS (parent_class)->button_press_event 
+				(GTK_WIDGET (view), event);
+		}
 
-	gtk_tree_model_get (model, &iter,
-			    EMPATHY_CONTACT_LIST_STORE_COL_CONTACT, &contact,
-			    -1);
+		if (event->button == 3)
+		{
+			GtkTreeModel *model;
+			GtkTreeIter iter;
+			EmpathyContact *contact;
+			GtkWidget *menu;
+
+			model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
+			gtk_tree_model_get_iter (model, &iter, path);
+			gtk_tree_model_get (model, &iter,
+					    EMPATHY_CONTACT_LIST_STORE_COL_CONTACT, &contact,
+					    -1);
+			if (contact) {
+				menu = empathy_contact_list_view_get_contact_menu (view, contact);
+				g_object_unref (contact);
+			}
+			else
+			{
+				menu = empathy_contact_list_view_get_group_menu (view);
+			}
+			
+			if (menu)
+			{
+				gtk_widget_show (menu);
+				gtk_menu_popup (GTK_MENU (menu),
+						NULL, NULL, NULL, NULL,
+						event->button, event->time);
+			}
+		}
 
-	if (contact) {
-		menu = empathy_contact_list_view_get_contact_menu (view, contact);
-		g_object_unref (contact);
-	} else {
-		menu = empathy_contact_list_view_get_group_menu (view);
+		gtk_tree_path_free (path);
 	}
-
-	if (!menu) {
-		return FALSE;
+	else
+	{
+		gtk_tree_selection_unselect_all (selection);
 	}
 
-	gtk_widget_show (menu);
-
-	gtk_menu_popup (GTK_MENU (menu),
-			NULL, NULL, NULL, NULL,
-			event->button, event->time);
-
 	return TRUE;
 }
 
@@ -1374,6 +1423,77 @@ contact_list_view_row_expand_or_collapse_cb (EmpathyContactListView *view,
 }
 
 static void
+editable_renderer_edited_cb (GtkCellRendererText *cell,
+			     gchar *path_str,
+			     gchar *new_group,
+			     EmpathyContactListView *view)
+{
+	EmpathyContactListViewPriv *priv;
+	priv = GET_PRIV (view);
+	
+	g_object_set (G_OBJECT (cell),
+                      "editable", FALSE,
+                      NULL);
+
+	if (strcmp (new_group, edited_group) != 0)
+	{
+		EmpathyContactList *list;
+		GtkTreePath *path;
+		GtkTreeModel *model;
+		GtkTreeIter iter;
+
+		list = empathy_contact_list_store_get_list_iface (priv->store);
+		empathy_contact_list_rename_group (list, edited_group, new_group);
+		
+		path = gtk_tree_path_new_from_string (path_str);
+		model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
+
+		gtk_tree_model_get_iter (model, &iter, path);
+		gtk_tree_store_set (GTK_TREE_STORE (priv->store), &iter,
+				    EMPATHY_CONTACT_LIST_STORE_COL_NAME,
+				    new_group, -1);
+		gtk_tree_path_free (path);
+	}
+	g_free (edited_group);
+}
+
+static void
+contact_list_view_rename_group (EmpathyContactListView *view,
+				gchar *group)
+{
+	GtkTreePath *path;
+	GtkTreeSelection *selection;
+	GList *rows;
+	GtkTreeModel *model;
+	EmpathyContactListViewPriv *priv;
+	
+	priv = GET_PRIV (view);
+
+	selection = gtk_tree_view_get_selection	(GTK_TREE_VIEW (view));
+	rows = gtk_tree_selection_get_selected_rows (selection, &model);
+	if (rows == NULL)
+	{
+		return;
+	}
+	
+	path = rows->data;
+	edited_group = g_strdup (group);
+
+	g_object_set (G_OBJECT (priv->editable_renderer),
+                      "editable-set", TRUE,
+		      "editable", TRUE,
+                      NULL);
+
+	gtk_tree_view_set_cursor_on_cell (GTK_TREE_VIEW (view), path,
+					  priv->editable_column,
+					  priv->editable_renderer,
+					  TRUE);
+
+	g_list_foreach (rows, (GFunc) gtk_tree_path_free, NULL);
+        g_list_free (rows);	
+}
+
+static void
 contact_list_view_action_cb (GtkAction             *action,
 			     EmpathyContactListView *view)
 {
@@ -1427,6 +1547,7 @@ contact_list_view_action_cb (GtkAction             *action,
 					parent);
 	}
 	else if (group && strcmp (name, "Rename") == 0) {
+		contact_list_view_rename_group (view, group);
 	}
 
 	g_free (group);
