diff --git a/eel/Makefile.am b/eel/Makefile.am
index 184d9dd..4805dc7 100644
--- a/eel/Makefile.am
+++ b/eel/Makefile.am
@@ -60,6 +60,7 @@ libeel_2_la_SOURCES =				\
 	eel-wrap-table.c			\
 	eel-xml-extensions.c			\
 	eel-lib-self-check-functions.h		\
+	gossip-cell-renderer-expander.c		\
 	$(NULL)
 
 eel_headers =					\
@@ -98,6 +99,7 @@ eel_headers =					\
 	eel-wrap-table.h			\
 	eel-xml-extensions.h			\
 	eel.h					\
+	gossip-cell-renderer-expander.h		\
 	$(NULL)
 
 marshal_sources = 				\
diff --git a/eel/gossip-cell-renderer-expander.c b/eel/gossip-cell-renderer-expander.c
new file mode 100644
index 0000000..8378d54
--- /dev/null
+++ b/eel/gossip-cell-renderer-expander.c
@@ -0,0 +1,513 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2006  Kristian Rietveld <kris@babi-pangang.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* To do:
+ *  - should probably cancel animation if model changes
+ *  - need to handle case where node-in-animation is removed
+ *  - it only handles a single animation at a time; but I guess users
+ *    aren't fast enough to trigger two or more animations at once anyway :P
+ *    (could guard for this by just cancelling the "old" animation, and
+ *     start the new one).
+ */
+
+#include <config.h>
+
+#include <gtk/gtk.h>
+
+#include "gossip-cell-renderer-expander.h"
+
+#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GOSSIP_TYPE_CELL_RENDERER_EXPANDER, GossipCellRendererExpanderPriv))
+
+static void     gossip_cell_renderer_expander_init         (GossipCellRendererExpander      *expander);
+static void     gossip_cell_renderer_expander_class_init   (GossipCellRendererExpanderClass *klass);
+static void     gossip_cell_renderer_expander_get_property (GObject                         *object,
+							    guint                            param_id,
+							    GValue                          *value,
+							    GParamSpec                      *pspec);
+static void     gossip_cell_renderer_expander_set_property (GObject                         *object,
+							    guint                            param_id,
+							    const GValue                    *value,
+							    GParamSpec                      *pspec);
+static void     gossip_cell_renderer_expander_finalize     (GObject                         *object);
+static void     gossip_cell_renderer_expander_get_size     (GtkCellRenderer                 *cell,
+							    GtkWidget                       *widget,
+							    GdkRectangle                    *cell_area,
+							    gint                            *x_offset,
+							    gint                            *y_offset,
+							    gint                            *width,
+							    gint                            *height);
+static void     gossip_cell_renderer_expander_render       (GtkCellRenderer                 *cell,
+							    GdkWindow                       *window,
+							    GtkWidget                       *widget,
+							    GdkRectangle                    *background_area,
+							    GdkRectangle                    *cell_area,
+							    GdkRectangle                    *expose_area,
+							    GtkCellRendererState             flags);
+static gboolean gossip_cell_renderer_expander_activate     (GtkCellRenderer                 *cell,
+							    GdkEvent                        *event,
+							    GtkWidget                       *widget,
+							    const gchar                     *path,
+							    GdkRectangle                    *background_area,
+							    GdkRectangle                    *cell_area,
+							    GtkCellRendererState             flags);
+
+/* Properties */
+enum {
+	PROP_0,
+	PROP_EXPANDER_STYLE,
+	PROP_EXPANDER_SIZE,
+	PROP_ACTIVATABLE
+};
+
+typedef struct _GossipCellRendererExpanderPriv GossipCellRendererExpanderPriv;
+
+struct _GossipCellRendererExpanderPriv {
+	GtkExpanderStyle     expander_style;
+	gint                 expander_size;
+
+	GtkTreeView         *animation_view;
+	GtkTreeRowReference *animation_node;
+	GtkExpanderStyle     animation_style;
+	guint                animation_timeout;
+	GdkRectangle         animation_area;
+
+	guint                activatable : 1;
+	guint                animation_expanding : 1;
+};
+
+G_DEFINE_TYPE (GossipCellRendererExpander, gossip_cell_renderer_expander, GTK_TYPE_CELL_RENDERER)
+
+static void
+gossip_cell_renderer_expander_init (GossipCellRendererExpander *expander)
+{
+	GossipCellRendererExpanderPriv *priv;
+
+	priv = GET_PRIV (expander);
+
+	priv->expander_style = GTK_EXPANDER_COLLAPSED;
+	priv->expander_size = 12;
+	priv->activatable = TRUE;
+	priv->animation_node = NULL;
+
+	GTK_CELL_RENDERER (expander)->xpad = 2;
+	GTK_CELL_RENDERER (expander)->ypad = 2;
+	GTK_CELL_RENDERER (expander)->mode = GTK_CELL_RENDERER_MODE_ACTIVATABLE;
+}
+
+static void
+gossip_cell_renderer_expander_class_init (GossipCellRendererExpanderClass *klass)
+{
+	GObjectClass         *object_class;
+	GtkCellRendererClass *cell_class;
+
+	object_class  = G_OBJECT_CLASS (klass);
+	cell_class = GTK_CELL_RENDERER_CLASS (klass);
+
+	object_class->finalize = gossip_cell_renderer_expander_finalize;
+
+	object_class->get_property = gossip_cell_renderer_expander_get_property;
+	object_class->set_property = gossip_cell_renderer_expander_set_property;
+
+	cell_class->get_size = gossip_cell_renderer_expander_get_size;
+	cell_class->render = gossip_cell_renderer_expander_render;
+	cell_class->activate = gossip_cell_renderer_expander_activate;
+
+	g_object_class_install_property (object_class,
+					 PROP_EXPANDER_STYLE,
+					 g_param_spec_enum ("expander-style",
+							    "Expander Style",
+							    "Style to use when painting the expander",
+							    GTK_TYPE_EXPANDER_STYLE,
+							    GTK_EXPANDER_COLLAPSED,
+							    G_PARAM_READWRITE));
+
+	g_object_class_install_property (object_class,
+					 PROP_EXPANDER_SIZE,
+					 g_param_spec_int ("expander-size",
+							   "Expander Size",
+							   "The size of the expander",
+							   0,
+							   G_MAXINT,
+							   12,
+							   G_PARAM_READWRITE));
+
+	g_object_class_install_property (object_class,
+					 PROP_ACTIVATABLE,
+					 g_param_spec_boolean ("activatable",
+							       "Activatable",
+							       "The expander can be activated",
+							       TRUE,
+							       G_PARAM_READWRITE));
+
+	g_type_class_add_private (object_class, sizeof (GossipCellRendererExpanderPriv));
+}
+
+static void
+gossip_cell_renderer_expander_get_property (GObject    *object,
+					    guint       param_id,
+					    GValue     *value,
+					    GParamSpec *pspec)
+{
+	GossipCellRendererExpander     *expander;
+	GossipCellRendererExpanderPriv *priv;
+
+	expander = GOSSIP_CELL_RENDERER_EXPANDER (object);
+	priv = GET_PRIV (expander);
+
+	switch (param_id) {
+	case PROP_EXPANDER_STYLE:
+		g_value_set_enum (value, priv->expander_style);
+		break;
+
+	case PROP_EXPANDER_SIZE:
+		g_value_set_int (value, priv->expander_size);
+		break;
+
+	case PROP_ACTIVATABLE:
+		g_value_set_boolean (value, priv->activatable);
+		break;
+
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	}
+}
+
+static void
+gossip_cell_renderer_expander_set_property (GObject      *object,
+					    guint         param_id,
+					    const GValue *value,
+					    GParamSpec   *pspec)
+{
+	GossipCellRendererExpander     *expander;
+	GossipCellRendererExpanderPriv *priv;
+
+	expander = GOSSIP_CELL_RENDERER_EXPANDER (object);
+	priv = GET_PRIV (expander);
+
+	switch (param_id) {
+	case PROP_EXPANDER_STYLE:
+		priv->expander_style = g_value_get_enum (value);
+		break;
+
+	case PROP_EXPANDER_SIZE:
+		priv->expander_size = g_value_get_int (value);
+		break;
+
+	case PROP_ACTIVATABLE:
+		priv->activatable = g_value_get_boolean (value);
+		break;
+
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	}
+}
+
+static void
+gossip_cell_renderer_expander_finalize (GObject *object)
+{
+	GossipCellRendererExpanderPriv *priv;
+
+	priv = GET_PRIV (object);
+
+	if (priv->animation_timeout) {
+		g_source_remove (priv->animation_timeout);
+		priv->animation_timeout = 0;
+	}
+
+	if (priv->animation_node) {
+		gtk_tree_row_reference_free (priv->animation_node);
+	}
+
+	(* G_OBJECT_CLASS (gossip_cell_renderer_expander_parent_class)->finalize) (object);
+}
+
+GtkCellRenderer *
+gossip_cell_renderer_expander_new (void)
+{
+	return g_object_new (GOSSIP_TYPE_CELL_RENDERER_EXPANDER, NULL);
+}
+
+static void
+gossip_cell_renderer_expander_get_size (GtkCellRenderer *cell,
+					GtkWidget       *widget,
+					GdkRectangle    *cell_area,
+					gint            *x_offset,
+					gint            *y_offset,
+					gint            *width,
+					gint            *height)
+{
+	GossipCellRendererExpander     *expander;
+	GossipCellRendererExpanderPriv *priv;
+
+	expander = (GossipCellRendererExpander*) cell;
+	priv = GET_PRIV (expander);
+
+	if (cell_area) {
+		if (x_offset) {
+			*x_offset = cell->xalign * (cell_area->width - (priv->expander_size + (2 * cell->xpad)));
+			*x_offset = MAX (*x_offset, 0);
+		}
+
+		if (y_offset) {
+			*y_offset = cell->yalign * (cell_area->height - (priv->expander_size + (2 * cell->ypad)));
+			*y_offset = MAX (*y_offset, 0);
+		}
+	} else {
+		if (x_offset)
+			*x_offset = 0;
+
+		if (y_offset)
+			*y_offset = 0;
+	}
+
+	if (width)
+		*width = cell->xpad * 2 + priv->expander_size;
+
+	if (height)
+		*height = cell->ypad * 2 + priv->expander_size;
+}
+
+static void
+gossip_cell_renderer_expander_render (GtkCellRenderer      *cell,
+				      GdkWindow            *window,
+				      GtkWidget            *widget,
+				      GdkRectangle         *background_area,
+				      GdkRectangle         *cell_area,
+				      GdkRectangle         *expose_area,
+				      GtkCellRendererState  flags)
+{
+	GossipCellRendererExpander     *expander;
+	GossipCellRendererExpanderPriv *priv;
+	GtkExpanderStyle                expander_style;
+	gint                            x_offset, y_offset;
+
+	expander = (GossipCellRendererExpander*) cell;
+	priv = GET_PRIV (expander);
+
+	if (priv->animation_node) {
+		GtkTreePath *path;
+		GdkRectangle rect;
+
+		/* Not sure if I like this ... */
+		path = gtk_tree_row_reference_get_path (priv->animation_node);
+		gtk_tree_view_get_background_area (priv->animation_view, path,
+						   NULL, &rect);
+		gtk_tree_path_free (path);
+
+		if (background_area->y == rect.y)
+			expander_style = priv->animation_style;
+		else
+			expander_style = priv->expander_style;
+	} else
+		expander_style = priv->expander_style;
+
+	gossip_cell_renderer_expander_get_size (cell, widget, cell_area,
+						&x_offset, &y_offset,
+						NULL, NULL);
+
+	gtk_paint_expander (widget->style,
+			    window,
+			    GTK_STATE_NORMAL,
+			    expose_area,
+			    widget,
+			    "treeview",
+			    cell_area->x + x_offset + cell->xpad + priv->expander_size / 2,
+			    cell_area->y + y_offset + cell->ypad + priv->expander_size / 2,
+			    expander_style);
+}
+
+static void
+invalidate_node (GtkTreeView *tree_view,
+		 GtkTreePath *path)
+{
+       GdkWindow    *bin_window;
+       GdkRectangle  rect;
+
+       bin_window = gtk_tree_view_get_bin_window (tree_view);
+
+       gtk_tree_view_get_background_area (tree_view, path, NULL, &rect);
+
+       rect.x = 0;
+       rect.width = GTK_WIDGET (tree_view)->allocation.width;
+
+       gdk_window_invalidate_rect (bin_window, &rect, TRUE);
+}
+
+static gboolean
+do_animation (GossipCellRendererExpander *expander)
+{
+	GossipCellRendererExpanderPriv *priv;
+	GtkTreePath                    *path;
+	gboolean                        done = FALSE;
+
+	priv = GET_PRIV (expander);
+
+	if (priv->animation_expanding) {
+		if (priv->animation_style == GTK_EXPANDER_SEMI_COLLAPSED)
+			priv->animation_style = GTK_EXPANDER_SEMI_EXPANDED;
+		else if (priv->animation_style == GTK_EXPANDER_SEMI_EXPANDED) {
+			priv->animation_style = GTK_EXPANDER_EXPANDED;
+			done = TRUE;
+		}
+	} else {
+		if (priv->animation_style == GTK_EXPANDER_SEMI_EXPANDED)
+			priv->animation_style = GTK_EXPANDER_SEMI_COLLAPSED;
+		else if (priv->animation_style == GTK_EXPANDER_SEMI_COLLAPSED) {
+			priv->animation_style = GTK_EXPANDER_COLLAPSED;
+			done = TRUE;
+		}
+	}
+
+	path = gtk_tree_row_reference_get_path (priv->animation_node);
+	invalidate_node (priv->animation_view, path);
+	gtk_tree_path_free (path);
+
+	if (done) {
+		gtk_tree_row_reference_free (priv->animation_node);
+		priv->animation_node = NULL;
+		priv->animation_timeout = 0;
+	}
+
+	return !done;
+}
+
+static gboolean
+animation_timeout (gpointer data)
+{
+	gboolean retval;
+
+	GDK_THREADS_ENTER ();
+
+	retval = do_animation (data);
+
+	GDK_THREADS_LEAVE ();
+
+	return retval;
+}
+
+static void
+gossip_cell_renderer_expander_start_animation (GossipCellRendererExpander *expander,
+					       GtkTreeView                *tree_view,
+					       GtkTreePath                *path,
+					       gboolean                    expanding,
+					       GdkRectangle               *background_area)
+{
+	GossipCellRendererExpanderPriv *priv;
+
+	priv = GET_PRIV (expander);
+
+	if (expanding) {
+		priv->animation_style = GTK_EXPANDER_SEMI_COLLAPSED;
+	} else {
+		priv->animation_style = GTK_EXPANDER_SEMI_EXPANDED;
+	}
+
+	invalidate_node (tree_view, path);
+
+	priv->animation_expanding = expanding;
+	priv->animation_view = tree_view;
+	priv->animation_node = gtk_tree_row_reference_new (gtk_tree_view_get_model (tree_view), path);
+	priv->animation_timeout = g_timeout_add (50, animation_timeout, expander);
+}
+
+static gboolean
+gossip_cell_renderer_expander_activate (GtkCellRenderer      *cell,
+					GdkEvent             *event,
+					GtkWidget            *widget,
+					const gchar          *path_string,
+					GdkRectangle         *background_area,
+					GdkRectangle         *cell_area,
+					GtkCellRendererState  flags)
+{
+	GossipCellRendererExpander     *expander;
+	GossipCellRendererExpanderPriv *priv;
+	GtkTreePath                    *path;
+	GtkSettings                    *settings;
+	gboolean                        animate;
+	gboolean                        expanding;
+	gboolean                        in_cell;
+	int                             mouse_x;
+	int                             mouse_y;
+
+	expander = GOSSIP_CELL_RENDERER_EXPANDER (cell);
+	priv = GET_PRIV (cell);
+
+	if (!GTK_IS_TREE_VIEW (widget) || !priv->activatable)
+		return FALSE;
+
+	path = gtk_tree_path_new_from_string (path_string);
+
+	gtk_widget_get_pointer (widget, &mouse_x, &mouse_y);
+	gtk_tree_view_widget_to_tree_coords (GTK_TREE_VIEW (widget),
+					     mouse_x,
+					     mouse_y,
+					     &mouse_x,
+					     &mouse_y);
+
+	/* check if click is within the cell */
+	if (mouse_x - cell_area->x >= 0
+	    && mouse_x - cell_area->x <= cell_area->width) {
+		in_cell = TRUE;
+	} else {
+		in_cell = FALSE;
+	}
+
+	if (! in_cell) {
+		return FALSE;
+	}
+
+#if 0
+	if (gtk_tree_path_get_depth (path) > 1) {
+		gtk_tree_path_free (path);
+		return TRUE;
+	}
+#endif
+
+	settings = gtk_widget_get_settings (GTK_WIDGET (widget));
+	if (g_object_class_find_property (G_OBJECT_GET_CLASS (settings), "gtk-enable-animations")) {
+		g_object_get (settings,
+			      "gtk-enable-animations", &animate,
+			      NULL);
+	} else {
+		animate = FALSE;
+	}
+
+	if (gtk_tree_view_row_expanded (GTK_TREE_VIEW (widget), path)) {
+		gtk_tree_view_collapse_row (GTK_TREE_VIEW (widget), path);
+		expanding = FALSE;
+	} else {
+		gtk_tree_view_expand_row (GTK_TREE_VIEW (widget), path, FALSE);
+		expanding = TRUE;
+	}
+
+	if (animate) {
+		gossip_cell_renderer_expander_start_animation (expander,
+							       GTK_TREE_VIEW (widget),
+							       path,
+							       expanding,
+							       background_area);
+	}
+
+	gtk_tree_path_free (path);
+
+	return TRUE;
+}
diff --git a/eel/gossip-cell-renderer-expander.h b/eel/gossip-cell-renderer-expander.h
new file mode 100644
index 0000000..79cdbcf
--- /dev/null
+++ b/eel/gossip-cell-renderer-expander.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2006  Kristian Rietveld <kris@babi-pangang.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GOSSIP_CELL_RENDERER_EXPANDER_H__
+#define __GOSSIP_CELL_RENDERER_EXPANDER_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GOSSIP_TYPE_CELL_RENDERER_EXPANDER		(gossip_cell_renderer_expander_get_type ())
+#define GOSSIP_CELL_RENDERER_EXPANDER(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), GOSSIP_TYPE_CELL_RENDERER_EXPANDER, GossipCellRendererExpander))
+#define GOSSIP_CELL_RENDERER_EXPANDER_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), GOSSIP_TYPE_CELL_RENDERER_EXPANDER, GossipCellRendererExpanderClass))
+#define GOSSIP_IS_CELL_RENDERER_EXPANDER(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOSSIP_TYPE_CELL_RENDERER_EXPANDER))
+#define GOSSIP_IS_CELL_RENDERER_EXPANDER_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), GOSSIP_TYPE_CELL_RENDERER_EXPANDER))
+#define GOSSIP_CELL_RENDERER_EXPANDER_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj), GOSSIP_TYPE_CELL_RENDERER_EXPANDER, GossipCellRendererExpanderClass))
+
+typedef struct _GossipCellRendererExpander GossipCellRendererExpander;
+typedef struct _GossipCellRendererExpanderClass GossipCellRendererExpanderClass;
+
+struct _GossipCellRendererExpander {
+  GtkCellRenderer parent;
+};
+
+struct _GossipCellRendererExpanderClass {
+  GtkCellRendererClass parent_class;
+
+  /* Padding for future expansion */
+  void (*_gtk_reserved1) (void);
+  void (*_gtk_reserved2) (void);
+  void (*_gtk_reserved3) (void);
+  void (*_gtk_reserved4) (void);
+};
+
+GType            gossip_cell_renderer_expander_get_type (void) G_GNUC_CONST;
+GtkCellRenderer *gossip_cell_renderer_expander_new      (void);
+
+G_END_DECLS
+
+#endif /* __GOSSIP_CELL_RENDERER_EXPANDER_H__ */
diff --git a/src/nautilus-places-sidebar.c b/src/nautilus-places-sidebar.c
index 467475d..8c69c27 100644
--- a/src/nautilus-places-sidebar.c
+++ b/src/nautilus-places-sidebar.c
@@ -29,6 +29,7 @@
 #include <eel/eel-preferences.h>
 #include <eel/eel-string.h>
 #include <eel/eel-stock-dialogs.h>
+#include <eel/gossip-cell-renderer-expander.h>
 #include <gdk/gdkkeysyms.h>
 #include <gtk/gtk.h>
 #include <glib/gi18n.h>
@@ -61,10 +62,11 @@
 typedef struct {
 	GtkScrolledWindow  parent;
 	GtkTreeView        *tree_view;
+	GtkCellRenderer    *indent_renderer;
 	GtkCellRenderer    *icon_cell_renderer;
 	GtkCellRenderer    *eject_text_cell_renderer;
 	char 	           *uri;
-	GtkListStore       *store;
+	GtkTreeStore       *store;
 	GtkTreeModel       *filter_model;
 	NautilusWindowInfo *window;
 	NautilusBookmarkList *bookmarks;
@@ -127,7 +129,7 @@ typedef enum {
 	PLACES_BUILT_IN,
 	PLACES_MOUNTED_VOLUME,
 	PLACES_BOOKMARK,
-	PLACES_SEPARATOR
+	PLACES_HEADER
 } PlaceType;
 
 static void  nautilus_places_sidebar_iface_init        (NautilusSidebarIface         *iface);
@@ -205,6 +207,7 @@ G_DEFINE_TYPE_WITH_CODE (NautilusPlacesSidebarProvider, nautilus_places_sidebar_
 static GtkTreeIter
 add_place (NautilusPlacesSidebar *sidebar,
 	   PlaceType place_type,
+	   GtkTreeIter *parent_iter,
 	   const char *name,
 	   GIcon *icon,
 	   const char *uri,
@@ -219,11 +222,14 @@ add_place (NautilusPlacesSidebar *sidebar,
 	int icon_size;
 	gboolean show_eject, show_unmount;
 
+	pixbuf = NULL;
 	icon_size = nautilus_get_icon_size_for_stock_size (GTK_ICON_SIZE_MENU);
-	icon_info = nautilus_icon_info_lookup (icon, icon_size);
+	if (icon) {
+		icon_info = nautilus_icon_info_lookup (icon, icon_size);
+		pixbuf = nautilus_icon_info_get_pixbuf_at_size (icon_info, icon_size);
+		g_object_unref (icon_info);
+	}
 
-	pixbuf = nautilus_icon_info_get_pixbuf_at_size (icon_info, icon_size);
-	g_object_unref (icon_info);
 	check_unmount_and_eject (mount, volume, drive,
 				 &show_unmount, &show_eject);
 
@@ -231,9 +237,14 @@ add_place (NautilusPlacesSidebar *sidebar,
 		g_assert (place_type != PLACES_BOOKMARK);
 	}
  		  
-	gtk_list_store_append (sidebar->store, &iter);
-	gtk_list_store_set (sidebar->store, &iter,
-			    PLACES_SIDEBAR_COLUMN_ICON, pixbuf,
+	if (place_type == PLACES_HEADER) {
+		gtk_tree_store_append (sidebar->store, &iter, NULL);
+		*parent_iter = iter;
+	} else {
+		gtk_tree_store_append (sidebar->store, &iter, parent_iter);
+	}
+	gtk_tree_store_set (sidebar->store, &iter,
+			    PLACES_SIDEBAR_COLUMN_ICON, (icon) ? pixbuf : NULL,
 			    PLACES_SIDEBAR_COLUMN_NAME, name,
 			    PLACES_SIDEBAR_COLUMN_URI, uri,
 			    PLACES_SIDEBAR_COLUMN_DRIVE, drive,
@@ -277,11 +288,16 @@ update_places (NautilusPlacesSidebar *sidebar)
 	NautilusWindowSlotInfo *slot;
 
 	selection = gtk_tree_view_get_selection (sidebar->tree_view);
-	gtk_list_store_clear (sidebar->store);
+	gtk_tree_store_clear (sidebar->store);
 
 	slot = nautilus_window_info_get_active_slot (sidebar->window);
 	location = nautilus_window_slot_info_get_current_location (slot);
 
+	/* First header */
+	last_iter = add_place (sidebar, PLACES_HEADER, &iter,
+			      _("Computer"),  NULL, NULL, 
+			       NULL, NULL, NULL, 0);
+
 	/* add built in bookmarks */
 	desktop_path = nautilus_get_desktop_directory ();
 
@@ -291,7 +307,7 @@ update_places (NautilusPlacesSidebar *sidebar)
 		mount_uri = nautilus_get_home_directory_uri ();
 		display_name = g_filename_display_basename (g_get_home_dir ());
 		icon = g_themed_icon_new (NAUTILUS_ICON_HOME);
-		last_iter = add_place (sidebar, PLACES_BUILT_IN,
+		last_iter = add_place (sidebar, PLACES_BUILT_IN, &iter,
 				       display_name, icon,
 				       mount_uri, NULL, NULL, NULL, 0);
 		g_object_unref (icon);
@@ -304,7 +320,7 @@ update_places (NautilusPlacesSidebar *sidebar)
 
 	mount_uri = g_filename_to_uri (desktop_path, NULL, NULL);
 	icon = g_themed_icon_new (NAUTILUS_ICON_DESKTOP);
-	last_iter = add_place (sidebar, PLACES_BUILT_IN,
+	last_iter = add_place (sidebar, PLACES_BUILT_IN, &iter,
 			       _("Desktop"), icon,
 			       mount_uri, NULL, NULL, NULL, 0);
 	g_object_unref (icon);
@@ -316,7 +332,7 @@ update_places (NautilusPlacesSidebar *sidebar)
 	
  	mount_uri = "file:///"; /* No need to strdup */
 	icon = g_themed_icon_new (NAUTILUS_ICON_FILESYSTEM);
-	last_iter = add_place (sidebar, PLACES_BUILT_IN,
+	last_iter = add_place (sidebar, PLACES_BUILT_IN, &iter,
 			       _("File System"), icon,
 			       mount_uri, NULL, NULL, NULL, 0);
 	g_object_unref (icon);
@@ -324,10 +340,25 @@ update_places (NautilusPlacesSidebar *sidebar)
 		gtk_tree_selection_select_iter (selection, &last_iter);
 	}
 
+	mount_uri = "trash:///"; /* No need to strdup */
+	icon = nautilus_trash_monitor_get_icon ();
+	last_iter = add_place (sidebar, PLACES_BUILT_IN, &iter,
+			       _("Trash"), icon, mount_uri,
+			       NULL, NULL, NULL, 0);
+	if (eel_strcmp (location, mount_uri) == 0) {
+		gtk_tree_selection_select_iter (selection, &last_iter);
+	}
+	g_object_unref (icon);
+	
+	/* second header "Network" stuff */
+	last_iter = add_place (sidebar, PLACES_HEADER, &iter,
+			     _("Network"), NULL, NULL, 
+			       NULL, NULL, NULL, 0);
+
  	mount_uri = "network:///"; /* No need to strdup */
 	icon = g_themed_icon_new (NAUTILUS_ICON_NETWORK);
-	last_iter = add_place (sidebar, PLACES_BUILT_IN,
-			       _("Network"), icon,
+	last_iter = add_place (sidebar, PLACES_BUILT_IN, &iter,
+			       _("Network Places"), icon,
 			       mount_uri, NULL, NULL, NULL, 0);
 	g_object_unref (icon);
 	if (strcmp (location, mount_uri) == 0) {
@@ -336,6 +367,40 @@ update_places (NautilusPlacesSidebar *sidebar)
 
 	volume_monitor = sidebar->volume_monitor;
 
+	/* add mounts that have no volume (/etc/mtab mounts, ftp, sftp,...)
+	 * Note: it's really ugly that we get /etc/mtab mounts in this list. */
+	mounts = g_volume_monitor_get_mounts (volume_monitor);
+	for (l = mounts; l != NULL; l = l->next) {
+		mount = l->data;
+		volume = g_mount_get_volume (mount);
+		if (volume != NULL) {
+		    	g_object_unref (volume);
+			g_object_unref (mount);
+			continue;
+		}
+		icon = g_mount_get_icon (mount);
+		root = g_mount_get_root (mount);
+		mount_uri = g_file_get_uri (root);
+		g_object_unref (root);
+		name = g_mount_get_name (mount);
+		last_iter = add_place (sidebar, PLACES_MOUNTED_VOLUME, &iter,
+				       name, icon, mount_uri,
+				       NULL, NULL, mount, 0);
+		if (eel_strcmp (location, mount_uri) == 0) {
+			gtk_tree_selection_select_iter (selection, &last_iter);
+		}
+		g_object_unref (mount);
+		g_object_unref (icon);
+		g_free (name);
+		g_free (mount_uri);
+	}
+	g_list_free (mounts);
+
+	/* third header "Drives" */
+	last_iter = add_place (sidebar, PLACES_HEADER, &iter,
+			     _("Drives"),  NULL, NULL, 
+			       NULL, NULL, NULL, 0);
+
 	/* first go through all connected drives */
 	drives = g_volume_monitor_get_connected_drives (volume_monitor);
 	for (l = drives; l != NULL; l = l->next) {
@@ -353,7 +418,7 @@ update_places (NautilusPlacesSidebar *sidebar)
 					mount_uri = g_file_get_uri (root);
 					g_object_unref (root);
 					name = g_mount_get_name (mount);
-					last_iter = add_place (sidebar, PLACES_MOUNTED_VOLUME,
+					last_iter = add_place (sidebar, PLACES_MOUNTED_VOLUME, &iter,
 							       name, icon, mount_uri,
 							       drive, volume, mount, 0);
 					if (eel_strcmp (location, mount_uri) == 0) {
@@ -374,7 +439,7 @@ update_places (NautilusPlacesSidebar *sidebar)
 					 */
 					icon = g_volume_get_icon (volume);
 					name = g_volume_get_name (volume);
-					last_iter = add_place (sidebar, PLACES_MOUNTED_VOLUME,
+					last_iter = add_place (sidebar, PLACES_MOUNTED_VOLUME, &iter,
 							       name, icon, NULL,
 							       drive, volume, NULL, 0);
 					g_object_unref (icon);
@@ -395,7 +460,7 @@ update_places (NautilusPlacesSidebar *sidebar)
 				 */
 				icon = g_drive_get_icon (drive);
 				name = g_drive_get_name (drive);
-				last_iter = add_place (sidebar, PLACES_BUILT_IN,
+				last_iter = add_place (sidebar, PLACES_BUILT_IN, &iter,
 						       name, icon, NULL,
 						       drive, NULL, NULL, 0);
 				g_object_unref (icon);
@@ -423,7 +488,7 @@ update_places (NautilusPlacesSidebar *sidebar)
 			mount_uri = g_file_get_uri (root);
 			g_object_unref (root);
 			name = g_mount_get_name (mount);
-			last_iter = add_place (sidebar, PLACES_MOUNTED_VOLUME,
+			last_iter = add_place (sidebar, PLACES_MOUNTED_VOLUME, &iter,
 					       name, icon, mount_uri,
 					       NULL, volume, mount, 0);
 			if (eel_strcmp (location, mount_uri) == 0) {
@@ -437,7 +502,7 @@ update_places (NautilusPlacesSidebar *sidebar)
 			/* see comment above in why we add an icon for an unmounted mountable volume */
 			icon = g_volume_get_icon (volume);
 			name = g_volume_get_name (volume);
-			last_iter = add_place (sidebar, PLACES_MOUNTED_VOLUME,
+			last_iter = add_place (sidebar, PLACES_MOUNTED_VOLUME, &iter,
 					       name, icon, NULL,
 					       NULL, volume, NULL, 0);
 			g_object_unref (icon);
@@ -447,52 +512,10 @@ update_places (NautilusPlacesSidebar *sidebar)
 	}
 	g_list_free (volumes);
 
-	/* add mounts that has no volume (/etc/mtab mounts, ftp, sftp,...) */
-	mounts = g_volume_monitor_get_mounts (volume_monitor);
-	for (l = mounts; l != NULL; l = l->next) {
-		mount = l->data;
-		volume = g_mount_get_volume (mount);
-		if (volume != NULL) {
-		    	g_object_unref (volume);
-			g_object_unref (mount);
-			continue;
-		}
-		icon = g_mount_get_icon (mount);
-		root = g_mount_get_root (mount);
-		mount_uri = g_file_get_uri (root);
-		g_object_unref (root);
-		name = g_mount_get_name (mount);
-		last_iter = add_place (sidebar, PLACES_MOUNTED_VOLUME,
-				       name, icon, mount_uri,
-				       NULL, NULL, mount, 0);
-		if (eel_strcmp (location, mount_uri) == 0) {
-			gtk_tree_selection_select_iter (selection, &last_iter);
-		}
-		g_object_unref (mount);
-		g_object_unref (icon);
-		g_free (name);
-		g_free (mount_uri);
-	}
-	g_list_free (mounts);
-
-	mount_uri = "trash:///"; /* No need to strdup */
-	icon = nautilus_trash_monitor_get_icon ();
-	last_iter = add_place (sidebar, PLACES_BUILT_IN,
-			       _("Trash"), icon, mount_uri,
+	/* last header "Network" stuff */
+	last_iter = add_place (sidebar, PLACES_HEADER, &iter,
+			     _("Bookmarks"),  NULL, NULL, 
 			       NULL, NULL, NULL, 0);
-	if (eel_strcmp (location, mount_uri) == 0) {
-		gtk_tree_selection_select_iter (selection, &last_iter);
-	}
-	g_object_unref (icon);
-
-	/* add separator */
-
-	gtk_list_store_append (sidebar->store, &iter);
-	gtk_list_store_set (sidebar->store, &iter,
-			    PLACES_SIDEBAR_COLUMN_ROW_TYPE, PLACES_SEPARATOR,
-			    -1);
-
-	/* add bookmarks */
 
 	bookmark_count = nautilus_bookmark_list_length (sidebar->bookmarks);
 	for (index = 0; index < bookmark_count; ++index) {
@@ -505,7 +528,7 @@ update_places (NautilusPlacesSidebar *sidebar)
 		name = nautilus_bookmark_get_name (bookmark);
 		icon = nautilus_bookmark_get_icon (bookmark);
 		mount_uri = nautilus_bookmark_get_uri (bookmark);
-		last_iter = add_place (sidebar, PLACES_BOOKMARK,
+		last_iter = add_place (sidebar, PLACES_BOOKMARK, &iter,
 				       name, icon, mount_uri,
 				       NULL, NULL, NULL, index);
 		if (eel_strcmp (location, mount_uri) == 0) {
@@ -518,22 +541,6 @@ update_places (NautilusPlacesSidebar *sidebar)
 	g_free (location);
 }
 
-static gboolean
-nautilus_shortcuts_row_separator_func (GtkTreeModel *model,
-				       GtkTreeIter  *iter,
-				       gpointer      data)
-{
-	PlaceType	 	type; 
-
-  	gtk_tree_model_get (model, iter, PLACES_SIDEBAR_COLUMN_ROW_TYPE, &type, -1);
-  
-  	if (type == PLACES_SEPARATOR) {
-   		return TRUE;
-	}
-
-  	return FALSE;
-}
-
 static void
 mount_added_callback (GVolumeMonitor *volume_monitor,
 		      GMount *mount,
@@ -737,8 +744,8 @@ get_bookmark_index (GtkTreeView *tree_view)
 	GtkTreeModel *model;
 	GtkTreePath *p;
 	GtkTreeIter iter;
-	PlaceType place_type;
 	int bookmark_index;
+	char *name;
 
 	model = gtk_tree_view_get_model (tree_view);
 
@@ -749,10 +756,10 @@ get_bookmark_index (GtkTreeView *tree_view)
 	while (p != NULL) {
 		gtk_tree_model_get_iter (model, &iter, p);
 		gtk_tree_model_get (model, &iter,
-				    PLACES_SIDEBAR_COLUMN_ROW_TYPE, &place_type,
+				    PLACES_SIDEBAR_COLUMN_NAME, &name,
 				    -1);
 
-		if (place_type == PLACES_SEPARATOR) {
+		if (g_strcmp0 (name, _("Bookmarks"))) {
 			bookmark_index = *gtk_tree_path_get_indices (p) + 1;
 			break;
 		}
@@ -1119,8 +1126,9 @@ drag_data_received_callback (GtkWidget *widget,
 	GtkTreeModel *model;
 	char *drop_uri;
 	GList *selection_list, *uris;
-	PlaceType type; 
 	gboolean success;
+	PlaceType type;
+	char *name;
 
 	tree_view = GTK_TREE_VIEW (widget);
 
@@ -1155,11 +1163,12 @@ drag_data_received_callback (GtkWidget *widget,
 		}
 
 		gtk_tree_model_get (model, &iter,
+				    PLACES_SIDEBAR_COLUMN_NAME, &name,
 				    PLACES_SIDEBAR_COLUMN_ROW_TYPE, &type,
 				    PLACES_SIDEBAR_COLUMN_INDEX, &position,
 				    -1);
 
-		if (type != PLACES_SEPARATOR && type != PLACES_BOOKMARK) {
+		if (!g_strcmp0 (name, _("Bookmarks")) && type != PLACES_BOOKMARK) {
 			goto out;
 		}
 
@@ -1225,6 +1234,8 @@ out:
 	free_drag_data (sidebar);
 	gtk_drag_finish (context, success, FALSE, time);
 
+	g_free (name);
+
 	gtk_tree_path_free (tree_path);
 }
 
@@ -1375,8 +1386,6 @@ bookmarks_check_popup_sensitivity (NautilusPlacesSidebar *sidebar)
 	show_empty_trash = (uri != NULL) &&
 			   (!strcmp (uri, "trash:///"));
 	
-	eel_gtk_widget_set_shown (sidebar->popup_menu_separator_item, 
-			show_mount || show_unmount || show_eject || show_format || show_empty_trash);
 	eel_gtk_widget_set_shown (sidebar->popup_menu_mount_item, show_mount);
 	eel_gtk_widget_set_shown (sidebar->popup_menu_unmount_item, show_unmount);
 	eel_gtk_widget_set_shown (sidebar->popup_menu_eject_item, show_eject);
@@ -2169,6 +2178,103 @@ trash_state_changed_cb (NautilusTrashMonitor *trash_monitor,
 }
 
 static void
+cell_set_background (NautilusPlacesSidebar *sidebar,
+		     GtkCellRenderer    *cell,
+		     gboolean            is_group,
+		     gboolean            is_active)
+{
+	GdkColor  color;
+	GtkStyle *style;
+
+	g_return_if_fail (sidebar != NULL);
+	g_return_if_fail (cell != NULL);
+
+	style = gtk_widget_get_style (GTK_WIDGET (sidebar));
+
+	if (!is_group) {
+		if (is_active) {
+			color = style->bg[GTK_STATE_SELECTED];
+
+			/* Here we take the current theme colour and add it to
+			 * the colour for white and average the two. This
+			 * gives a colour which is inline with the theme but
+			 * slightly whiter.
+			 */
+			color.red = (color.red + (style->white).red) / 2;
+			color.green = (color.green + (style->white).green) / 2;
+			color.blue = (color.blue + (style->white).blue) / 2;
+
+			g_object_set (cell,
+				      "cell-background-gdk", &color,
+				      NULL);
+		} else {
+			g_object_set (cell,
+				      "cell-background-gdk", NULL,
+				      NULL);
+		}
+	}
+}
+
+static void
+expander_cell_data_func (GtkTreeViewColumn *column,
+                         GtkCellRenderer *cell,
+                         GtkTreeModel *model,
+                         GtkTreeIter *iter,
+                         NautilusPlacesSidebar *sidebar)
+{
+	if (gtk_tree_model_iter_has_child (model, iter)) {
+		GtkTreePath *path;
+		gboolean     row_expanded;
+
+		path = gtk_tree_model_get_path (model, iter);
+		row_expanded = gtk_tree_view_row_expanded (GTK_TREE_VIEW (column->tree_view), path);
+		gtk_tree_path_free (path);
+
+		g_object_set (cell,
+			      "visible", TRUE,
+			      "expander-style", row_expanded ? GTK_EXPANDER_EXPANDED : GTK_EXPANDER_COLLAPSED,
+			      NULL);
+	} else {
+		g_object_set (cell, "visible", FALSE, NULL);
+	}
+
+	cell_set_background (sidebar, cell, TRUE, TRUE);
+}
+
+static void
+indent_level1_cell_data_func (GtkTreeViewColumn *tree_column,
+                              GtkCellRenderer *cell,
+                              GtkTreeModel *model,
+                              GtkTreeIter *iter,
+                              NautilusPlacesSidebar *sidebar)
+{
+	GtkTreePath *path;
+	int          depth;
+
+	path = gtk_tree_model_get_path (model, iter);
+	depth = gtk_tree_path_get_depth (path);
+	gtk_tree_path_free (path);
+	g_object_set (cell,
+		      "text", "    ",
+		      "visible", depth > 1,
+		      NULL);
+}
+
+static void
+icon_cell_data_func (GtkTreeViewColumn *tree_column,
+                              GtkCellRenderer *cell,
+                              GtkTreeModel *model,
+                              GtkTreeIter *iter,
+                              NautilusPlacesSidebar *sidebar)
+{
+	if (!gtk_tree_model_iter_has_child (model, iter)) {
+		g_object_set (cell, "visible", TRUE, NULL);
+	} else {
+		g_object_set (cell, "visible", FALSE, NULL);
+	}
+}
+
+static void
 nautilus_places_sidebar_init (NautilusPlacesSidebar *sidebar)
 {
 	GtkTreeView       *tree_view;
@@ -2190,13 +2296,28 @@ nautilus_places_sidebar_init (NautilusPlacesSidebar *sidebar)
 
 	col = GTK_TREE_VIEW_COLUMN (gtk_tree_view_column_new ());
 
+	cell = gtk_cell_renderer_text_new ();
+	sidebar->indent_renderer = cell;
+	gtk_tree_view_column_pack_start (col, cell, FALSE);
+	gtk_tree_view_column_set_cell_data_func (col, cell,
+						 (GtkTreeCellDataFunc) indent_level1_cell_data_func,
+						 sidebar,
+						 NULL);
+	g_object_set (cell,
+		      "xpad", 0,
+		      "visible", FALSE,
+		      NULL);		     
+
 	cell = gtk_cell_renderer_pixbuf_new ();
 	sidebar->icon_cell_renderer = cell;
 	gtk_tree_view_column_pack_start (col, cell, FALSE);
 	gtk_tree_view_column_set_attributes (col, cell,
 					     "pixbuf", PLACES_SIDEBAR_COLUMN_ICON,
 					     NULL);
-
+	gtk_tree_view_column_set_cell_data_func (col, cell,
+						 (GtkTreeCellDataFunc) icon_cell_data_func,
+						 sidebar,
+						 NULL);
 	
 	cell = gtk_cell_renderer_text_new ();
 	sidebar->eject_text_cell_renderer = cell;
@@ -2241,16 +2362,21 @@ nautilus_places_sidebar_init (NautilusPlacesSidebar *sidebar)
 	g_signal_connect (cell, "editing-canceled", 
 			  G_CALLBACK (bookmarks_editing_canceled), sidebar);
 
-	gtk_tree_view_set_row_separator_func (tree_view,
-					      nautilus_shortcuts_row_separator_func,
-					      NULL,
-					      NULL);
+	g_object_set (tree_view, "show-expanders", FALSE, NULL);
+
+	/* Expander */
+	cell = gossip_cell_renderer_expander_new ();
+	gtk_tree_view_column_pack_end (col, cell, FALSE);
+	gtk_tree_view_column_set_cell_data_func (col, cell,
+						 (GtkTreeCellDataFunc) expander_cell_data_func,
+						 sidebar,
+						 NULL);
 
 	/* this is required to align the eject buttons to the right */
 	gtk_tree_view_column_set_max_width (GTK_TREE_VIEW_COLUMN (col), NAUTILUS_ICON_SIZE_SMALLER);
 	gtk_tree_view_append_column (tree_view, col);
 
-	sidebar->store = gtk_list_store_new (PLACES_SIDEBAR_COLUMN_COUNT,
+	sidebar->store = gtk_tree_store_new (PLACES_SIDEBAR_COLUMN_COUNT,
 					     G_TYPE_INT, 
 					     G_TYPE_STRING,
 					     G_TYPE_DRIVE,
@@ -2270,6 +2396,7 @@ nautilus_places_sidebar_init (NautilusPlacesSidebar *sidebar)
 
 	gtk_tree_view_set_model (tree_view, sidebar->filter_model);
 	gtk_container_add (GTK_CONTAINER (sidebar), GTK_WIDGET (tree_view));
+	gtk_tree_view_expand_all (tree_view);
 	gtk_widget_show (GTK_WIDGET (tree_view));
 
 	gtk_widget_show (GTK_WIDGET (sidebar));
