Index: rhythmdb/rhythmdb-private.h
===================================================================
--- rhythmdb/rhythmdb-private.h	(revision 5796)
+++ rhythmdb/rhythmdb-private.h	(working copy)
@@ -88,6 +88,7 @@
 	/* metadata */
 	RBRefString *title;
 	RBRefString *artist;
+	RBRefString *composer;
 	RBRefString *album;
 	RBRefString *genre;
 	RBRefString *musicbrainz_trackid;
@@ -95,6 +96,7 @@
 	RBRefString *musicbrainz_albumid;
 	RBRefString *musicbrainz_albumartistid;
 	RBRefString *artist_sortname;
+	RBRefString *composer_sortname;
 	gulong tracknum;
 	gulong discnum;
 	gulong duration;
Index: rhythmdb/rhythmdb-property-model.c
===================================================================
--- rhythmdb/rhythmdb-property-model.c	(revision 5796)
+++ rhythmdb/rhythmdb-property-model.c	(working copy)
@@ -121,6 +121,7 @@
 	TARGET_ALBUMS,
 	TARGET_GENRE,
 	TARGET_ARTISTS,
+	TARGET_COMPOSERS,
 	TARGET_LOCATION,
 	TARGET_ENTRIES,
 	TARGET_URIS,
@@ -141,6 +142,11 @@
 	{ "application/x-rhythmbox-entry", 0, TARGET_ENTRIES },
 	{ "text/uri-list", 0, TARGET_URIS },
 };
+static const GtkTargetEntry targets_composer [] = {
+	{ "text/x-rhythmbox-composer", 0, TARGET_COMPOSERS },
+	{ "application/x-rhythmbox-entry", 0, TARGET_ENTRIES },
+	{ "text/uri-list", 0, TARGET_URIS },
+};
 static const GtkTargetEntry targets_location [] = {
 	{ "text/x-rhythmbox-location", 0, TARGET_LOCATION },
 	{ "application/x-rhythmbox-entry", 0, TARGET_ENTRIES },
@@ -149,6 +155,7 @@
 
 static GtkTargetList *rhythmdb_property_model_album_drag_target_list = NULL;
 static GtkTargetList *rhythmdb_property_model_artist_drag_target_list = NULL;
+static GtkTargetList *rhythmdb_property_model_composer_drag_target_list = NULL;
 static GtkTargetList *rhythmdb_property_model_genre_drag_target_list = NULL;
 static GtkTargetList *rhythmdb_property_model_location_drag_target_list = NULL;
 
@@ -212,6 +219,10 @@
 		rhythmdb_property_model_artist_drag_target_list =
 			gtk_target_list_new (targets_artist,
 					     G_N_ELEMENTS (targets_artist));
+   if (!rhythmdb_property_model_composer_drag_target_list)
+		rhythmdb_property_model_composer_drag_target_list =
+			gtk_target_list_new (targets_composer,
+					     G_N_ELEMENTS (targets_composer));
 	if (!rhythmdb_property_model_album_drag_target_list)
 		rhythmdb_property_model_album_drag_target_list =
 			gtk_target_list_new (targets_album,
@@ -410,6 +421,9 @@
 		case RHYTHMDB_PROP_ARTIST:
 			model->priv->sort_propid = RHYTHMDB_PROP_ARTIST;
 			break;
+		case RHYTHMDB_PROP_COMPOSER:
+			model->priv->sort_propid = RHYTHMDB_PROP_COMPOSER;
+			break;
 		case RHYTHMDB_PROP_ALBUM:
 			model->priv->sort_propid = RHYTHMDB_PROP_ALBUM;
 			break;
@@ -1060,6 +1074,9 @@
 	case RHYTHMDB_PROP_ARTIST:
 		drag_target_list = rhythmdb_property_model_artist_drag_target_list;
 		break;
+	case RHYTHMDB_PROP_COMPOSER:
+		drag_target_list = rhythmdb_property_model_composer_drag_target_list;
+		break;
 	case RHYTHMDB_PROP_LOCATION:
 		drag_target_list = rhythmdb_property_model_location_drag_target_list;
 		break;
@@ -1227,6 +1244,10 @@
 		targets = targets_artist;
 		n_elements = G_N_ELEMENTS (targets_artist);
 		break;
+	case RHYTHMDB_PROP_COMPOSER:
+		targets = targets_composer;
+		n_elements = G_N_ELEMENTS (targets_composer);
+		break;
 	case RHYTHMDB_PROP_LOCATION:
 		targets = targets_location;
 		n_elements = G_N_ELEMENTS (targets_location);
Index: rhythmdb/rhythmdb.c
===================================================================
--- rhythmdb/rhythmdb.c	(revision 5796)
+++ rhythmdb/rhythmdb.c	(working copy)
@@ -364,6 +364,9 @@
 	case RHYTHMDB_PROP_ARTIST:
 		*field = RB_METADATA_FIELD_ARTIST;
 		return TRUE;
+	case RHYTHMDB_PROP_COMPOSER:
+		*field = RB_METADATA_FIELD_COMPOSER;
+		return TRUE;
 	case RHYTHMDB_PROP_ALBUM:
 		*field = RB_METADATA_FIELD_ALBUM;
 		return TRUE;
@@ -1225,6 +1228,7 @@
 	ret->title = rb_refstring_ref (db->priv->empty_string);
 	ret->genre = rb_refstring_ref (db->priv->empty_string);
 	ret->artist = rb_refstring_ref (db->priv->empty_string);
+	ret->composer = rb_refstring_ref (db->priv->empty_string);
 	ret->album = rb_refstring_ref (db->priv->empty_string);
 	ret->musicbrainz_trackid = rb_refstring_ref (db->priv->empty_string);
 	ret->musicbrainz_artistid = rb_refstring_ref (db->priv->empty_string);
@@ -1405,6 +1409,7 @@
 	rb_refstring_unref (entry->title);
 	rb_refstring_unref (entry->genre);
 	rb_refstring_unref (entry->artist);
+	rb_refstring_unref (entry->composer);
 	rb_refstring_unref (entry->album);
 	rb_refstring_unref (entry->musicbrainz_trackid);
 	rb_refstring_unref (entry->musicbrainz_artistid);
@@ -1598,6 +1603,15 @@
 		g_value_unset (&val);
 	}
 
+	/* composer sortname */
+	if (rb_metadata_get (metadata,
+			     RB_METADATA_FIELD_COMPOSER_SORTNAME,
+			     &val)) {
+		rhythmdb_entry_set_internal (db, entry, TRUE,
+					     RHYTHMDB_PROP_COMPOSER_SORTNAME, &val);
+		g_value_unset (&val);
+	}
+
 	/* filesize */
 	g_value_init (&val, G_TYPE_UINT64);
 	g_value_set_uint64 (&val, vfsinfo->size);
@@ -1632,6 +1646,12 @@
 	set_metadata_string_default_unknown (db, metadata, entry,
 					     RB_METADATA_FIELD_ARTIST,
 					     RHYTHMDB_PROP_ARTIST);
+
+	/* composer */
+	set_metadata_string_default_unknown (db, metadata, entry,
+					     RB_METADATA_FIELD_COMPOSER,
+					     RHYTHMDB_PROP_COMPOSER);
+
 	/* album */
 	set_metadata_string_default_unknown (db, metadata, entry,
 					     RB_METADATA_FIELD_ALBUM,
@@ -2966,6 +2986,12 @@
 			}
 			entry->artist = rb_refstring_new (g_value_get_string (value));
 			break;
+		case RHYTHMDB_PROP_COMPOSER:
+			if (entry->composer != NULL) {
+				rb_refstring_unref (entry->composer);
+			}
+			entry->composer = rb_refstring_new (g_value_get_string (value));
+			break;
 		case RHYTHMDB_PROP_GENRE:
 			if (entry->genre != NULL) {
 				rb_refstring_unref (entry->genre);
@@ -3073,6 +3099,10 @@
 			rb_refstring_unref (entry->artist_sortname);
 			entry->artist_sortname = rb_refstring_new (g_value_get_string (value));
 			break;
+		case RHYTHMDB_PROP_COMPOSER_SORTNAME:
+			rb_refstring_unref (entry->composer_sortname);
+			entry->composer_sortname = rb_refstring_new (g_value_get_string (value));
+			break;
 		case RHYTHMDB_PROP_HIDDEN:
 			if (g_value_get_boolean (value)) {
 				entry->flags |= RHYTHMDB_ENTRY_HIDDEN;
@@ -3855,6 +3885,7 @@
 			ENUM_ENTRY (RHYTHMDB_PROP_TITLE, "Title (gchararray) [title]"),
 			ENUM_ENTRY (RHYTHMDB_PROP_GENRE, "Genre (gchararray) [genre]"),
 			ENUM_ENTRY (RHYTHMDB_PROP_ARTIST, "Artist (gchararray) [artist]"),
+			ENUM_ENTRY (RHYTHMDB_PROP_COMPOSER, "Composer (gchararray) [composer]"),
 			ENUM_ENTRY (RHYTHMDB_PROP_ALBUM, "Album (gchararray) [album]"),
 			ENUM_ENTRY (RHYTHMDB_PROP_TRACK_NUMBER, "Track Number (gulong) [track-number]"),
 			ENUM_ENTRY (RHYTHMDB_PROP_DISC_NUMBER, "Disc Number (gulong) [disc-number]"),
@@ -3884,11 +3915,13 @@
 			ENUM_ENTRY (RHYTHMDB_PROP_TITLE_SORT_KEY, "Title sort key (gchararray) [title-sort-key]"),
 			ENUM_ENTRY (RHYTHMDB_PROP_GENRE_SORT_KEY, "Genre sort key (gchararray) [genre-sort-key]"),
 			ENUM_ENTRY (RHYTHMDB_PROP_ARTIST_SORT_KEY, "Artist sort key (gchararray) [artist-sort-key]"),
+			ENUM_ENTRY (RHYTHMDB_PROP_COMPOSER_SORT_KEY, "Composer sort key (gchararray) [composer-sort-key]"),
 			ENUM_ENTRY (RHYTHMDB_PROP_ALBUM_SORT_KEY, "Album sort key (gchararray) [album-sort-key]"),
 
 			ENUM_ENTRY (RHYTHMDB_PROP_TITLE_FOLDED, "Title folded (gchararray) [title-folded]"),
 			ENUM_ENTRY (RHYTHMDB_PROP_GENRE_FOLDED, "Genre folded (gchararray) [genre-folded]"),
 			ENUM_ENTRY (RHYTHMDB_PROP_ARTIST_FOLDED, "Artist folded (gchararray) [artist-folded]"),
+			ENUM_ENTRY (RHYTHMDB_PROP_COMPOSER_FOLDED, "Composer folded (gchararray) [composer-folded]"),
 			ENUM_ENTRY (RHYTHMDB_PROP_ALBUM_FOLDED, "Album folded (gchararray) [album-folded]"),
 			ENUM_ENTRY (RHYTHMDB_PROP_LAST_PLAYED_STR, "Last Played (gchararray) [last-played-str]"),
 			ENUM_ENTRY (RHYTHMDB_PROP_PLAYBACK_ERROR, "Playback error string (gchararray) [playback-error]"),
@@ -4607,6 +4640,8 @@
 		return rb_refstring_get (entry->album);
 	case RHYTHMDB_PROP_ARTIST:
 		return rb_refstring_get (entry->artist);
+	case RHYTHMDB_PROP_COMPOSER:
+		return rb_refstring_get (entry->composer);
 	case RHYTHMDB_PROP_GENRE:
 		return rb_refstring_get (entry->genre);
 	case RHYTHMDB_PROP_MUSICBRAINZ_TRACKID:
@@ -4619,6 +4654,8 @@
 		return rb_refstring_get (entry->musicbrainz_albumartistid);
 	case RHYTHMDB_PROP_ARTIST_SORTNAME:
 		return rb_refstring_get (entry->artist_sortname);
+	case RHYTHMDB_PROP_COMPOSER_SORTNAME:
+		return rb_refstring_get (entry->composer_sortname);
 	case RHYTHMDB_PROP_MIMETYPE:
 		return rb_refstring_get (entry->mimetype);
 	case RHYTHMDB_PROP_TITLE_SORT_KEY:
@@ -4627,6 +4664,8 @@
 		return rb_refstring_get_sort_key (entry->album);
 	case RHYTHMDB_PROP_ARTIST_SORT_KEY:
 		return rb_refstring_get_sort_key (entry->artist);
+	case RHYTHMDB_PROP_COMPOSER_SORT_KEY:
+		return rb_refstring_get_sort_key (entry->composer);
 	case RHYTHMDB_PROP_GENRE_SORT_KEY:
 		return rb_refstring_get_sort_key (entry->genre);
 	case RHYTHMDB_PROP_TITLE_FOLDED:
@@ -4635,6 +4674,8 @@
 		return rb_refstring_get_folded (entry->album);
 	case RHYTHMDB_PROP_ARTIST_FOLDED:
 		return rb_refstring_get_folded (entry->artist);
+	case RHYTHMDB_PROP_COMPOSER_FOLDED:
+		return rb_refstring_get_folded (entry->composer);
 	case RHYTHMDB_PROP_GENRE_FOLDED:
 		return rb_refstring_get_folded (entry->genre);
 	case RHYTHMDB_PROP_LOCATION:
@@ -4710,6 +4751,8 @@
 		return rb_refstring_ref (entry->album);
 	case RHYTHMDB_PROP_ARTIST:
 		return rb_refstring_ref (entry->artist);
+	case RHYTHMDB_PROP_COMPOSER:
+		return rb_refstring_ref (entry->composer);
 	case RHYTHMDB_PROP_GENRE:
 		return rb_refstring_ref (entry->genre);
 	case RHYTHMDB_PROP_MUSICBRAINZ_TRACKID:
@@ -4722,6 +4765,8 @@
 		return rb_refstring_ref (entry->musicbrainz_albumartistid);
 	case RHYTHMDB_PROP_ARTIST_SORTNAME:
 		return rb_refstring_ref (entry->artist_sortname);
+	case RHYTHMDB_PROP_COMPOSER_SORTNAME:
+		return rb_refstring_ref (entry->composer_sortname);
 	case RHYTHMDB_PROP_MIMETYPE:
 		return rb_refstring_ref (entry->mimetype);
 	case RHYTHMDB_PROP_MOUNTPOINT:
Index: rhythmdb/rhythmdb-query-model.c
===================================================================
--- rhythmdb/rhythmdb-query-model.c	(revision 5796)
+++ rhythmdb/rhythmdb-query-model.c	(working copy)
@@ -2718,6 +2718,34 @@
 	if (ret != 0)
 		return ret;
 	else
+		return rhythmdb_query_model_composer_sort_func (a, b, data);
+}
+
+gint
+rhythmdb_query_model_composer_sort_func (RhythmDBEntry *a,
+				       RhythmDBEntry *b,
+				       gpointer data)
+{
+	const char *a_val;
+	const char *b_val;
+	gint ret;
+
+	a_val = rhythmdb_entry_get_string (a, RHYTHMDB_PROP_COMPOSER_SORT_KEY);
+	b_val = rhythmdb_entry_get_string (b, RHYTHMDB_PROP_COMPOSER_SORT_KEY);
+
+	if (a_val == NULL) {
+		if (b_val == NULL)
+			ret = 0;
+		else
+			ret = -1;
+	} else if (b_val == NULL)
+		ret = 1;
+	else
+		ret = strcmp (a_val, b_val);
+
+	if (ret != 0)
+		return ret;
+	else
 		return rhythmdb_query_model_album_sort_func (a, b, data);
 }
 
Index: rhythmdb/rhythmdb-query.c
===================================================================
--- rhythmdb/rhythmdb-query.c	(revision 5796)
+++ rhythmdb/rhythmdb-query.c	(working copy)
@@ -647,6 +647,7 @@
 			case RHYTHMDB_PROP_TITLE_FOLDED:
 			case RHYTHMDB_PROP_GENRE_FOLDED:
 			case RHYTHMDB_PROP_ARTIST_FOLDED:
+			case RHYTHMDB_PROP_COMPOSER_FOLDED:
 			case RHYTHMDB_PROP_ALBUM_FOLDED:
 			{
 				/* as we are matching against a folded property, the string needs to also be folded */
Index: rhythmdb/rhythmdb.h
===================================================================
--- rhythmdb/rhythmdb.h	(revision 5796)
+++ rhythmdb/rhythmdb.h	(working copy)
@@ -157,6 +157,7 @@
 	RHYTHMDB_PROP_TITLE,
 	RHYTHMDB_PROP_GENRE,
 	RHYTHMDB_PROP_ARTIST,
+	RHYTHMDB_PROP_COMPOSER,
 	RHYTHMDB_PROP_ALBUM,
 	RHYTHMDB_PROP_TRACK_NUMBER,
 	RHYTHMDB_PROP_DISC_NUMBER,
@@ -180,10 +181,12 @@
 	RHYTHMDB_PROP_TITLE_SORT_KEY,
 	RHYTHMDB_PROP_GENRE_SORT_KEY,
 	RHYTHMDB_PROP_ARTIST_SORT_KEY,
+	RHYTHMDB_PROP_COMPOSER_SORT_KEY,
 	RHYTHMDB_PROP_ALBUM_SORT_KEY,
 	RHYTHMDB_PROP_TITLE_FOLDED,
 	RHYTHMDB_PROP_GENRE_FOLDED,
 	RHYTHMDB_PROP_ARTIST_FOLDED,
+	RHYTHMDB_PROP_COMPOSER_FOLDED,
 	RHYTHMDB_PROP_ALBUM_FOLDED,
 	RHYTHMDB_PROP_LAST_PLAYED_STR,
 	RHYTHMDB_PROP_HIDDEN,
@@ -211,6 +214,7 @@
 	RHYTHMDB_PROP_MUSICBRAINZ_ALBUMID,
 	RHYTHMDB_PROP_MUSICBRAINZ_ALBUMARTISTID,
 	RHYTHMDB_PROP_ARTIST_SORTNAME,
+	RHYTHMDB_PROP_COMPOSER_SORTNAME,
 
 	RHYTHMDB_NUM_PROPERTIES
 } RhythmDBPropType;
@@ -224,7 +228,8 @@
 
 /* commonly used extra entry metadata */
 #define RHYTHMDB_PROP_STREAM_SONG_TITLE		"rb:stream-song-title"
-#define RHYTHMDB_PROP_STREAM_SONG_ARTIST	"rb:stream-song-artist"
+#define RHYTHMDB_PROP_STREAM_SONG_ARTIST  	"rb:stream-song-artist"
+#define RHYTHMDB_PROP_STREAM_SONG_COMPOSER	"rb:stream-song-composer"
 #define RHYTHMDB_PROP_STREAM_SONG_ALBUM		"rb:stream-song-album"
 #define RHYTHMDB_PROP_COVER_ART			"rb:coverArt"
 #define RHYTHMDB_PROP_COVER_ART_URI		"rb:coverArt-uri"
Index: rhythmdb/rhythmdb-query-model.h
===================================================================
--- rhythmdb/rhythmdb-query-model.h	(revision 5796)
+++ rhythmdb/rhythmdb-query-model.h	(working copy)
@@ -173,6 +173,10 @@
 								 RhythmDBEntry *b,
 								 gpointer data);
 
+gint 			rhythmdb_query_model_composer_sort_func	(RhythmDBEntry *a,
+								 RhythmDBEntry *b,
+								 gpointer data);
+
 gint 			rhythmdb_query_model_genre_sort_func	(RhythmDBEntry *a,
 								 RhythmDBEntry *b,
 								 gpointer data);
Index: sources/rb-playlist-source.c
===================================================================
--- sources/rb-playlist-source.c	(revision 5796)
+++ sources/rb-playlist-source.c	(working copy)
@@ -350,6 +350,7 @@
 	rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_TITLE, TRUE);
 	rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_GENRE, FALSE);
 	rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_ARTIST, FALSE);
+	rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_COMPOSER, FALSE);
 	rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_ALBUM, FALSE);
 	rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_YEAR, FALSE);
 	rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_DURATION, FALSE);
Index: sources/rb-auto-playlist-source.c
===================================================================
--- sources/rb-auto-playlist-source.c	(revision 5796)
+++ sources/rb-auto-playlist-source.c	(working copy)
@@ -108,7 +108,8 @@
 	{ "AutoPlaylistSearchAll", NULL, N_("All"), NULL, N_("Search all fields"), 0 },
 	{ "AutoPlaylistSearchArtists", NULL, N_("Artists"), NULL, N_("Search artists"), 1 },
 	{ "AutoPlaylistSearchAlbums", NULL, N_("Albums"), NULL, N_("Search albums"), 2 },
-	{ "AutoPlaylistSearchTitles", NULL, N_("Titles"), NULL, N_("Search titles"), 3 }
+	{ "AutoPlaylistSearchTitles", NULL, N_("Titles"), NULL, N_("Search titles"), 3 },
+	{ "AutoPlaylistSearchComposers", NULL, N_("Composers"), NULL, N_("Search composers"), 4 }
 };
 
 enum
@@ -543,6 +544,8 @@
 		return RHYTHMDB_PROP_ALBUM;
 	else if (smasher == gdk_atom_intern ("text/x-rhythmbox-artist", TRUE))
 		return RHYTHMDB_PROP_ARTIST;
+	else if (smasher == gdk_atom_intern ("text/x-rhythmbox-composer", TRUE))
+		return RHYTHMDB_PROP_COMPOSER;
 	else if (smasher == gdk_atom_intern ("text/x-rhythmbox-genre", TRUE))
 		return RHYTHMDB_PROP_GENRE;
 	else {
@@ -915,6 +918,7 @@
 	actions = g_list_prepend (actions, g_strdup ("AutoPlaylistSearchTitles"));
 	actions = g_list_prepend (actions, g_strdup ("AutoPlaylistSearchAlbums"));
 	actions = g_list_prepend (actions, g_strdup ("AutoPlaylistSearchArtists"));
+	actions = g_list_prepend (actions, g_strdup ("AutoPlaylistSearchComposers"));
 	actions = g_list_prepend (actions, g_strdup ("AutoPlaylistSearchAll"));
 
 	return actions;
@@ -934,6 +938,8 @@
 		prop = RHYTHMDB_PROP_SEARCH_MATCH;
 	} else if (strcmp (name, "AutoPlaylistSearchArtists") == 0) {
 		prop = RHYTHMDB_PROP_ARTIST_FOLDED;
+	} else if (strcmp (name, "AutoPlaylistSearchComposers") == 0) {
+		prop = RHYTHMDB_PROP_COMPOSER_FOLDED;
 	} else if (strcmp (name, "AutoPlaylistSearchAlbums") == 0) {
 		prop = RHYTHMDB_PROP_ALBUM_FOLDED;
 	} else if (strcmp (name, "AutoPlaylistSearchTitles") == 0) {
Index: sources/rb-missing-files-source.c
===================================================================
--- sources/rb-missing-files-source.c	(revision 5796)
+++ sources/rb-missing-files-source.c	(working copy)
@@ -192,6 +192,7 @@
 	rb_entry_view_append_column (source->priv->view, RB_ENTRY_VIEW_COL_TITLE, TRUE);
 /*	rb_entry_view_append_column (source->priv->view, RB_ENTRY_VIEW_COL_GENRE, FALSE); */
 	rb_entry_view_append_column (source->priv->view, RB_ENTRY_VIEW_COL_ARTIST, FALSE);
+	rb_entry_view_append_column (source->priv->view, RB_ENTRY_VIEW_COL_COMPOSER, FALSE);
 	rb_entry_view_append_column (source->priv->view, RB_ENTRY_VIEW_COL_ALBUM, FALSE);
 	rb_entry_view_append_column (source->priv->view, RB_ENTRY_VIEW_COL_LOCATION, TRUE);
 	rb_entry_view_append_column (source->priv->view, RB_ENTRY_VIEW_COL_LAST_SEEN, TRUE);
Index: sources/rb-static-playlist-source.c
===================================================================
--- sources/rb-static-playlist-source.c	(revision 5796)
+++ sources/rb-static-playlist-source.c	(working copy)
@@ -114,7 +114,8 @@
 	{ "StaticPlaylistSearchAll", NULL, N_("All"), NULL, N_("Search all fields"), 0 },
 	{ "StaticPlaylistSearchArtists", NULL, N_("Artists"), NULL, N_("Search artists"), 1 },
 	{ "StaticPlaylistSearchAlbums", NULL, N_("Albums"), NULL, N_("Search albums"), 2 },
-	{ "StaticPlaylistSearchTitles", NULL, N_("Titles"), NULL, N_("Search titles"), 3 }
+	{ "StaticPlaylistSearchTitles", NULL, N_("Titles"), NULL, N_("Search titles"), 3 },
+	{ "StaticPlaylistSearchComposers", NULL, N_("Composers"), NULL, N_("Search Composers"), 4 }
 };
 
 enum
@@ -886,6 +887,7 @@
 	actions = g_list_prepend (actions, g_strdup ("StaticPlaylistSearchTitles"));
 	actions = g_list_prepend (actions, g_strdup ("StaticPlaylistSearchAlbums"));
 	actions = g_list_prepend (actions, g_strdup ("StaticPlaylistSearchArtists"));
+	actions = g_list_prepend (actions, g_strdup ("StaticPlaylistSearchComposers"));
 	actions = g_list_prepend (actions, g_strdup ("StaticPlaylistSearchAll"));
 
 	return actions;
@@ -905,6 +907,8 @@
 		prop = RHYTHMDB_PROP_SEARCH_MATCH;
 	} else if (strcmp (name, "StaticPlaylistSearchArtists") == 0) {
 		prop = RHYTHMDB_PROP_ARTIST_FOLDED;
+	} else if (strcmp (name, "StaticPlaylistSearchComposers") == 0) {
+		prop = RHYTHMDB_PROP_COMPOSER_FOLDED;
 	} else if (strcmp (name, "StaticPlaylistSearchAlbums") == 0) {
 		prop = RHYTHMDB_PROP_ALBUM_FOLDED;
 	} else if (strcmp (name, "StaticPlaylistSearchTitles") == 0) {
Index: sources/rb-browser-source.c
===================================================================
--- sources/rb-browser-source.c	(revision 5796)
+++ sources/rb-browser-source.c	(working copy)
@@ -87,6 +87,8 @@
 						RBShell *shell);
 static void rb_browser_source_cmd_choose_artist (GtkAction *action,
 						 RBShell *shell);
+static void rb_browser_source_cmd_choose_composer (GtkAction *action,
+						 RBShell *shell);
 static void rb_browser_source_cmd_choose_album (GtkAction *action,
 						RBShell *shell);
 static void songs_view_sort_order_changed_cb (RBEntryView *view, RBBrowserSource *source);
@@ -107,6 +109,26 @@
 static RBEntryView *impl_get_entry_view (RBSource *source);
 static GList *impl_get_property_views (RBSource *source);
 static void impl_delete (RBSource *source);
+static void rb_browser_source_cmd_choose_album (GtkAction *action,
+						RBShell *shell);
+static void songs_view_sort_order_changed_cb (RBEntryView *view, RBBrowserSource *source);
+static void rb_browser_source_browser_changed_cb (RBLibraryBrowser *entry,
+						  GParamSpec *param,
+						  RBBrowserSource *source);
+
+static void rb_browser_source_state_prefs_sync (RBBrowserSource *source);
+static void rb_browser_source_state_pref_changed (GConfClient *client,
+							 guint cnxn_id,
+							 GConfEntry *entry,
+							 RBBrowserSource *source);
+
+static void paned_size_allocate_cb (GtkWidget *widget,
+				    GtkAllocation *allocation,
+		                    RBBrowserSource *source);
+/* source methods */
+static RBEntryView *impl_get_entry_view (RBSource *source);
+static GList *impl_get_property_views (RBSource *source);
+static void impl_delete (RBSource *source);
 static void impl_search (RBSource *source, const char *text);
 static void impl_reset_filters (RBSource *source);
 static void impl_song_properties (RBSource *source);
@@ -163,6 +185,9 @@
 	{ "BrowserSrcChooseArtist", NULL , N_("Browse This _Artist"), NULL,
 	  N_("Set the browser to view only this artist"),
 	  G_CALLBACK (rb_browser_source_cmd_choose_artist) },
+	{ "BrowserSrcChooseComposer", NULL , N_("Browse This _Composer"), NULL,
+	  N_("Set the browser to view only this composer"),
+	  G_CALLBACK (rb_browser_source_cmd_choose_composer) },
 	{ "BrowserSrcChooseAlbum", NULL, N_("Browse This A_lbum"), NULL,
 	  N_("Set the browser to view only this album"),
 	  G_CALLBACK (rb_browser_source_cmd_choose_album) }
@@ -173,7 +198,8 @@
 	{ "BrowserSourceSearchAll", NULL, N_("All"), NULL, N_("Search all fields"), 0 },
 	{ "BrowserSourceSearchArtists", NULL, N_("Artists"), NULL, N_("Search artists"), 1 },
 	{ "BrowserSourceSearchAlbums", NULL, N_("Albums"), NULL, N_("Search albums"), 2 },
-	{ "BrowserSourceSearchTitles", NULL, N_("Titles"), NULL, N_("Search titles"), 3 }
+	{ "BrowserSourceSearchTitles", NULL, N_("Titles"), NULL, N_("Search titles"), 3 },
+	{ "BrowserSourceSearchComposers", NULL, N_("Composers"), NULL, N_("Search composers"), 4 }
 };
 
 static const GtkTargetEntry songs_view_drag_types[] = {
@@ -339,6 +365,8 @@
 		prop = RHYTHMDB_PROP_SEARCH_MATCH;
 	} else if (strcmp (name, "BrowserSourceSearchArtists") == 0) {
 		prop = RHYTHMDB_PROP_ARTIST_FOLDED;
+	} else if (strcmp (name, "BrowserSourceSearchComposers") == 0) {
+		prop = RHYTHMDB_PROP_COMPOSER_FOLDED;
 	} else if (strcmp (name, "BrowserSourceSearchAlbums") == 0) {
 		prop = RHYTHMDB_PROP_ALBUM_FOLDED;
 	} else if (strcmp (name, "BrowserSourceSearchTitles") == 0) {
@@ -441,6 +469,7 @@
 	rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_TITLE, TRUE);
 	rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_GENRE, FALSE);
 	rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_ARTIST, FALSE);
+	rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_COMPOSER, FALSE);
 	rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_ALBUM, FALSE);
 	rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_YEAR, FALSE);
 	rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_DURATION, FALSE);
@@ -601,6 +630,26 @@
 }
 
 static void
+rb_browser_source_cmd_choose_composer (GtkAction *action,
+				     RBShell *shell)
+{
+	GList *props;
+	RBBrowserSource *source;
+	RBPropertyView *view;
+
+	rb_debug ("choosing composer");
+
+	g_object_get (shell, "selected-source", &source, NULL);
+	props = rb_source_gather_selected_properties (RB_SOURCE (source), RHYTHMDB_PROP_COMPOSER);
+	view = rb_library_browser_get_property_view (source->priv->browser, RHYTHMDB_PROP_COMPOSER);
+	if (view)
+		rb_property_view_set_selection (view, props);
+
+	rb_list_deep_free (props);
+	g_object_unref (source);
+}
+
+static void
 rb_browser_source_cmd_choose_album (GtkAction *action,
 				    RBShell *shell)
 {
@@ -795,6 +844,7 @@
 	actions = g_list_prepend (actions, g_strdup ("BrowserSourceSearchTitles"));
 	actions = g_list_prepend (actions, g_strdup ("BrowserSourceSearchAlbums"));
 	actions = g_list_prepend (actions, g_strdup ("BrowserSourceSearchArtists"));
+	actions = g_list_prepend (actions, g_strdup ("BrowserSourceSearchComposers"));
 	actions = g_list_prepend (actions, g_strdup ("BrowserSourceSearchAll"));
 
 	return actions;
Index: sources/rb-streaming-source.c
===================================================================
--- sources/rb-streaming-source.c	(revision 5796)
+++ sources/rb-streaming-source.c	(working copy)
@@ -75,6 +75,9 @@
 static GValue * streaming_artist_request_cb (RhythmDB *db,
 					     RhythmDBEntry *entry,
 					     RBStreamingSource *source);
+static GValue * streaming_composer_request_cb (RhythmDB *db,
+					     RhythmDBEntry *entry,
+					     RBStreamingSource *source);
 static GValue * streaming_album_request_cb (RhythmDB *db,
 					    RhythmDBEntry *entry,
 					    RBStreamingSource *source);
@@ -94,6 +97,7 @@
 	RhythmDBEntry *playing_stream;
 	char *streaming_title;
 	char *streaming_artist;
+	char *streaming_composer;
 	char *streaming_album;
 
 	gint emit_notify_id;
@@ -183,6 +187,11 @@
 				 source, 0);
 
 	g_signal_connect_object (G_OBJECT (source->priv->db),
+				 "entry-extra-metadata-request::" RHYTHMDB_PROP_STREAM_SONG_COMPOSER,
+				 G_CALLBACK (streaming_composer_request_cb),
+				 source, 0);
+
+	g_signal_connect_object (G_OBJECT (source->priv->db),
 				 "entry-extra-metadata-request::" RHYTHMDB_PROP_STREAM_SONG_ALBUM,
 				 G_CALLBACK (streaming_album_request_cb),
 				 source, 0);
@@ -289,6 +298,25 @@
 }
 
 static GValue *
+streaming_composer_request_cb (RhythmDB *db,
+			     RhythmDBEntry *entry,
+			     RBStreamingSource *source)
+{
+	GValue *value;
+
+	if (check_entry_type (source, entry) == FALSE ||
+	    entry != rb_shell_player_get_playing_entry (source->priv->player) ||
+	    source->priv->streaming_composer == NULL)
+		return NULL;
+
+	rb_debug ("returning streaming composer\"%s\" to extra metadata request", source->priv->streaming_composer);
+	value = g_new0 (GValue, 1);
+	g_value_init (value, G_TYPE_STRING);
+	g_value_set_string (value, source->priv->streaming_composer);
+	return value;
+}
+
+static GValue *
 streaming_album_request_cb (RhythmDB *db,
 			    RhythmDBEntry *entry,
 			    RBStreamingSource *source)
@@ -335,6 +363,15 @@
 		g_value_unset (&value);
 	}
 
+	if (source->priv->streaming_composer != NULL) {
+		GValue value = {0,};
+
+		g_value_init (&value, G_TYPE_STRING);
+		g_value_set_string (&value, source->priv->streaming_composer);
+		rb_string_value_map_set (data, RHYTHMDB_PROP_STREAM_SONG_COMPOSER, &value);
+		g_value_unset (&value);
+	}
+
 	if (source->priv->streaming_album != NULL) {
 		GValue value = {0,};
 
@@ -416,6 +453,17 @@
 }
 
 void
+rb_streaming_source_set_streaming_composer (RBStreamingSource *source,
+					  const char *composer)
+{
+	rb_debug ("streaming composer: \"%s\"", composer);
+	set_streaming_metadata (source,
+				&source->priv->streaming_composer,
+				RHYTHMDB_PROP_STREAM_SONG_COMPOSER,
+				composer);
+}
+
+void
 rb_streaming_source_set_streaming_album (RBStreamingSource *source,
 					 const char *album)
 {
@@ -439,9 +487,11 @@
 
 	g_free (source->priv->streaming_title);
 	g_free (source->priv->streaming_artist);
+	g_free (source->priv->streaming_composer);
 	g_free (source->priv->streaming_album);
 	source->priv->streaming_title = NULL;
 	source->priv->streaming_artist = NULL;
+	source->priv->streaming_composer  = NULL;
 	source->priv->streaming_album = NULL;
 
 	if (source->priv->playing_stream != NULL) {
Index: sources/rb-sourcelist-model.c
===================================================================
--- sources/rb-sourcelist-model.c	(revision 5796)
+++ sources/rb-sourcelist-model.c	(working copy)
@@ -135,7 +135,8 @@
 						     { "application/x-rhythmbox-source", 0, TARGET_SOURCE },
 						     { "application/x-rhythmbox-entry", 0, TARGET_ENTRIES },
 						     { "text/uri-list", 0, TARGET_URIS },
-						     { "application/x-delete-me", 0, TARGET_DELETE }};
+						     { "application/x-delete-me", 0, TARGET_DELETE },
+						     { "text/x-rhythmbox-composer", 0, TARGET_PROPERTY }};
 
 static GtkTargetList *sourcelist_drag_target_list = NULL;
 
@@ -357,6 +358,7 @@
         /* if artist, album or genre, only allow new playlists */
         if (selection_data->type == gdk_atom_intern ("text/x-rhythmbox-album", TRUE) ||
             selection_data->type == gdk_atom_intern ("text/x-rhythmbox-artist", TRUE) ||
+            selection_data->type == gdk_atom_intern ("text/x-rhythmbox-composer", TRUE) ||
             selection_data->type == gdk_atom_intern ("text/x-rhythmbox-genre", TRUE)) {
                 rb_debug ("text/x-rhythmbox-(album|artist|genre) drag data received");
                 g_signal_emit (G_OBJECT (model), rb_sourcelist_model_signals[DROP_RECEIVED],
@@ -442,9 +444,10 @@
 
 	if ((g_list_find (targets, gdk_atom_intern ("text/x-rhythmbox-artist", TRUE))
 	     || g_list_find (targets, gdk_atom_intern ("text/x-rhythmbox-album", TRUE))
+	     || g_list_find (targets, gdk_atom_intern ("text/x-rhythmbox-composer", TRUE))
 	     || g_list_find (targets, gdk_atom_intern ("text/x-rhythmbox-genre", TRUE)))
 	    && !g_list_find (targets, gdk_atom_intern ("application/x-rhythmbox-source", TRUE))) {
-		rb_debug ("genre, album, or artist type");
+		rb_debug ("genre, album, composer, or artist type");
 		*pos = GTK_TREE_VIEW_DROP_AFTER;
 		return TRUE;
 	}
Index: sources/rb-streaming-source.h
===================================================================
--- sources/rb-streaming-source.h	(revision 5796)
+++ sources/rb-streaming-source.h	(working copy)
@@ -63,6 +63,8 @@
 							 const char *title);
 void		rb_streaming_source_set_streaming_artist (RBStreamingSource *source,
 							  const char *artist);
+void		rb_streaming_source_set_streaming_composer (RBStreamingSource *source,
+							  const char *composer);
 void		rb_streaming_source_set_streaming_album (RBStreamingSource *source,
 							 const char *album);
 
Index: bindings/python/rhythmdb.defs
===================================================================
--- bindings/python/rhythmdb.defs	(revision 5796)
+++ bindings/python/rhythmdb.defs	(working copy)
@@ -111,6 +111,7 @@
     '("prop-title" "RHYTHMDB_PROP_TITLE")
     '("prop-genre" "RHYTHMDB_PROP_GENRE")
     '("prop-artist" "RHYTHMDB_PROP_ARTIST")
+    '("prop-composer" "RHYTHMDB_PROP_COMPOSER")
     '("prop-album" "RHYTHMDB_PROP_ALBUM")
     '("prop-track-number" "RHYTHMDB_PROP_TRACK_NUMBER")
     '("prop-disc-number" "RHYTHMDB_PROP_DISC_NUMBER")
@@ -134,10 +135,12 @@
     '("prop-title-sort-key" "RHYTHMDB_PROP_TITLE_SORT_KEY")
     '("prop-genre-sort-key" "RHYTHMDB_PROP_GENRE_SORT_KEY")
     '("prop-artist-sort-key" "RHYTHMDB_PROP_ARTIST_SORT_KEY")
+    '("prop-composer-sort-key" "RHYTHMDB_PROP_COMPOSER_SORT_KEY")
     '("prop-album-sort-key" "RHYTHMDB_PROP_ALBUM_SORT_KEY")
     '("prop-title-folded" "RHYTHMDB_PROP_TITLE_FOLDED")
     '("prop-genre-folded" "RHYTHMDB_PROP_GENRE_FOLDED")
     '("prop-artist-folded" "RHYTHMDB_PROP_ARTIST_FOLDED")
+    '("prop-composer-folded" "RHYTHMDB_PROP_COMPOSER_FOLDED")
     '("prop-album-folded" "RHYTHMDB_PROP_ALBUM_FOLDED")
     '("prop-last-played-str" "RHYTHMDB_PROP_LAST_PLAYED_STR")
     '("prop-hidden" "RHYTHMDB_PROP_HIDDEN")
@@ -1037,6 +1040,16 @@
   )
 )
 
+(define-function rhythmdb_query_model_composer_sort_func
+  (c-name "rhythmdb_query_model_composer_sort_func")
+  (return-type "gint")
+  (parameters
+    '("RhythmDBEntry*" "a")
+    '("RhythmDBEntry*" "b")
+    '("RhythmDBQueryModel*" "model")
+  )
+)
+
 (define-function rhythmdb_query_model_genre_sort_func
   (c-name "rhythmdb_query_model_genre_sort_func")
   (return-type "gint")
Index: bindings/python/rb.defs
===================================================================
--- bindings/python/rb.defs	(revision 5796)
+++ bindings/python/rb.defs	(working copy)
@@ -199,6 +199,7 @@
     '("track-number" "RB_ENTRY_VIEW_COL_TRACK_NUMBER")
     '("title" "RB_ENTRY_VIEW_COL_TITLE")
     '("artist" "RB_ENTRY_VIEW_COL_ARTIST")
+    '("composer" "RB_ENTRY_VIEW_COL_COMPOSER")
     '("album" "RB_ENTRY_VIEW_COL_ALBUM")
     '("genre" "RB_ENTRY_VIEW_COL_GENRE")
     '("duration" "RB_ENTRY_VIEW_COL_DURATION")
@@ -1898,6 +1899,15 @@
   )
 )
 
+(define-method set_streaming_composer_
+  (of-object "RBStreamingSource")
+  (c-name "rb_streaming_source_set_streaming_composer")
+  (return-type "none")
+  (parameters
+    '("const-char*" "composer")
+  )
+)
+
 (define-method set_streaming_album
   (of-object "RBStreamingSource")
   (c-name "rb_streaming_source_set_streaming_album")
Index: shell/rb-shell-preferences.c
===================================================================
--- shell/rb-shell-preferences.c	(revision 5796)
+++ shell/rb-shell-preferences.c	(working copy)
@@ -112,6 +112,7 @@
 
 	GtkWidget *config_widget;
 	GtkWidget *artist_check;
+	GtkWidget *composer_check;
 	GtkWidget *album_check;
 	GtkWidget *genre_check;
 	GtkWidget *duration_check;
@@ -218,6 +219,8 @@
 	/* Columns */
 	shell_preferences->priv->artist_check =
 		glade_xml_get_widget (xml, "artist_check");
+	shell_preferences->priv->composer_check =
+		glade_xml_get_widget (xml, "composer_check");
 	shell_preferences->priv->album_check =
 		glade_xml_get_widget (xml, "album_check");
 	shell_preferences->priv->genre_check =
@@ -462,6 +465,8 @@
 
 	if (butt == GTK_CHECK_BUTTON (shell_preferences->priv->artist_check))
 		colname = "RHYTHMDB_PROP_ARTIST";
+	else if (butt == GTK_CHECK_BUTTON (shell_preferences->priv->composer_check))
+		colname = "RHYTHMDB_PROP_COMPOSER";
 	else if (butt == GTK_CHECK_BUTTON (shell_preferences->priv->album_check))
 		colname = "RHYTHMDB_PROP_ALBUM";
 	else if (butt == GTK_CHECK_BUTTON (shell_preferences->priv->genre_check))
@@ -542,6 +547,9 @@
 			       				 shell_preferences->priv->artist_check,
 							 columns, "RHYTHMDB_PROP_ARTIST");
 		rb_shell_preferences_sync_column_button (shell_preferences,
+			       				 shell_preferences->priv->composer_check,
+							 columns, "RHYTHMDB_PROP_COMPOSER");
+		rb_shell_preferences_sync_column_button (shell_preferences,
 			       				 shell_preferences->priv->album_check,
 							 columns, "RHYTHMDB_PROP_ALBUM");
 		rb_shell_preferences_sync_column_button (shell_preferences,
Index: shell/rb-shell.c
===================================================================
--- shell/rb-shell.c	(revision 5796)
+++ shell/rb-shell.c	(working copy)
@@ -2957,6 +2957,7 @@
 	GValue *value;
 	const char *stream_title = NULL;
 	char *artist = NULL;
+	char *composer = NULL;
 	char *album = NULL;
 	char *title = NULL;
 	GString *secondary;
@@ -2989,6 +2990,24 @@
 	}
 	g_free (artist);
 
+	/* get artist, preferring streaming song details */
+	value = rhythmdb_entry_request_extra_metadata (shell->priv->db,
+						       entry,
+						       RHYTHMDB_PROP_STREAM_SONG_COMPOSER);
+	if (value != NULL) {
+		artist = markup_escape (g_value_get_string (value));
+		g_value_unset (value);
+		g_free (value);
+	} else {
+		composer = markup_escape (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_COMPOSER));
+	}
+
+	if (composer != NULL && composer[0] != '\0') {
+		/* Translators: by Artist */
+		g_string_append_printf (secondary, _("by <i>%s</i>"), composer);
+	}
+	g_free (composer);
+
 	/* get album, preferring streaming song details */
 	value = rhythmdb_entry_request_extra_metadata (shell->priv->db,
 						       entry,
Index: shell/rb-playlist-manager.c
===================================================================
--- shell/rb-playlist-manager.c	(revision 5796)
+++ shell/rb-playlist-manager.c	(working copy)
@@ -1009,17 +1009,22 @@
 		if (list != NULL) {
 			GList   *l;
 			char    *artist;
+			char    *composer;
 			char    *album;
 			gboolean mixed_artists;
+			gboolean mixed_composers;
 			gboolean mixed_albums;
 
 			artist = NULL;
+			composer = NULL;
 			album  = NULL;
 			mixed_artists = FALSE;
+			mixed_composers = FALSE;
 			mixed_albums  = FALSE;
 			for (l = list; l != NULL; l = g_list_next (l)) {
 				RhythmDBEntry *entry;
 				const char    *e_artist;
+				const char    *e_composer;
 				const char    *e_album;
 
 				entry = rhythmdb_entry_lookup_from_string (mgr->priv->db,
@@ -1030,6 +1035,7 @@
 				}
 
 				e_artist = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST);
+				e_composer = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_COMPOSER);
 				e_album = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM);
 
 				/* get value of first non-NULL artist */
@@ -1037,6 +1043,11 @@
 					artist = g_strdup (e_artist);
 				}
 
+				/* get value of first non-NULL composer */
+				if (e_composer != NULL && composer == NULL) {
+					composer = g_strdup (e_composer);
+				}
+
 				/* get value of first non-NULL album */
 				if (e_album != NULL && album == NULL) {
 					album = g_strdup (e_album);
@@ -1055,12 +1066,12 @@
 				}
 
 				/* if there is a mix of both then stop */
-				if (mixed_artists && mixed_albums) {
+				if (mixed_artists && mixed_albums && mixed_composers) {
 					break;
 				}
 			}
 
-			if (! mixed_artists && ! mixed_albums) {
+			if (! mixed_artists && ! mixed_albums &&) {
 				name = g_strdup_printf ("%s - %s", artist, album);
 			} else if (! mixed_artists) {
 				name = g_strdup_printf ("%s", artist);
@@ -1069,6 +1080,7 @@
 			}
 
 			g_free (artist);
+			g_free (composer);
 			g_free (album);
 			rb_list_deep_free (list);
 		}
Index: shell/rb-shell-player.c
===================================================================
--- shell/rb-shell-player.c	(revision 5796)
+++ shell/rb-shell-player.c	(working copy)
@@ -2858,6 +2858,7 @@
 		case RHYTHMDB_PROP_TITLE:
 		case RHYTHMDB_PROP_ARTIST:
 		case RHYTHMDB_PROP_ALBUM:
+		case RHYTHMDB_PROP_COMPOSER:
 			if (!synced) {
 				rb_shell_player_sync_with_source (player);
 				synced = TRUE;
Index: data/glade/general-prefs.glade
===================================================================
--- data/glade/general-prefs.glade	(revision 5796)
+++ data/glade/general-prefs.glade	(working copy)
@@ -558,10 +558,10 @@
 			      </child>
 
 			      <child>
-				<widget class="GtkCheckButton" id="last_played_check">
+				<widget class="GtkCheckButton" id="composer_check">
 				  <property name="visible">True</property>
 				  <property name="can_focus">True</property>
-				  <property name="label" translatable="yes">_Last played</property>
+				  <property name="label" translatable="yes">_Composer</property>
 				  <property name="use_underline">True</property>
 				  <property name="relief">GTK_RELIEF_NORMAL</property>
 				  <property name="focus_on_click">True</property>
@@ -575,6 +575,28 @@
 				  <property name="right_attach">1</property>
 				  <property name="top_attach">3</property>
 				  <property name="bottom_attach">4</property>
+				  <property name="y_options"></property>
+				</packing>
+			      </child>
+
+			      <child>
+				<widget class="GtkCheckButton" id="last_played_check">
+				  <property name="visible">True</property>
+				  <property name="can_focus">True</property>
+				  <property name="label" translatable="yes">_Last played</property>
+				  <property name="use_underline">True</property>
+				  <property name="relief">GTK_RELIEF_NORMAL</property>
+				  <property name="focus_on_click">True</property>
+				  <property name="active">False</property>
+				  <property name="inconsistent">False</property>
+				  <property name="draw_indicator">True</property>
+				  <signal name="toggled" handler="rb_shell_preferences_column_check_changed_cb" last_modification_time="Fri, 02 May 2003 04:26:32 GMT"/>
+				</widget>
+				<packing>
+				  <property name="left_attach">1</property>
+				  <property name="right_attach">2</property>
+				  <property name="top_attach">5</property>
+				  <property name="bottom_attach">6</property>
 				  <property name="x_options">fill</property>
 				  <property name="y_options"></property>
 				</packing>
Index: metadata/rb-metadata.h
===================================================================
--- metadata/rb-metadata.h	(revision 5796)
+++ metadata/rb-metadata.h	(working copy)
@@ -40,6 +40,7 @@
 {
 	RB_METADATA_FIELD_TITLE,                   /* string */
 	RB_METADATA_FIELD_ARTIST,                  /* string */
+	RB_METADATA_FIELD_COMPOSER,                /* string */
 	RB_METADATA_FIELD_ALBUM,                   /* string */
 	RB_METADATA_FIELD_DATE,                    /* ulong */
 	RB_METADATA_FIELD_GENRE,                   /* string */
@@ -68,7 +69,8 @@
 	RB_METADATA_FIELD_MUSICBRAINZ_ARTISTID,    /* string */
 	RB_METADATA_FIELD_MUSICBRAINZ_ALBUMID,     /* string */
 	RB_METADATA_FIELD_MUSICBRAINZ_ALBUMARTISTID,   /* string */
-	RB_METADATA_FIELD_ARTIST_SORTNAME,         /* string */
+	RB_METADATA_FIELD_ARTIST_SORTNAME,           /* string */
+	RB_METADATA_FIELD_COMPOSER_SORTNAME,         /* string */
 
 	RB_METADATA_FIELD_LAST			   /* nothing */
 } RBMetaDataField;
Index: metadata/rb-metadata-common.c
===================================================================
--- metadata/rb-metadata-common.c	(revision 5796)
+++ metadata/rb-metadata-common.c	(working copy)
@@ -45,6 +45,7 @@
 static struct RBMetaDataFieldInfo field_info[RB_METADATA_FIELD_LAST] = {
 	/* RB_METADATA_FIELD_TITLE */ 			{ G_TYPE_STRING, "title" },
 	/* RB_METADATA_FIELD_ARTIST */ 			{ G_TYPE_STRING, "artist" },
+	/* RB_METADATA_FIELD_COMPOSER */ 			{ G_TYPE_STRING, "composer" },
 	/* RB_METADATA_FIELD_ALBUM */ 			{ G_TYPE_STRING, "album" },
 	/* RB_METADATA_FIELD_DATE */ 			{ G_TYPE_ULONG, "date" },
 	/* RB_METADATA_FIELD_GENRE */ 			{ G_TYPE_STRING, "genre" },
Index: metadata/rb-metadata-gst.c
===================================================================
--- metadata/rb-metadata-gst.c	(revision 5796)
+++ metadata/rb-metadata-gst.c	(working copy)
@@ -421,6 +421,8 @@
 		return RB_METADATA_FIELD_TITLE;
 	else if (!strcmp (tag, GST_TAG_ARTIST))
 		return RB_METADATA_FIELD_ARTIST;
+	else if (!strcmp (tag, GST_TAG_COMPOSER))
+		return RB_METADATA_FIELD_COMPOSER;
 	else if (!strcmp (tag, GST_TAG_ALBUM))
 		return RB_METADATA_FIELD_ALBUM;
 	else if (!strcmp (tag, GST_TAG_DATE))
@@ -493,6 +495,8 @@
 		return GST_TAG_TITLE;
 	case RB_METADATA_FIELD_ARTIST:
 		return GST_TAG_ARTIST;
+	case RB_METADATA_FIELD_COMPOSER:
+		return GST_TAG_COMPOSER;
 	case RB_METADATA_FIELD_ALBUM:
 		return GST_TAG_ALBUM;
 	case RB_METADATA_FIELD_DATE:
Index: widgets/rb-entry-view.c
===================================================================
--- widgets/rb-entry-view.c	(revision 5796)
+++ widgets/rb-entry-view.c	(working copy)
@@ -1317,6 +1317,9 @@
 	case RB_ENTRY_VIEW_COL_ARTIST:
 		propid = RHYTHMDB_PROP_ARTIST;
 		break;
+	case RB_ENTRY_VIEW_COL_COMPOSER:
+		propid = RHYTHMDB_PROP_COMPOSER;
+		break;
 	case RB_ENTRY_VIEW_COL_ALBUM:
 		propid = RHYTHMDB_PROP_ALBUM;
 		break;
@@ -1430,6 +1433,16 @@
 		key = "Artist";
 		ellipsize = TRUE;
 		break;
+	case RB_ENTRY_VIEW_COL_COMPOSER:
+		propid = RHYTHMDB_PROP_COMPOSER;
+		cell_data->propid = propid;
+		cell_data_func = (GtkTreeCellDataFunc) rb_entry_view_string_cell_data_func;
+		sort_propid = RHYTHMDB_PROP_COMPOSER_SORT_KEY;
+		sort_func = (GCompareDataFunc) rhythmdb_query_model_composer_sort_func;
+		title = _("Composer");
+		key = "Composer";
+		ellipsize = TRUE;
+		break;
 	case RB_ENTRY_VIEW_COL_ALBUM:
 		propid = RHYTHMDB_PROP_ALBUM;
 		cell_data->propid = propid;
@@ -2559,6 +2572,7 @@
 			ENUM_ENTRY (RB_ENTRY_VIEW_COL_TRACK_NUMBER, "Track Number"),
 			ENUM_ENTRY (RB_ENTRY_VIEW_COL_TITLE, "Title"),
 			ENUM_ENTRY (RB_ENTRY_VIEW_COL_ARTIST, "Artist"),
+			ENUM_ENTRY (RB_ENTRY_VIEW_COL_COMPOSER, "Composer"),
 			ENUM_ENTRY (RB_ENTRY_VIEW_COL_ALBUM, "Album"),
 			ENUM_ENTRY (RB_ENTRY_VIEW_COL_GENRE, "Genre"),
 			ENUM_ENTRY (RB_ENTRY_VIEW_COL_DURATION, "Duration"),
Index: widgets/rb-entry-view.h
===================================================================
--- widgets/rb-entry-view.h	(revision 5796)
+++ widgets/rb-entry-view.h	(working copy)
@@ -52,6 +52,7 @@
 	RB_ENTRY_VIEW_COL_TRACK_NUMBER,
 	RB_ENTRY_VIEW_COL_TITLE,
 	RB_ENTRY_VIEW_COL_ARTIST,
+	RB_ENTRY_VIEW_COL_COMPOSER,
 	RB_ENTRY_VIEW_COL_ALBUM,
 	RB_ENTRY_VIEW_COL_GENRE,
 	RB_ENTRY_VIEW_COL_DURATION,
Index: widgets/rb-library-browser.c
===================================================================
--- widgets/rb-library-browser.c	(revision 5796)
+++ widgets/rb-library-browser.c	(working copy)
@@ -136,7 +136,8 @@
 static BrowserPropertyInfo browser_properties[] = {
 	{RHYTHMDB_PROP_GENRE, N_("Genre")},
 	{RHYTHMDB_PROP_ARTIST, N_("Artist")},
-	{RHYTHMDB_PROP_ALBUM, N_("Album")}
+	{RHYTHMDB_PROP_ALBUM, N_("Album")},
+	{RHYTHMDB_PROP_COMPOSER, N_("Composer")}
 };
 const int num_browser_properties = G_N_ELEMENTS (browser_properties);
 
@@ -399,6 +400,7 @@
 		if (views == 0 || views == 2)
 			properties = g_list_prepend (properties, (gpointer)RHYTHMDB_PROP_ALBUM);
 		properties = g_list_prepend (properties, (gpointer)RHYTHMDB_PROP_ARTIST);
+		properties = g_list_prepend (properties, (gpointer)RHYTHMDB_PROP_COMPOSER);
 		if (views == 1 || views == 2)
 			properties = g_list_prepend (properties, (gpointer)RHYTHMDB_PROP_GENRE);
 	}
Index: widgets/rb-query-creator-properties.c
===================================================================
--- widgets/rb-query-creator-properties.c	(revision 5796)
+++ widgets/rb-query-creator-properties.c	(working copy)
@@ -74,7 +74,8 @@
 {
 	{ N_("Title"), RHYTHMDB_PROP_TITLE, RHYTHMDB_PROP_TITLE_FOLDED, &string_property_type },
 	{ N_("Artist"), RHYTHMDB_PROP_ARTIST, RHYTHMDB_PROP_ARTIST_FOLDED, &string_property_type },
-	{ N_("Album"), RHYTHMDB_PROP_ALBUM, RHYTHMDB_PROP_ALBUM_FOLDED, &string_property_type },
+	{ N_("Composer"), RHYTHMDB_PROP_COMPOSER, RHYTHMDB_PROP_COMPOSER_FOLDED, &string_property_type },
+	{ N_("kAlbum"), RHYTHMDB_PROP_ALBUM, RHYTHMDB_PROP_ALBUM_FOLDED, &string_property_type },
 	{ N_("Genre"), RHYTHMDB_PROP_GENRE, RHYTHMDB_PROP_GENRE_FOLDED, &string_property_type },
 	{ N_("Year"), RHYTHMDB_PROP_DATE, RHYTHMDB_PROP_DATE, &year_property_type },
 	{ N_("Rating"), RHYTHMDB_PROP_RATING, RHYTHMDB_PROP_RATING, &rating_property_type },
@@ -100,6 +101,7 @@
 const RBQueryCreatorSortOption sort_options[] =
 {
 	{ N_("Artist"), "Artist", N_("_In reverse alphabetical order") },
+	{ N_("Composer"), "Composer", N_("_In reverse alphabetical order") },
 	{ N_("Album"), "Album", N_("_In reverse alphabetical order") },
 	{ N_("Genre"), "Genre", N_("_In reverse alphabetical order") },
 	{ N_("Title"), "Title", N_("_In reverse alphabetical order") },
Index: widgets/rb-property-view.c
===================================================================
--- widgets/rb-property-view.c	(revision 5796)
+++ widgets/rb-property-view.c	(working copy)
@@ -630,6 +630,9 @@
 		case RHYTHMDB_PROP_ARTIST:
 			fmt = ngettext ("%d artist (%d)", "All %d artists (%d)", nodes);
 			break;
+		case RHYTHMDB_PROP_COMPOSER:
+			fmt = ngettext ("%d composer (%d)", "All %d composers (%d)", nodes);
+			break;
 		case RHYTHMDB_PROP_ALBUM:
 			fmt = ngettext ("%d album (%d)", "All %d albums (%d)", nodes);
 			break;
Index: widgets/rb-song-info.c
===================================================================
--- widgets/rb-song-info.c	(revision 5796)
+++ widgets/rb-song-info.c	(working copy)
@@ -125,6 +125,7 @@
 
 	GtkWidget   *title;
 	GtkWidget   *artist;
+	GtkWidget   *composer;
 	GtkWidget   *album;
 	GtkWidget   *genre;
 	GtkWidget   *track_cur;
@@ -145,6 +146,7 @@
 
 	RhythmDBPropertyModel* albums;
 	RhythmDBPropertyModel* artists;
+	RhythmDBPropertyModel* composers;
 	RhythmDBPropertyModel* genres;
 };
 
@@ -491,6 +493,7 @@
 	glade_xml_signal_autoconnect (xml);
 
 	song_info->priv->artist = glade_xml_get_widget (xml, "song_info_artist");
+	song_info->priv->composer = glade_xml_get_widget (xml, "song_info_composer");
 	song_info->priv->album = glade_xml_get_widget (xml, "song_info_album");
 	song_info->priv->genre = glade_xml_get_widget (xml, "song_info_genre");
 	song_info->priv->year = glade_xml_get_widget (xml, "song_info_year");
@@ -500,10 +503,12 @@
 
 	rb_song_info_add_completion (GTK_ENTRY (song_info->priv->genre), song_info->priv->genres);
 	rb_song_info_add_completion (GTK_ENTRY (song_info->priv->artist), song_info->priv->artists);
+	rb_song_info_add_completion (GTK_ENTRY (song_info->priv->composer), song_info->priv->composers);
 	rb_song_info_add_completion (GTK_ENTRY (song_info->priv->album), song_info->priv->albums);
 
 	rb_glade_boldify_label (xml, "album_label");
 	rb_glade_boldify_label (xml, "artist_label");
+	rb_glade_boldify_label (xml, "composer_label");
 	rb_glade_boldify_label (xml, "genre_label");
 	rb_glade_boldify_label (xml, "year_label");
 	rb_glade_boldify_label (xml, "rating_label");
@@ -513,6 +518,10 @@
 				 "mnemonic-activate",
 				 G_CALLBACK (rb_song_info_mnemonic_cb),
 				 NULL, 0);
+	g_signal_connect_object (G_OBJECT (song_info->priv->composer),
+				 "mnemonic-activate",
+				 G_CALLBACK (rb_song_info_mnemonic_cb),
+				 NULL, 0);
 	g_signal_connect_object (G_OBJECT (song_info->priv->album),
 				 "mnemonic-activate",
 				 G_CALLBACK (rb_song_info_mnemonic_cb),
@@ -539,6 +548,7 @@
 			   song_info->priv->rating);
 
 	gtk_editable_set_editable (GTK_EDITABLE (song_info->priv->artist), editable);
+	gtk_editable_set_editable (GTK_EDITABLE (song_info->priv->composer), editable);
 	gtk_editable_set_editable (GTK_EDITABLE (song_info->priv->album), editable);
 	gtk_editable_set_editable (GTK_EDITABLE (song_info->priv->genre), editable);
 	gtk_editable_set_editable (GTK_EDITABLE (song_info->priv->year), editable);
@@ -587,6 +597,10 @@
 		g_object_unref (song_info->priv->artists);
 		song_info->priv->artists = NULL;
 	}
+	if (song_info->priv->composer != NULL) {
+		g_object_unref (song_info->priv->composers);
+		song_info->priv->composers = NULL;
+	}
 	if (song_info->priv->genres != NULL) {
 		g_object_unref (song_info->priv->genres);
 		song_info->priv->genres = NULL;
@@ -666,17 +680,22 @@
 		if (song_info->priv->artists) {
 			g_object_unref (song_info->priv->artists);
 		}
+		if (song_info->priv->composers) {
+			g_object_unref (song_info->priv->composers);
+		}
 		if (song_info->priv->genres) {
 			g_object_unref (song_info->priv->genres);
 		}
 
 		song_info->priv->albums  = rhythmdb_property_model_new (song_info->priv->db, RHYTHMDB_PROP_ALBUM);
 		song_info->priv->artists = rhythmdb_property_model_new (song_info->priv->db, RHYTHMDB_PROP_ARTIST);
+		song_info->priv->composers = rhythmdb_property_model_new (song_info->priv->db, RHYTHMDB_PROP_COMPOSER);
 		song_info->priv->genres  = rhythmdb_property_model_new (song_info->priv->db, RHYTHMDB_PROP_GENRE);
 
-		g_object_set (song_info->priv->albums,  "query-model", song_info->priv->query_model, NULL);
-		g_object_set (song_info->priv->artists, "query-model", song_info->priv->query_model, NULL);
-		g_object_set (song_info->priv->genres,  "query-model", song_info->priv->query_model, NULL);
+		g_object_set (song_info->priv->albums,    "query-model", song_info->priv->query_model, NULL);
+		g_object_set (song_info->priv->artists,   "query-model", song_info->priv->query_model, NULL);
+		g_object_set (song_info->priv->composers, "query-model", song_info->priv->query_model, NULL);
+		g_object_set (song_info->priv->genres,    "query-model", song_info->priv->query_model, NULL);
 
 		if(song_info->priv->album) {
 			GtkEntryCompletion *comp = gtk_entry_get_completion (GTK_ENTRY (song_info->priv->album));
@@ -688,6 +707,11 @@
 			gtk_entry_completion_set_model (comp, GTK_TREE_MODEL (song_info->priv->artist));
 		}
 
+		if(song_info->priv->composers) {
+			GtkEntryCompletion *comp = gtk_entry_get_completion (GTK_ENTRY (song_info->priv->composer));
+			gtk_entry_completion_set_model (comp, GTK_TREE_MODEL (song_info->priv->composer));
+		}
+
 		if(song_info->priv->genre) {
 			GtkEntryCompletion *comp = gtk_entry_get_completion (GTK_ENTRY (song_info->priv->genre));
 			gtk_entry_completion_set_model (comp, GTK_TREE_MODEL (song_info->priv->genre));
@@ -909,12 +933,14 @@
 rb_song_info_populate_dialog_multiple (RBSongInfo *song_info)
 {
 	gboolean mixed_artists = FALSE;
+	gboolean mixed_composers = FALSE;
 	gboolean mixed_albums = FALSE;
 	gboolean mixed_genres = FALSE;
 	gboolean mixed_years = FALSE;
 	gboolean mixed_disc_numbers = FALSE;
 	gboolean mixed_ratings = FALSE;
 	const char *artist = NULL;
+	const char *composer = NULL;
 	const char *album = NULL;
 	const char *genre = NULL;
 	int year = 0;
@@ -927,6 +953,7 @@
 	for (l = song_info->priv->selected_entries; l != NULL; l = g_list_next (l)) {
 		RhythmDBEntry *entry;
 		const char *entry_artist;
+		const char *entry_composer;
 		const char *entry_album;
 		const char *entry_genre;
 		int entry_year;
@@ -935,6 +962,7 @@
 
 		entry = (RhythmDBEntry*)l->data;
 		entry_artist = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST);
+		entry_composer = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_COMPOSER);
 		entry_album = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM);
 		entry_genre = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_GENRE);
 		entry_year = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_YEAR);
@@ -944,6 +972,8 @@
 		/* grab first valid values */
 		if (artist == NULL)
 			artist = entry_artist;
+		if (composer == NULL)
+			composer = entry_composer;
 		if (album == NULL)
 			album = entry_album;
 		if (genre == NULL)
@@ -958,6 +988,8 @@
 		/* locate mixed values */
 		if (artist != entry_artist)
 			mixed_artists = TRUE;
+		if (composer != entry_composer)
+			mixed_composers = TRUE;
 		if (album != entry_album)
 			mixed_albums = TRUE;
 		if (genre != entry_genre)
@@ -970,13 +1002,15 @@
 			mixed_ratings = TRUE;
 
 		/* don't continue search if everything is mixed */
-		if (mixed_artists && mixed_albums && mixed_genres &&
+		if (mixed_artists && mixed_composers && mixed_albums && mixed_genres &&
 		    mixed_years && mixed_disc_numbers && mixed_ratings)
 			break;
 	}
 
 	if (!mixed_artists && artist != NULL)
 		gtk_entry_set_text (GTK_ENTRY (song_info->priv->artist), artist);
+	if (!mixed_composers && composer != NULL)
+		gtk_entry_set_text (GTK_ENTRY (song_info->priv->composer), composer);
 	if (!mixed_albums && album != NULL)
 		gtk_entry_set_text (GTK_ENTRY (song_info->priv->album), album);
 	if (!mixed_genres && genre != NULL)
@@ -1010,6 +1044,8 @@
 
 	text = rhythmdb_entry_get_string (song_info->priv->current_entry, RHYTHMDB_PROP_ARTIST);
 	gtk_entry_set_text (GTK_ENTRY (song_info->priv->artist), text);
+	text = rhythmdb_entry_get_string (song_info->priv->current_entry, RHYTHMDB_PROP_COMPOSER);
+	gtk_entry_set_text (GTK_ENTRY (song_info->priv->composer), text);
 	text = rhythmdb_entry_get_string (song_info->priv->current_entry, RHYTHMDB_PROP_ALBUM);
 	gtk_entry_set_text (GTK_ENTRY (song_info->priv->album), text);
 	text = rhythmdb_entry_get_string (song_info->priv->current_entry, RHYTHMDB_PROP_GENRE);
@@ -1354,6 +1390,7 @@
 {
 	const char *genre = gtk_entry_get_text (GTK_ENTRY (dialog->priv->genre));
 	const char *artist = gtk_entry_get_text (GTK_ENTRY (dialog->priv->artist));
+	const char *composer = gtk_entry_get_text (GTK_ENTRY (dialog->priv->composer));
 	const char *album = gtk_entry_get_text (GTK_ENTRY (dialog->priv->album));
 	const char *year_str = gtk_entry_get_text (GTK_ENTRY (dialog->priv->year));
 	const char *discn_str = gtk_entry_get_text (GTK_ENTRY (dialog->priv->disc_cur));
@@ -1402,6 +1439,24 @@
 		g_value_unset (&val);
 	}
 
+	if (strlen (composer) > 0) {
+		g_value_init (&val, G_TYPE_STRING);
+		g_value_set_string (&val, composer);
+		for (tem = dialog->priv->selected_entries; tem; tem = tem->next) {
+			const char *entry_composer;
+
+			entry = (RhythmDBEntry *)tem->data;
+			entry_composer = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_COMPOSER);
+
+			if (strcmp (composer, entry_composer) == 0)
+				continue;
+			rhythmdb_entry_set (dialog->priv->db, entry,
+					    RHYTHMDB_PROP_COMPOSER, &val);
+			changed = TRUE;
+		}
+		g_value_unset (&val);
+	}
+
 	if (strlen (genre) > 0) {
 		g_value_init (&val, G_TYPE_STRING);
 		g_value_set_string (&val, genre);
@@ -1480,6 +1535,7 @@
 	const char *title;
 	const char *genre;
 	const char *artist;
+	const char *composer;
 	const char *album;
 	const char *tracknum_str;
 	const char *discnum_str;
@@ -1498,6 +1554,7 @@
 	title = gtk_entry_get_text (GTK_ENTRY (dialog->priv->title));
 	genre = gtk_entry_get_text (GTK_ENTRY (dialog->priv->genre));
 	artist = gtk_entry_get_text (GTK_ENTRY (dialog->priv->artist));
+	composer = gtk_entry_get_text (GTK_ENTRY (dialog->priv->composer));
 	album = gtk_entry_get_text (GTK_ENTRY (dialog->priv->album));
 	tracknum_str = gtk_entry_get_text (GTK_ENTRY (dialog->priv->track_cur));
 	discnum_str = gtk_entry_get_text (GTK_ENTRY (dialog->priv->disc_cur));
@@ -1597,7 +1654,20 @@
 		changed = TRUE;
 	}
 
+	entry_string = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_COMPOSER);
+	if (strcmp (composer, entry_string)) {
+		type = rhythmdb_get_property_type (dialog->priv->db,
+						   RHYTHMDB_PROP_COMPOSER);
+		g_value_init (&val, type);
+		g_value_set_string (&val, composer);
+		rhythmdb_entry_set (dialog->priv->db, entry,
+				    RHYTHMDB_PROP_COMPOSER, &val);
+		g_value_unset (&val);
+		changed = TRUE;
+	}
+
 	entry_string = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_GENRE);
+	entry_string = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_GENRE);
 	if (strcmp (genre, entry_string)) {
 		type = rhythmdb_get_property_type (dialog->priv->db,
 						   RHYTHMDB_PROP_GENRE);
Index: widgets/rb-header.c
===================================================================
--- widgets/rb-header.c	(revision 5796)
+++ widgets/rb-header.c	(working copy)
@@ -122,6 +122,7 @@
 #define TITLE_MARKUP(xTITLE) g_markup_printf_escaped ("<big><b>%s</b></big>", xTITLE)
 #define ALBUM_MARKUP(xALBUM) g_markup_printf_escaped (" %s <i>%s</i>", _("from"), xALBUM)
 #define ARTIST_MARKUP(xARTIST) g_markup_printf_escaped (" %s <i>%s</i>", _("by"), xARTIST)
+#define COMPOSER_MARKUP(xCOMPOSER) g_markup_printf_escaped (" %s <i>%s</i>", _("by"), xCOMPOSER)
 #define STREAM_MARKUP(xSTREAM) g_markup_printf_escaped (" (%s)", xSTREAM)
 
 G_DEFINE_TYPE (RBHeader, rb_header, GTK_TYPE_HBOX)
@@ -455,9 +456,11 @@
 		const char *title;
 		const char *album;
 		const char *artist;
+		const char *composer;
 		const char *stream_name = NULL;
 		char *streaming_title;
 		char *streaming_artist;
+		char *streaming_composer;
 		char *streaming_album;
 		GString *label_str;
 
@@ -466,6 +469,7 @@
 		title = rhythmdb_entry_get_string (header->priv->entry, RHYTHMDB_PROP_TITLE);
 		album = rhythmdb_entry_get_string (header->priv->entry, RHYTHMDB_PROP_ALBUM);
 		artist = rhythmdb_entry_get_string (header->priv->entry, RHYTHMDB_PROP_ARTIST);
+		composer = rhythmdb_entry_get_string (header->priv->entry, RHYTHMDB_PROP_COMPOSER);
 
 		get_extra_metadata (header->priv->db,
 				    header->priv->entry,
@@ -486,8 +490,18 @@
 			artist = streaming_artist;
 		}
 
+
 		get_extra_metadata (header->priv->db,
 				    header->priv->entry,
+				    RHYTHMDB_PROP_STREAM_SONG_COMPOSER,
+				    &streaming_composer);
+		if (streaming_composer) {
+			/* override artist from entry */
+			composer = streaming_composer;
+		}
+
+		get_extra_metadata (header->priv->db,
+				    header->priv->entry,
 				    RHYTHMDB_PROP_STREAM_SONG_ALBUM,
 				    &streaming_album);
 		if (streaming_album) {
@@ -507,6 +521,9 @@
 		if (artist != NULL && artist[0] != '\0')
 			append_and_free (label_str, ARTIST_MARKUP (artist));
 
+		if (composer != NULL && composer[0] != '\0')
+			append_and_free (label_str, COMPOSER_MARKUP (composer));
+
 		if (album != NULL && album[0] != '\0')
 			append_and_free (label_str, ALBUM_MARKUP (album));
 
@@ -522,6 +539,7 @@
 			rb_header_sync_time (header);
 
 		g_free (streaming_artist);
+		g_free (streaming_composer);
 		g_free (streaming_album);
 		g_free (streaming_title);
 	} else {
Index: backends/gstreamer/rb-encoder-gst.c
===================================================================
--- backends/gstreamer/rb-encoder-gst.c	(revision 5796)
+++ backends/gstreamer/rb-encoder-gst.c	(working copy)
@@ -402,6 +402,7 @@
 			  /* TODO: compute replay-gain */
 			  GST_TAG_TITLE, rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_TITLE),
 			  GST_TAG_ARTIST, rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST),
+			  GST_TAG_COMPOSER, rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_COMPOSER),
 			  GST_TAG_TRACK_NUMBER, rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_TRACK_NUMBER),
 			  GST_TAG_ALBUM_VOLUME_NUMBER, rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_DISC_NUMBER),
 			  GST_TAG_ALBUM, rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM),
