diff --git a/plugins/daap/daap-ui.xml b/plugins/daap/daap-ui.xml
index 1ca46bd..84d6e84 100644
--- a/plugins/daap/daap-ui.xml
+++ b/plugins/daap/daap-ui.xml
@@ -8,6 +8,7 @@
   </menubar>
 
   <popup name="DAAPSourcePopup">
+    <menuitem name="DAAPSrcPopupRefresh" action="DaapSourceRefresh"/>
     <menuitem name="DAAPSrcPopupDisconnect" action="DaapSourceDisconnect"/>
   </popup>
 
diff --git a/plugins/daap/rb-daap-connection.c b/plugins/daap/rb-daap-connection.c
index 1f89dab..006c376 100644
--- a/plugins/daap/rb-daap-connection.c
+++ b/plugins/daap/rb-daap-connection.c
@@ -55,6 +55,8 @@
 
 #define ITUNES_7_SERVER "iTunes/7"
 
+#define RB_DAAP_REFRESH_TIMEOUT (5 * 60 * 1000)
+
 static void      rb_daap_connection_dispose      (GObject *obj);
 static void      rb_daap_connection_set_property (GObject *object,
 						  guint prop_id,
@@ -89,6 +91,7 @@ struct RBDAAPConnectionPrivate {
 
 	gboolean is_connected;
 	gboolean is_connecting;
+	gboolean is_refreshing;
 
 	SoupSession *session;
 	SoupURI *base_uri;
@@ -115,6 +118,7 @@ struct RBDAAPConnectionPrivate {
 
 	guint emit_progress_id;
 	guint do_something_id;
+	guint refresh_timeout_id;
 
 	gboolean result;
 	char *last_error_message;
@@ -134,6 +138,7 @@ enum {
 	AUTHENTICATE,
 	CONNECTING,
 	CONNECTED,
+	REFRESHED,
 	DISCONNECTED,
 	OPERATION_DONE,
 	LAST_SIGNAL
@@ -239,7 +244,16 @@ rb_daap_connection_class_init (RBDAAPConnectionClass *klass)
 					    NULL,
 					    NULL,
 					    g_cclosure_marshal_VOID__VOID,
-					       G_TYPE_NONE,
+					    G_TYPE_NONE,
+					    0);
+	signals [REFRESHED] = g_signal_new ("refreshed",
+					    G_TYPE_FROM_CLASS (object_class),
+					    G_SIGNAL_RUN_LAST,
+					    G_STRUCT_OFFSET (RBDAAPConnectionClass, refreshed),
+					    NULL,
+					    NULL,
+					    g_cclosure_marshal_VOID__VOID,
+					    G_TYPE_NONE,
 					    0);
 	signals [DISCONNECTED] = g_signal_new ("disconnected",
 					       G_TYPE_FROM_CLASS (object_class),
@@ -315,6 +329,20 @@ connection_disconnected (RBDAAPConnection *connection)
 }
 
 static void
+connection_refreshed (RBDAAPConnection *connection)
+{
+	rb_debug ("Emitting refreshed");
+
+	GDK_THREADS_ENTER ();
+	connection->priv->is_refreshing = FALSE;
+
+	g_signal_emit (connection,
+		       signals [REFRESHED],
+		       0);
+	GDK_THREADS_LEAVE ();
+}
+
+static void
 connection_operation_done (RBDAAPConnection *connection)
 {
 	rb_debug ("Emitting operation done");
@@ -788,6 +816,7 @@ handle_update (RBDAAPConnection *connection,
 {
 	RBDAAPConnectionPrivate *priv = connection->priv;
 	RBDAAPItem *item;
+	gint new_revision;
 
 	if (structure == NULL || SOUP_STATUS_IS_SUCCESSFUL (status) == FALSE) {
 		rb_daap_connection_state_done (connection, FALSE);
@@ -802,7 +831,17 @@ handle_update (RBDAAPConnection *connection,
 		return;
 	}
 
-	priv->revision_number = g_value_get_int (&(item->content));
+	new_revision = g_value_get_int (&(item->content));
+	if (new_revision != priv->revision_number) {
+		rb_debug ("revision number updated from %d to %d", priv->revision_number, new_revision);
+		priv->revision_number = new_revision;
+
+		if (priv->state == DAAP_REFRESH) {
+			priv->is_refreshing = TRUE;
+			priv->state = DAAP_GET_REVISION_NUMBER;	
+		}
+	}
+
 	rb_daap_connection_state_done (connection, TRUE);
 }
 
@@ -915,7 +954,19 @@ handle_song_listing (RBDAAPConnection *connection,
 		return;
 	}
 
-	priv->item_id_to_uri = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)rb_refstring_unref);
+	if (priv->item_id_to_uri == NULL) {
+		priv->item_id_to_uri = g_hash_table_new_full (g_direct_hash,
+							      g_direct_equal,
+							      NULL,
+							      (GDestroyNotify)rb_refstring_unref);
+	} else {
+		/* what probably needs to happen here is that we create a copy
+		 * of the item->uri map, removing any items that we see in the new
+		 * item list from the server.  once we're done, we'd then remove
+		 * any items left in the map, as they've been removed from the server.
+		 */
+	}
+	
 
 	rb_profile_start ("handling song listing");
 	priv->progress = 0.0f;
@@ -993,28 +1044,22 @@ handle_song_listing (RBDAAPConnection *connection,
 			}
 		}
 
-		/*if (connection->daap_version == 3.0) {*/
-			uri = g_strdup_printf ("%s/databases/%d/items/%d.%s?session-id=%u",
-					       priv->daap_base_uri,
-					       priv->database_id,
-					       item_id, format,
-					       priv->session_id);
-		/*} else {*/
-		/* uri should be
-		 * "/databases/%d/items/%d.%s?session-id=%u&revision-id=%d";
-		 * but its not going to work cause the other parts of the code
-		 * depend on the uri to have the ip address so that the
-		 * RBDAAPSource can be found to ++request_id
-		 * maybe just /dont/ support older itunes.  doesn't seem
-		 * unreasonable to me, honestly
-		 */
-		/*}*/
-		entry = rhythmdb_entry_new (priv->db, priv->db_type, uri);
+		uri = g_strdup_printf ("%s/databases/%d/items/%d.%s?session-id=%u",
+				       priv->daap_base_uri,
+				       priv->database_id,
+				       item_id, format,
+				       priv->session_id);
+
+		entry = rhythmdb_entry_lookup_by_location (priv->db, uri);
 		if (entry == NULL) {
-			rb_debug ("cannot create entry for daap track %s", uri);
-			continue;
+			entry = rhythmdb_entry_new (priv->db, priv->db_type, uri);
+			if (entry == NULL) {
+				rb_debug ("cannot create entry for daap track %s", uri);
+				continue;
+			}
+
+			g_hash_table_insert (priv->item_id_to_uri, GINT_TO_POINTER (item_id), rb_refstring_new (uri));
 		}
-		g_hash_table_insert (priv->item_id_to_uri, GINT_TO_POINTER (item_id), rb_refstring_new (uri));
 		g_free (uri);
 
 		/* year */
@@ -1096,14 +1141,31 @@ handle_song_listing (RBDAAPConnection *connection,
 }
 
 static int
-compare_playlists_by_name(gconstpointer a, gconstpointer b)
+compare_playlists_by_name (gconstpointer a, gconstpointer b)
 {
 	const RBDAAPPlaylist *playlist1 = a;
 	const RBDAAPPlaylist *playlist2 = b;
 
-	return strcmp(playlist1->name, playlist2->name);
+	return strcmp (playlist1->name, playlist2->name);
 }
 
+static int
+compare_playlist_to_id (gconstpointer a, gconstpointer b)
+{
+	const RBDAAPPlaylist *pa = a;
+
+	return (pa->id - GPOINTER_TO_INT (b));
+}
+
+static void
+rb_daap_diff_free (gpointer *a)
+{
+	RBDAAPPlaylistDiff *diff = (RBDAAPPlaylistDiff *)a;
+	rb_refstring_unref (diff->uri);
+	g_free (diff);
+}
+
+
 /* FIXME
  * what we really should do is only get a list of playlists and their ids
  * then when they are clicked on ('activate'd) by the user, get a list of
@@ -1161,12 +1223,19 @@ handle_playlists (RBDAAPConnection *connection,
 		}
 		name = g_value_dup_string (&(item->content));
 
-		playlist = g_new0 (RBDAAPPlaylist, 1);
-		playlist->id = id;
+		playlist = (RBDAAPPlaylist *)g_slist_find_custom (priv->playlists,
+								  GINT_TO_POINTER (id),
+								  (GCompareFunc) compare_playlist_to_id);
+		if (playlist == NULL) {
+			playlist = g_new0 (RBDAAPPlaylist, 1);
+			playlist->id = id;
+			rb_debug ("Got playlist %p: name %s, id %d", playlist, name, id);
+			priv->playlists = g_slist_prepend (priv->playlists, playlist);
+		} else {
+			rb_debug ("got existing playlist %p: name %s, id %d (current name %s)", playlist, name, id, playlist->name);
+			g_free (playlist->name);
+		}
 		playlist->name = name;
-		rb_debug ("Got playlist %p: name %s, id %d", playlist, playlist->name, playlist->id);
-
-		priv->playlists = g_slist_prepend (priv->playlists, playlist);
 	}
 
 	/* Sort the playlists into lexical order. Established DAAP clients already
@@ -1185,7 +1254,7 @@ handle_playlist_entries (RBDAAPConnection *connection,
 	RBDAAPPlaylist *playlist;
 	GNode *listing_node;
 	GNode *node;
-	gint i;
+	GList *l;
 	GList *playlist_uris = NULL;
 
 	if (structure == NULL || SOUP_STATUS_IS_SUCCESSFUL (status) == FALSE) {
@@ -1196,6 +1265,9 @@ handle_playlist_entries (RBDAAPConnection *connection,
 	playlist = (RBDAAPPlaylist *)g_slist_nth_data (priv->playlists, priv->reading_playlist);
 	g_assert (playlist);
 
+	rb_list_destroy_free (playlist->diffs, (GDestroyNotify) rb_daap_diff_free);
+	playlist->diffs = NULL;
+
 	listing_node = rb_daap_structure_find_node (structure, RB_DAAP_CC_MLCL);
 	if (listing_node == NULL) {
 		rb_debug ("Could not find dmap.listing item in /databases/%d/containers/%d/items",
@@ -1205,7 +1277,7 @@ handle_playlist_entries (RBDAAPConnection *connection,
 	}
 
 	rb_profile_start ("handling playlist entries");
-	for (i = 0, node = listing_node->children; node; node = node->next, i++) {
+	for (node = listing_node->children; node; node = node->next) {
 		RBRefString *item_uri;
 		gint playlist_item_id;
 		RBDAAPItem *item;
@@ -1226,10 +1298,30 @@ handle_playlist_entries (RBDAAPConnection *connection,
 		}
 
 		playlist_uris = g_list_prepend (playlist_uris, rb_refstring_ref (item_uri));
+
+		if (g_list_find (playlist->uris, item_uri) == NULL) {
+			RBDAAPPlaylistDiff *diff = g_new0 (RBDAAPPlaylistDiff, 1);
+			diff->uri = rb_refstring_ref (item_uri);
+			diff->difftype = DAAP_ADD_URI;
+			playlist->diffs = g_list_prepend (playlist->diffs, diff);
+		}
 	}
 	rb_profile_end ("handling playlist entries");
 
+	/* XXX O(n^2) .. probably not good enough */
+	for (l = playlist->uris; l != NULL; l = l->next) {
+		RBRefString *uri = l->data;
+		if (g_list_find (playlist_uris, uri) == NULL) {
+			RBDAAPPlaylistDiff *diff = g_new0 (RBDAAPPlaylistDiff, 1);
+			diff->uri = rb_refstring_ref (uri);
+			diff->difftype = DAAP_DEL_URI;
+			playlist->diffs = g_list_prepend (playlist->diffs, diff);
+		}
+	}
+
 	playlist->uris = g_list_reverse (playlist_uris);
+	playlist->diffs = g_list_reverse (playlist->diffs);
+
 	rb_daap_connection_state_done (connection, TRUE);
 }
 
@@ -1270,6 +1362,13 @@ rb_daap_connection_is_connected (RBDAAPConnection *connection)
 	return connection->priv->is_connected;
 }
 
+static gboolean
+rb_daap_connection_refresh_timeout_cb (RBDAAPConnection *connection)
+{
+	rb_daap_connection_refresh (connection);
+	return TRUE;
+}
+
 typedef struct {
 	RBDAAPConnection        *connection;
 	RBDAAPConnectionCallback callback;
@@ -1304,15 +1403,23 @@ connected_cb (RBDAAPConnection       *connection,
 	result = rb_daap_connection_is_connected (connection);
 
 	if (rdata->callback) {
-		rdata->callback (rdata->connection,
+		rdata->callback (connection,
 				 result,
-				 rdata->connection->priv->last_error_message,
+				 connection->priv->last_error_message,
 				 rdata->data);
 	}
 
 	if (rdata->destroy) {
 		rdata->destroy (rdata);
 	}
+
+	/* start refresh timer */
+	if (result == TRUE) {
+		connection->priv->refresh_timeout_id =
+			g_timeout_add (RB_DAAP_REFRESH_TIMEOUT,
+				       (GSourceFunc) rb_daap_connection_refresh_timeout_cb,
+				       connection);
+	}
 }
 
 void
@@ -1393,7 +1500,11 @@ rb_daap_connection_finish (RBDAAPConnection *connection)
 	connection->priv->state = DAAP_DONE;
 	connection->priv->progress = 1.0f;
 
-	connection_operation_done (connection);
+	if (connection->priv->is_refreshing) {
+		connection_refreshed (connection);
+	} else {
+		connection_operation_done (connection);
+	}
 }
 
 void
@@ -1442,6 +1553,18 @@ rb_daap_connection_disconnect (RBDAAPConnection        *connection,
 	}
 }
 
+void
+rb_daap_connection_refresh (RBDAAPConnection *connection)
+{
+	if (connection->priv->state != DAAP_DONE) {
+		rb_debug ("connection hasn't finished setup, can't refresh it yet");
+		return;
+	}
+
+	connection->priv->state = DAAP_REFRESH;
+	rb_daap_connection_do_something (connection);
+}
+
 static void
 rb_daap_connection_state_done (RBDAAPConnection *connection,
 			       gboolean          result)
@@ -1463,8 +1586,10 @@ rb_daap_connection_state_done (RBDAAPConnection *connection,
 			break;
 		case DAAP_GET_PLAYLIST_ENTRIES:
 			/* keep reading playlists until we've got them all */
-			if (++priv->reading_playlist >= g_slist_length (priv->playlists))
+			if (++priv->reading_playlist >= g_slist_length (priv->playlists)) {
+				priv->reading_playlist = 0;
 				priv->state = DAAP_DONE;
+			}
 			break;
 
 		case DAAP_LOGOUT:
@@ -1476,6 +1601,11 @@ rb_daap_connection_state_done (RBDAAPConnection *connection,
 			rb_debug ("This should never happen.");
 			break;
 
+		case DAAP_REFRESH:
+			rb_debug ("refresh complete");
+			priv->state = DAAP_DONE;
+			break;
+
 		default:
 			/* in most states, we just move on to the next */
 			if (priv->state > DAAP_DONE) {
@@ -1556,6 +1686,7 @@ rb_daap_connection_do_something (RBDAAPConnection *connection)
 
 		break;
 
+	case DAAP_REFRESH:
 	case DAAP_GET_REVISION_NUMBER:
 		rb_debug ("Getting DAAP server database revision number");
 		path = g_strdup_printf ("/update?session-id=%u&revision-number=1", priv->session_id);
@@ -1735,6 +1866,11 @@ rb_daap_connection_dispose (GObject *object)
 		priv->do_something_id = 0;
 	}
 
+	if (priv->refresh_timeout_id != 0) {
+		g_source_remove (priv->refresh_timeout_id);
+		priv->refresh_timeout_id = 0;
+	}
+
 	if (priv->name) {
 		g_free (priv->name);
 		priv->name = NULL;
@@ -1759,8 +1895,8 @@ rb_daap_connection_dispose (GObject *object)
 		for (l = priv->playlists; l; l = l->next) {
 			RBDAAPPlaylist *playlist = l->data;
 
-			g_list_foreach (playlist->uris, (GFunc)rb_refstring_unref, NULL);
-			g_list_free (playlist->uris);
+			rb_list_destroy_free (playlist->uris, (GDestroyNotify) rb_refstring_unref);
+			rb_list_destroy_free (playlist->diffs, (GDestroyNotify) rb_daap_diff_free);
 			g_free (playlist->name);
 			g_free (playlist);
 			l->data = NULL;
diff --git a/plugins/daap/rb-daap-connection.h b/plugins/daap/rb-daap-connection.h
index 11235ca..0e0dac0 100644
--- a/plugins/daap/rb-daap-connection.h
+++ b/plugins/daap/rb-daap-connection.h
@@ -37,10 +37,21 @@
 
 G_BEGIN_DECLS
 
+typedef enum {
+	DAAP_ADD_URI,
+	DAAP_DEL_URI
+} RBDAAPDiffType;
+
+typedef struct {
+	RBRefString *uri;
+	RBDAAPDiffType difftype;
+} RBDAAPPlaylistDiff;
+
 typedef struct {
 	char  *name;
 	int    id;
 	GList *uris;
+	GList *diffs;
 } RBDAAPPlaylist;
 
 #define RB_TYPE_DAAP_CONNECTION		(rb_daap_connection_get_type ())
@@ -62,7 +73,8 @@ typedef enum {
 	DAAP_GET_PLAYLISTS,
 	DAAP_GET_PLAYLIST_ENTRIES,
 	DAAP_LOGOUT,
-	DAAP_DONE
+	DAAP_DONE,
+	DAAP_REFRESH
 } RBDAAPConnectionState;
 
 typedef struct {
@@ -83,6 +95,7 @@ typedef struct {
 				   float		 progress);
 
 	void   (* operation_done) (RBDAAPConnection     *connection);
+	void   (* refreshed)      (RBDAAPConnection     *connection);
 
 } RBDAAPConnectionClass;
 
@@ -108,6 +121,7 @@ void               rb_daap_connection_connect         (RBDAAPConnection        *
 void               rb_daap_connection_disconnect      (RBDAAPConnection        *connection,
 						       RBDAAPConnectionCallback callback,
 						       gpointer                 user_data);
+void               rb_daap_connection_refresh         (RBDAAPConnection        *connection);
 
 char *             rb_daap_connection_get_headers     (RBDAAPConnection         *connection,
 						       const char               *uri,
diff --git a/plugins/daap/rb-daap-plugin.c b/plugins/daap/rb-daap-plugin.c
index 1fb8877..fd35482 100644
--- a/plugins/daap/rb-daap-plugin.c
+++ b/plugins/daap/rb-daap-plugin.c
@@ -100,6 +100,7 @@ static void impl_deactivate (RBPlugin *plugin, RBShell *shell);
 static GtkWidget* impl_create_configure_dialog (RBPlugin *plugin);
 static void rb_daap_plugin_cmd_disconnect (GtkAction *action, RBDaapPlugin *plugin);
 static void rb_daap_plugin_cmd_connect (GtkAction *action, RBDaapPlugin *plugin);
+static void rb_daap_plugin_cmd_refresh (GtkAction *actino, RBDaapPlugin *plugin);
 
 static void create_pixbufs (RBDaapPlugin *plugin);
 static void start_browsing (RBDaapPlugin *plugin);
@@ -116,6 +117,9 @@ static GtkActionEntry rb_daap_source_actions [] =
 	{ "DaapSourceDisconnect", GTK_STOCK_DISCONNECT, N_("_Disconnect"), NULL,
 	  N_("Disconnect from DAAP share"),
 	  G_CALLBACK (rb_daap_plugin_cmd_disconnect) },
+	{ "DaapSourceRefresh", GTK_STOCK_REFRESH, N_("_Refresh"), NULL,
+	  N_("Refresh DAAP share"),
+	  G_CALLBACK (rb_daap_plugin_cmd_refresh) },
 	{ "MusicNewDAAPShare", GTK_STOCK_CONNECT, N_("Connect to _DAAP share"), NULL,
 	  N_("Connect to a new DAAP share"),
 	  G_CALLBACK (rb_daap_plugin_cmd_connect) },
@@ -591,6 +595,23 @@ rb_daap_plugin_cmd_disconnect (GtkAction *action,
 	}
 }
 
+static void
+rb_daap_plugin_cmd_refresh (GtkAction *action,
+			    RBDaapPlugin *plugin)
+{
+	RBSource *source;
+
+	g_object_get (plugin->priv->shell,
+		      "selected-source", &source,
+		      NULL);
+
+	if (RB_IS_DAAP_SOURCE (source)) {
+		rb_daap_source_refresh (RB_DAAP_SOURCE (source));
+	} else {
+		g_warning ("got DAAP refresh action for non-DAAP source");
+	}
+}
+
 typedef struct {
 	RBDaapPlugin *plugin;
 	char *location;
diff --git a/plugins/daap/rb-daap-source.c b/plugins/daap/rb-daap-source.c
index 3e7cc77..d3a6aa4 100644
--- a/plugins/daap/rb-daap-source.c
+++ b/plugins/daap/rb-daap-source.c
@@ -439,6 +439,7 @@ connection_connecting_cb (RBDAAPConnection     *connection,
 		source->priv->connection_status = _("Retrieving songs from music share");
 		break;
 	case DAAP_LOGOUT:
+	case DAAP_REFRESH:
 	case DAAP_DONE:
 		source->priv->connection_status = NULL;
 		break;
@@ -501,9 +502,74 @@ release_connection (RBDAAPSource *daap_source)
 }
 
 static void
-_add_location_to_playlist (RBRefString *uri, RBStaticPlaylistSource *source)
+_apply_diff_to_playlist (RBDAAPPlaylistDiff *diff, RBStaticPlaylistSource *source)
 {
-	rb_static_playlist_source_add_location (source, rb_refstring_get (uri), -1);
+	switch (diff->difftype) {
+	case DAAP_ADD_URI:
+		rb_static_playlist_source_add_location (source, rb_refstring_get (diff->uri), -1);
+		break;
+
+	case DAAP_DEL_URI:
+		rb_static_playlist_source_remove_location (source, rb_refstring_get (diff->uri));
+		break;
+
+	default:
+		g_assert_not_reached ();
+		break;
+	}
+}
+
+static void
+update_playlists_from_connection (RBDAAPSource *source)
+{
+	RBShell *shell = NULL;
+	GSList *playlists;
+	GSList *l;
+	GSList *m;
+	RhythmDBEntryType entry_type;
+
+	g_object_get (source,
+		      "shell", &shell,
+		      "entry-type", &entry_type,
+		      NULL);
+	playlists = rb_daap_connection_get_playlists (source->priv->connection);
+	for (l = playlists; l != NULL; l = g_slist_next (l)) {
+		RBDAAPPlaylist *playlist = l->data;
+		RBSource *playlist_source = NULL;
+		char *sorting_name;
+
+		/* XXX this is wrong.  need to search by playlist ID, otherwise renamed playlists
+		 * will screw things up.
+		 */
+		for (m = source->priv->playlist_sources; m != NULL; m = m->next) {
+			RBSource *existing = (RBSource *)m->data;
+			char *name;
+
+			g_object_get (existing, "name", &name, NULL);
+			if (strcmp (name, playlist->name) == 0) {
+				playlist_source = existing;
+				g_free (name);
+				break;
+			}
+			g_free (name);
+		}
+
+		if (playlist_source == NULL) {
+			/* Construct a unique sorting name for this playlist, as <Share Name>_<Playlist> */
+			sorting_name = g_strjoin (NULL, source->priv->service_name, "_", playlist->name, NULL);
+
+			playlist_source = rb_static_playlist_source_new (shell, playlist->name, sorting_name, FALSE, entry_type);
+			g_free (sorting_name);
+
+			rb_shell_append_source (shell, playlist_source, RB_SOURCE (source));
+			source->priv->playlist_sources = g_slist_prepend (source->priv->playlist_sources, playlist_source);
+		}
+			
+		g_list_foreach (playlist->diffs, (GFunc)_apply_diff_to_playlist, playlist_source);
+	}
+
+	g_object_unref (shell);
+	g_boxed_free (RHYTHMDB_TYPE_ENTRY_TYPE, entry_type);
 }
 
 static void
@@ -513,10 +579,6 @@ rb_daap_source_connection_cb (RBDAAPConnection *connection,
 			      RBSource         *source)
 {
 	RBDAAPSource *daap_source = RB_DAAP_SOURCE (source);
-	RBShell *shell = NULL;
-	GSList *playlists;
-	GSList *l;
-	RhythmDBEntryType entry_type;
 
 	rb_debug ("Connection callback result: %s", result ? "success" : "failure");
 	daap_source->priv->tried_password = FALSE;
@@ -534,30 +596,20 @@ rb_daap_source_connection_cb (RBDAAPConnection *connection,
 		return;
 	}
 
-	g_object_get (daap_source,
-		      "shell", &shell,
-		      "entry-type", &entry_type,
-		      NULL);
-	playlists = rb_daap_connection_get_playlists (RB_DAAP_CONNECTION (daap_source->priv->connection));
-	for (l = playlists; l != NULL; l = g_slist_next (l)) {
-		RBDAAPPlaylist *playlist = l->data;
-		RBSource *playlist_source;
-		char *sorting_name;
-
-		/* Construct a unique sorting name for this playlist, as <Share Name>_<Playlist> */
-		sorting_name = g_strjoin (NULL, daap_source->priv->service_name, "_", playlist->name, NULL);
-
-		playlist_source = rb_static_playlist_source_new (shell, playlist->name, sorting_name, FALSE, entry_type);
-		g_free (sorting_name);
-
-		g_list_foreach (playlist->uris, (GFunc)_add_location_to_playlist, playlist_source);
+	update_playlists_from_connection (daap_source);
+}
 
-		rb_shell_append_source (shell, playlist_source, RB_SOURCE (daap_source));
-		daap_source->priv->playlist_sources = g_slist_prepend (daap_source->priv->playlist_sources, playlist_source);
-	}
+static void
+connection_refreshed_cb (RBDAAPConnection *connection,
+			 RBDAAPSource     *source)
+{
+	update_playlists_from_connection (source);
+}
 
-	g_object_unref (shell);
-	g_boxed_free (RHYTHMDB_TYPE_ENTRY_TYPE, entry_type);
+void
+rb_daap_source_refresh (RBDAAPSource *source)
+{
+	rb_daap_connection_refresh (source->priv->connection);
 }
 
 static void
@@ -603,6 +655,10 @@ rb_daap_source_activate (RBSource *source)
 			  "disconnected",
                           G_CALLBACK (connection_disconnected_cb),
 			  source);
+	g_signal_connect (daap_source->priv->connection,
+			  "refreshed",
+			  G_CALLBACK (connection_refreshed_cb),
+			  source);
 
 	rb_daap_connection_connect (RB_DAAP_CONNECTION (daap_source->priv->connection),
 				    (RBDAAPConnectionCallback) rb_daap_source_connection_cb,
diff --git a/plugins/daap/rb-daap-source.h b/plugins/daap/rb-daap-source.h
index 914bd82..7db689c 100644
--- a/plugins/daap/rb-daap-source.h
+++ b/plugins/daap/rb-daap-source.h
@@ -66,6 +66,7 @@ RBSource *	rb_daap_source_new 		(RBShell *shell,
 						 gboolean password_protected);
 
 void 		rb_daap_source_disconnect 	(RBDAAPSource *daap_source);
+void		rb_daap_source_refresh		(RBDAAPSource *daap_source);
 
 gchar *		rb_daap_source_get_headers 	(RBDAAPSource *source,
 					    	 const gchar *uri,
