diff --git a/plugins/audiocd/Makefile.am b/plugins/audiocd/Makefile.am
index 679550a..dd9e6f3 100644
--- a/plugins/audiocd/Makefile.am
+++ b/plugins/audiocd/Makefile.am
@@ -52,7 +52,9 @@ libaudiocd_la_LIBADD += $(NULL)
 
 
 gladedir = $(plugindir)
-glade_DATA =	multiple-album.glade
+glade_DATA =									\
+	album-info.glade							\
+	multiple-album.glade
 
 uixmldir = $(plugindir)
 uixml_DATA = audiocd-ui.xml
diff --git a/plugins/audiocd/album-info.glade b/plugins/audiocd/album-info.glade
new file mode 100644
index 0000000..868adf6
--- /dev/null
+++ b/plugins/audiocd/album-info.glade
@@ -0,0 +1,62 @@
+<?xml version="1.0"?>
+<glade-interface>
+  <requires-version lib="gtk+" version="2.12"/>
+  <widget class="GtkWindow" id="window1">
+    <child>
+      <widget class="GtkTable" id="album_info_table">
+        <property name="visible">True</property>
+        <property name="border_width">12</property>
+        <property name="n_rows">2</property>
+        <property name="n_columns">2</property>
+        <property name="column_spacing">12</property>
+        <property name="row_spacing">6</property>
+        <child>
+          <widget class="GtkEntry" id="artist_sortname_entry">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="invisible_char">&#x25CF;</property>
+          </widget>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">1</property>
+            <property name="bottom_attach">2</property>
+          </packing>
+        </child>
+        <child>
+          <widget class="GtkEntry" id="artist_entry">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="invisible_char">&#x25CF;</property>
+          </widget>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+          </packing>
+        </child>
+        <child>
+          <widget class="GtkLabel" id="artist_sortname_label">
+            <property name="visible">True</property>
+            <property name="label" translatable="yes">Artist _sort name:</property>
+            <property name="use_underline">True</property>
+          </widget>
+          <packing>
+            <property name="top_attach">1</property>
+            <property name="bottom_attach">2</property>
+            <property name="x_options"></property>
+          </packing>
+        </child>
+        <child>
+          <widget class="GtkLabel" id="artist_label">
+            <property name="visible">True</property>
+            <property name="label" translatable="yes">_Artist:</property>
+            <property name="use_underline">True</property>
+          </widget>
+          <packing>
+            <property name="x_options"></property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+</glade-interface>
diff --git a/plugins/audiocd/rb-audiocd-source.c b/plugins/audiocd/rb-audiocd-source.c
index b0f214c..fd93d1c 100644
--- a/plugins/audiocd/rb-audiocd-source.c
+++ b/plugins/audiocd/rb-audiocd-source.c
@@ -57,6 +57,7 @@
 #endif
 
 static void rb_audiocd_source_dispose (GObject *object);
+static void rb_audiocd_source_finalize (GObject *object);
 static GObject *rb_audiocd_source_constructor (GType type, guint n_construct_properties,
 					        GObjectConstructParam *construct_properties);
 
@@ -68,10 +69,16 @@ static void impl_delete_thyself (RBSource *source);
 static GList* impl_get_ui_actions (RBSource *source);
 static gboolean impl_try_playlist (RBSource *source);
 
+static void impl_pack_paned (RBBrowserSource *source, GtkWidget *paned);
+
 static gpointer rb_audiocd_load_songs (RBAudioCdSource *source);
 static void rb_audiocd_load_metadata (RBAudioCdSource *source, RhythmDB *db);
 static void rb_audiocd_load_metadata_cancel (RBAudioCdSource *source);
 
+static void metadata_gather_cb (RhythmDB *db, RhythmDBEntry *entry, RBStringValueMap *data, RBAudioCdSource *source);
+static GValue *album_artist_metadata_request_cb (RhythmDB *db, RhythmDBEntry *entry, RBAudioCdSource *source);
+static GValue *album_artist_sortname_metadata_request_cb (RhythmDB *db, RhythmDBEntry *entry, RBAudioCdSource *source);
+
 typedef struct
 {
 	gchar *device_path;
@@ -81,6 +88,10 @@ typedef struct
 	GstElement *cdda;
 	GstElement *fakesink;
 
+	GtkWidget *box;
+	GtkWidget *artist_entry;
+	GtkWidget *artist_sortname_entry;
+
 #ifdef HAVE_SJ_METADATA_GETTER
 	SjMetadataGetter *metadata;
 #endif
@@ -92,14 +103,31 @@ RB_PLUGIN_DEFINE_TYPE (RBAudioCdSource, rb_audiocd_source, RB_TYPE_REMOVABLE_MED
 #ifdef HAVE_SJ_METADATA_GETTER
 static AlbumDetails* multiple_album_dialog (GList *albums, RBAudioCdSource *source);
 #endif
+
+static RhythmDB *
+get_db_for_source (RBAudioCdSource *source)
+{
+	RBShell *shell;
+	RhythmDB *db;
+
+	g_object_get (source, "shell", &shell, NULL);
+	g_object_get (shell, "db", &db, NULL);
+	g_object_unref (shell);
+
+	return db;
+}
+
+
 static void
 rb_audiocd_source_class_init (RBAudioCdSourceClass *klass)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 	RBSourceClass *source_class = RB_SOURCE_CLASS (klass);
+	RBBrowserSourceClass *browser_source_class = RB_BROWSER_SOURCE_CLASS (klass);
 
 	object_class->constructor = rb_audiocd_source_constructor;
 	object_class->dispose = rb_audiocd_source_dispose;
+	object_class->finalize = rb_audiocd_source_finalize;
 
 	/* don't bother showing the browser/search bits */
 	source_class->impl_can_browse = (RBSourceFeatureFunc) rb_false_function;
@@ -114,26 +142,37 @@ rb_audiocd_source_class_init (RBAudioCdSourceClass *klass)
 	source_class->impl_try_playlist = impl_try_playlist;
 	source_class->impl_want_uri = impl_want_uri;
 
+	/* add the browser below the album info section */
+	browser_source_class->impl_pack_paned = impl_pack_paned;
+
 	g_type_class_add_private (klass, sizeof (RBAudioCdSourcePrivate));
 }
 
 static void
 rb_audiocd_source_init (RBAudioCdSource *self)
 {
-
 }
 
 static void
-rb_audiocd_source_dispose (GObject *object)
+rb_audiocd_source_finalize (GObject *object)
 {
 	RBAudioCdSourcePrivate *priv = AUDIOCD_SOURCE_GET_PRIVATE (object);
-
+	
 	g_free (priv->device_path);
 
 	if (priv->tracks) {
 		g_list_free (priv->tracks);
 		priv->tracks = NULL;
 	}
+	
+	G_OBJECT_CLASS (rb_audiocd_source_parent_class)->finalize (object);
+}
+
+static void
+rb_audiocd_source_dispose (GObject *object)
+{
+	RBAudioCdSourcePrivate *priv = AUDIOCD_SOURCE_GET_PRIVATE (object);
+
 	if (priv->pipeline) {
 		gst_object_unref (GST_OBJECT (priv->pipeline));
 		priv->pipeline = NULL;
@@ -149,6 +188,9 @@ rb_audiocd_source_constructor (GType type,
 {
 	RBAudioCdSource *source;
 	RBEntryView *entry_view;
+	RhythmDB *db;
+	RBPlugin *plugin;
+	char *glade_file;
 
 	source = RB_AUDIOCD_SOURCE (G_OBJECT_CLASS (rb_audiocd_source_parent_class)->
 			constructor (type, n_construct_properties, construct_properties));
@@ -159,6 +201,44 @@ rb_audiocd_source_constructor (GType type,
 	entry_view = rb_source_get_entry_view (RB_SOURCE (source));
 	rb_entry_view_set_sorting_order (entry_view, "Track", GTK_SORT_ASCENDING);
 
+	/* handle extra metadata requests for album artist and album artist sortname */
+	db = get_db_for_source (source);
+	g_signal_connect_object (G_OBJECT (db), "entry-extra-metadata-request::" RHYTHMDB_PROP_ALBUM_ARTIST,
+				 G_CALLBACK (album_artist_metadata_request_cb), source, 0);
+	g_signal_connect_object (G_OBJECT (db), "entry-extra-metadata-request::" RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME,
+				 G_CALLBACK (album_artist_sortname_metadata_request_cb), source, 0);
+	g_signal_connect_object (G_OBJECT (db), "entry-extra-metadata-gather",
+				 G_CALLBACK (metadata_gather_cb), source, 0);
+	g_object_unref (db);
+
+	/* set up the album info widgets */
+	g_object_get (source, "plugin", &plugin, NULL);
+	glade_file = rb_plugin_find_file (plugin, "album-info.glade");
+	g_object_unref (plugin);
+
+	if (glade_file == NULL) {
+		g_warning ("couldn't find album-info.glade");
+	} else {
+		RBAudioCdSourcePrivate *priv;
+		GtkWidget *table;
+		GladeXML *xml;
+
+		priv = AUDIOCD_SOURCE_GET_PRIVATE (source);
+
+		xml = glade_xml_new (glade_file, NULL, NULL);
+		g_free (glade_file);
+
+		table = glade_xml_get_widget (xml, "album_info_table");
+		g_assert (table != NULL);
+
+		priv->artist_entry = glade_xml_get_widget (xml, "artist_entry");
+		priv->artist_sortname_entry = glade_xml_get_widget (xml, "artist_sortname_entry");
+
+		g_object_ref (table);
+		gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (table)), table);
+		gtk_box_pack_end (GTK_BOX (priv->box), table, FALSE, FALSE, 0);
+	}
+
 	g_object_ref (G_OBJECT (source));
 	g_thread_create ((GThreadFunc)rb_audiocd_load_songs, source, FALSE, NULL);
 
@@ -205,6 +285,17 @@ rb_audiocd_source_new (RBPlugin *plugin,
 }
 
 static void
+impl_pack_paned (RBBrowserSource *source, GtkWidget *paned)
+{
+	RBAudioCdSourcePrivate *priv = AUDIOCD_SOURCE_GET_PRIVATE (source);
+
+	priv->box = gtk_vbox_new (FALSE, 6);
+	gtk_widget_show_all (priv->box);
+	gtk_container_add (GTK_CONTAINER (source), priv->box);
+	gtk_box_pack_start (GTK_BOX (priv->box), paned, TRUE, TRUE, 0);
+}
+
+static void
 entry_set_string_prop (RhythmDB *db,
 		       RhythmDBEntry *entry,
 		       gboolean is_inserted,
@@ -358,19 +449,6 @@ rb_audiocd_scan_songs (RBAudioCdSource *source,
 	return ok;
 }
 
-static RhythmDB *
-get_db_for_source (RBAudioCdSource *source)
-{
-	RBShell *shell;
-	RhythmDB *db;
-
-  	g_object_get (source, "shell", &shell, NULL);
-  	g_object_get (shell, "db", &db, NULL);
-  	g_object_unref (shell);
-
-        return db;
-}
-
 #ifdef HAVE_SJ_METADATA_GETTER
 
 /*
@@ -538,7 +616,19 @@ metadata_cb (SjMetadataGetter *metadata,
 		return;
 	}
 
+	if (album->artist != NULL) {
+		gtk_entry_set_text (GTK_ENTRY (priv->artist_entry), album->artist);
+	}
+	if (album->artist_sortname != NULL) {
+		gtk_entry_set_text (GTK_ENTRY (priv->artist_sortname_entry), album->artist_sortname);
+	}
+
 	g_object_set (G_OBJECT (source), "name", album->title, NULL);
+	rb_debug ("musicbrainz_albumid: %s", album->album_id);
+	rb_debug ("musicbrainz_albumartistid: %s", album->artist_id);
+	rb_debug ("album artist: %s", album->artist);
+	rb_debug ("disc number: %d", album->disc_number);
+	rb_debug ("genre: %s", album->genre);
 
 	while (album->tracks && cd_track) {
 		TrackDetails *track = (TrackDetails*)album->tracks->data;
@@ -547,12 +637,9 @@ metadata_cb (SjMetadataGetter *metadata,
 
 		rb_debug ("storing metadata for %s - %s - %s", track->artist, album->title, track->title);
 
-		rb_debug ("genre: %s", album->genre);
 		rb_debug ("musicbrainz_trackid: %s", track->track_id);
 		rb_debug ("musicbrainz_artistid: %s", track->artist_id);
-		rb_debug ("musicbrainz_albumid: %s", album->album_id);
-		rb_debug ("musicbrainz_albumartistid: %s", album->artist_id);
-		rb_debug ("album sortname: %s", album->artist_sortname);
+		rb_debug ("artist sortname: %s", track->artist_sortname);
 
 		/* record track info in entry*/
 		entry_set_string_prop (db, entry, TRUE, RHYTHMDB_PROP_TITLE, track->title);
@@ -563,13 +650,20 @@ metadata_cb (SjMetadataGetter *metadata,
 		entry_set_string_prop (db, entry, TRUE, RHYTHMDB_PROP_MUSICBRAINZ_ARTISTID, track->artist_id);
 		entry_set_string_prop (db, entry, TRUE, RHYTHMDB_PROP_MUSICBRAINZ_ALBUMID, album->album_id);
 		entry_set_string_prop (db, entry, TRUE, RHYTHMDB_PROP_MUSICBRAINZ_ALBUMARTISTID, album->artist_id);
-		entry_set_string_prop (db, entry, TRUE, RHYTHMDB_PROP_ARTIST_SORTNAME, album->artist_sortname);
+		entry_set_string_prop (db, entry, TRUE, RHYTHMDB_PROP_ARTIST_SORTNAME, track->artist_sortname);
 
 		g_value_init (&value, G_TYPE_ULONG);
 		g_value_set_ulong (&value, track->duration);
 		rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_DURATION, &value);
 		g_value_unset (&value);
 
+		if (album->disc_number != 0) {
+			g_value_init (&value, G_TYPE_ULONG);
+			g_value_set_ulong (&value, album->disc_number);
+			rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_DISC_NUMBER, &value);
+			g_value_unset (&value);
+		}
+
 		/*album->release_date (could potentially have multiple values)*/
 		/* in current sj-structures.h, however, it does not */
 
@@ -808,3 +902,71 @@ impl_try_playlist (RBSource *source)
 {
 	return TRUE;
 }
+
+
+
+static void
+metadata_gather_cb (RhythmDB *db, RhythmDBEntry *entry, RBStringValueMap *data, RBAudioCdSource *source)
+{
+	RBAudioCdSourcePrivate *priv = AUDIOCD_SOURCE_GET_PRIVATE (source);
+	GValue value = {0,};
+
+	if (_rb_source_check_entry_type (RB_SOURCE (source), entry) == FALSE) {
+		return;
+	}
+
+	if (gtk_entry_get_text_length (GTK_ENTRY (priv->artist_entry)) > 0) {
+		g_value_init (&value, G_TYPE_STRING);
+		g_value_set_string (&value, gtk_entry_get_text (GTK_ENTRY (priv->artist_entry)));
+		rb_string_value_map_set (data, RHYTHMDB_PROP_ALBUM_ARTIST, &value);
+		g_value_unset (&value);
+	}
+	
+	if (gtk_entry_get_text_length (GTK_ENTRY (priv->artist_sortname_entry)) > 0) {
+		g_value_init (&value, G_TYPE_STRING);
+		g_value_set_string (&value, gtk_entry_get_text (GTK_ENTRY (priv->artist_sortname_entry)));
+		rb_string_value_map_set (data, RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME, &value);
+		g_value_unset (&value);
+	}
+}
+
+
+static GValue *
+album_artist_metadata_request_cb (RhythmDB *db, RhythmDBEntry *entry, RBAudioCdSource *source)
+{
+	RBAudioCdSourcePrivate *priv = AUDIOCD_SOURCE_GET_PRIVATE (source);
+	GValue *value = NULL;
+
+	if (_rb_source_check_entry_type (RB_SOURCE (source), entry) == FALSE) {
+		return NULL;
+	}
+
+	if (gtk_entry_get_text_length (GTK_ENTRY (priv->artist_entry)) > 0) {
+		value = g_new0 (GValue, 1);
+		g_value_init (value, G_TYPE_STRING);
+		g_value_set_string (value, gtk_entry_get_text (GTK_ENTRY (priv->artist_entry)));
+	}
+
+	return value;
+}
+
+static GValue *
+album_artist_sortname_metadata_request_cb (RhythmDB *db, RhythmDBEntry *entry, RBAudioCdSource *source)
+{
+	RBAudioCdSourcePrivate *priv = AUDIOCD_SOURCE_GET_PRIVATE (source);
+	GValue *value = NULL;
+
+	if (_rb_source_check_entry_type (RB_SOURCE (source), entry) == FALSE) {
+		return NULL;
+	}
+
+	if (gtk_entry_get_text_length (GTK_ENTRY (priv->artist_sortname_entry)) > 0) {
+		value = g_new0 (GValue, 1);
+		g_value_init (value, G_TYPE_STRING);
+		g_value_set_string (value, gtk_entry_get_text (GTK_ENTRY (priv->artist_sortname_entry)));
+	}
+
+	return value;
+}
+
+
diff --git a/rhythmdb/rhythmdb.h b/rhythmdb/rhythmdb.h
index 01d3ec6..4ec24de 100644
--- a/rhythmdb/rhythmdb.h
+++ b/rhythmdb/rhythmdb.h
@@ -229,6 +229,8 @@ enum {
 #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"
+#define RHYTHMDB_PROP_ALBUM_ARTIST		"rb:album-artist"
+#define RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME	"rb:album-artist-sortname"
 
 GType rhythmdb_query_type_get_type (void);
 GType rhythmdb_prop_type_get_type (void);
diff --git a/sources/rb-library-source.c b/sources/rb-library-source.c
index 75b697b..08258a6 100644
--- a/sources/rb-library-source.c
+++ b/sources/rb-library-source.c
@@ -829,17 +829,30 @@ sanitize_pattern (const char *pat)
  * %tS -- track artist sortname (lowercase)
  */
 static char *
-filepath_parse_pattern (const char *pattern,
+filepath_parse_pattern (RhythmDB *db,
+			const char *pattern,
 			RhythmDBEntry *entry)
 {
 	/* p is the pattern iterator, i is a general purpose iterator */
 	const char *p;
 	char *temp;
 	GString *s;
+	GValue *value;
+	RBRefString *albumartist;
 
 	if (pattern == NULL || pattern[0] == 0)
 		return g_strdup (" ");
 
+	/* request album artist (this is sort of temporary) */
+	value = rhythmdb_entry_request_extra_metadata (db, entry, RHYTHMDB_PROP_ALBUM_ARTIST);
+	if (value != NULL) {
+		albumartist = rb_refstring_new (g_value_get_string (value));
+		g_value_unset (value);
+		g_free (value);
+	} else {
+		albumartist = rhythmdb_entry_get_refstring (entry, RHYTHMDB_PROP_ARTIST);
+	}
+
 	s = g_string_new (NULL);
 
 	p = pattern;
@@ -874,10 +887,10 @@ filepath_parse_pattern (const char *pattern,
 				string = sanitize_path (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM_FOLDED));
 				break;
 			case 'a':
-				string = sanitize_path (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST));
+				string = sanitize_path (rb_refstring_get (albumartist));
 				break;
 			case 'A':
-				string = sanitize_path (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST_FOLDED));
+				string = sanitize_path (rb_refstring_get_folded (albumartist));
 				break;
 			case 's':
 				string = sanitize_path (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST_SORTNAME));
@@ -945,6 +958,7 @@ filepath_parse_pattern (const char *pattern,
 
 	temp = s->str;
 	g_string_free (s, FALSE);
+	rb_refstring_unref (albumartist);
 	return temp;
 }
 
@@ -982,8 +996,8 @@ layout_example_label_update (RBLibrarySource *source)
 	sample_entry = rhythmdb_entry_example_new (source->priv->db, entry_type, NULL);
 	g_boxed_free (RHYTHMDB_TYPE_ENTRY_TYPE, entry_type);
 
-	file_value = filepath_parse_pattern (file_pattern, sample_entry);
-	path_value = filepath_parse_pattern (path_pattern, sample_entry);
+	file_value = filepath_parse_pattern (source->priv->db, file_pattern, sample_entry);
+	path_value = filepath_parse_pattern (source->priv->db, path_pattern, sample_entry);
 	rhythmdb_entry_unref (sample_entry);
 
 	example = g_build_filename (G_DIR_SEPARATOR_S, path_value, file_value, NULL);
@@ -1108,7 +1122,7 @@ build_filename (RBLibrarySource *source, RhythmDBEntry *entry)
 	g_free (layout_filename);
 	layout_filename = tmp;
 
-	realpath = filepath_parse_pattern (layout_path, entry);
+	realpath = filepath_parse_pattern (source->priv->db, layout_path, entry);
 
 	library_location = g_file_new_for_uri ((const char *)list->data);
 	dir = g_file_resolve_relative_path (library_location, realpath);
@@ -1142,7 +1156,7 @@ build_filename (RBLibrarySource *source, RhythmDBEntry *entry)
 			*tmp = '\0';
 	}
 
-	realfile = filepath_parse_pattern (layout_filename, entry);
+	realfile = filepath_parse_pattern (source->priv->db, layout_filename, entry);
 	if (extension) {
 		filename = g_strdup_printf ("%s.%s", realfile, extension);
 		g_free (realfile);
diff --git a/sources/rb-source.c b/sources/rb-source.c
index 2b5109f..f77dd01 100644
--- a/sources/rb-source.c
+++ b/sources/rb-source.c
@@ -325,7 +325,7 @@ rb_source_class_init (RBSourceClass *klass)
 						 	      "RBPlugin",
 							      "RBPlugin instance for the plugin that created the source",
 							      RB_TYPE_PLUGIN,
-							      G_PARAM_READWRITE));
+							      G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 	/**
 	 * RBSource:base-query-model:
 	 *
