diff --git a/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue.csproj b/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue.csproj
index 6dd6773..502aacd 100644
--- a/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue.csproj
+++ b/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue.csproj
@@ -48,6 +48,7 @@
     <Compile Include="Banshee.PlayQueue\PlayQueueActions.cs" />
     <Compile Include="Banshee.PlayQueue\IPlayQueue.cs" />
     <Compile Include="Banshee.PlayQueue\ConfigurationPane.cs" />
+    <Compile Include="Banshee.PlayQueue\QueueableSourceComboBox.cs" />
   </ItemGroup>
   <ItemGroup>
     <EmbeddedResource Include="Resources\ActiveSourceUI.xml">
diff --git a/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/ConfigurationPane.cs b/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/ConfigurationPane.cs
index 79a0344..f381cf7 100644
--- a/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/ConfigurationPane.cs
+++ b/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/ConfigurationPane.cs
@@ -28,36 +28,153 @@
 
 using Gtk;
 using Mono.Unix;
+using System;
+
+using Banshee.Sources;
 
 namespace Banshee.PlayQueue
 {
     public class ConfigurationPane : Hyena.Widgets.RoundedFrame
     {
-        private HBox main_box;
+        public event EventHandler<PopulateChangedEventArgs> PopulateChanged;
+        public event EventHandler<SourceChangedEventArgs> SourceChanged;
+        public event EventHandler<SongsNumberChangedEventArgs> PlayedSongsNumberChanged;
+        public event EventHandler<SongsNumberChangedEventArgs> UpcomingSongsNumberChanged;
+        public event EventHandler RefreshButtonClicked;
 
-        public ConfigurationPane () : base ()
+        public ConfigurationPane (bool populate, string source_name, int played_songs_number, int upcoming_songs_number) : base ()
         {
-            main_box = new HBox ();
-            main_box.BorderWidth = 5;
+            var main_table = new Table (2, 5, false);
+            main_table.BorderWidth = 5;
+            main_table.ColumnSpacing = 5;
+
+            var populate_check_button = new CheckButton (Catalog.GetString ("Randomly populate the Play Queue from:"));
+            populate_check_button.Toggled += delegate {
+                var handler = PopulateChanged;
+                if (handler != null) {
+                    handler (this, new PopulateChangedEventArgs (populate_check_button.Active));
+                }
+            };
+            populate_check_button.Active = populate;
+            main_table.Attach (populate_check_button, 0, 1, 0, 1,
+                AttachOptions.Shrink | AttachOptions.Fill, AttachOptions.Fill,
+                main_table.ColumnSpacing, main_table.RowSpacing);
+
+            var source_combo_box = new QueueableSourceComboBox (source_name);
+            source_combo_box.Changed += delegate {
+                var handler = SourceChanged;
+                if (handler != null) {
+                    handler (this, new SourceChangedEventArgs (source_combo_box.Source));
+                }
+            };
+            main_table.Attach (source_combo_box, 0, 1, 1, 2,
+                AttachOptions.Shrink | AttachOptions.Fill, AttachOptions.Fill,
+                main_table.ColumnSpacing, main_table.RowSpacing);
 
-            // Translators: this label will be part of the following sentense: "Display: X recently played songs"
-            Label display_label = new Label (Catalog.GetString ("Display:"));
+            // Translators: this label will be part of the following sentense: "Show X recently played tracks"
+            var show_label = new Label (Catalog.GetString ("Show"));
+            show_label.Xalign = 1f;
+            main_table.Attach (show_label, 1, 2, 0, 1,
+                AttachOptions.Shrink | AttachOptions.Fill, AttachOptions.Fill,
+                main_table.ColumnSpacing, main_table.RowSpacing);
 
             SpinButton played_songs_spin_button = new SpinButton (0, 100, 1);
-            played_songs_spin_button.Value = PlayQueueSource.PlayedSongsNumber;
+            played_songs_spin_button.Value = played_songs_number;
             played_songs_spin_button.ValueChanged += delegate {
-                PlayQueueSource.PlayedSongsNumber = (int) played_songs_spin_button.Value;
+                var handler = PlayedSongsNumberChanged;
+                if (handler != null) {
+                    handler (this, new SongsNumberChangedEventArgs ((int) played_songs_spin_button.Value));
+                }
+            };
+            main_table.Attach (played_songs_spin_button, 2, 3, 0, 1,
+                AttachOptions.Shrink | AttachOptions.Fill, AttachOptions.Fill, 0, 0);
+
+            // Translators: this label will be part of the following sentense: "Show X recently played tracks"
+            var recent_songs_label = new Label (Catalog.GetString ("recently played tracks"));
+            recent_songs_label.Xalign = 0f;
+            main_table.Attach (recent_songs_label, 3, 4, 0, 1,
+                AttachOptions.Shrink | AttachOptions.Fill, AttachOptions.Fill,
+                main_table.ColumnSpacing, main_table.RowSpacing);
+
+            // Translators: this label will be part of the following sentense: "and X upcoming tracks"
+            var and_label = new Label (Catalog.GetString ("and"));
+            and_label.Xalign = 1f;
+            main_table.Attach (and_label, 1, 2, 1, 2,
+                AttachOptions.Shrink | AttachOptions.Fill, AttachOptions.Fill,
+                main_table.ColumnSpacing, main_table.RowSpacing);
+
+            SpinButton upcoming_songs_spin_button = new SpinButton (0, 100, 1);
+            upcoming_songs_spin_button.Value = upcoming_songs_number;
+            upcoming_songs_spin_button.ValueChanged += delegate {
+                var handler = UpcomingSongsNumberChanged;
+                if (handler != null) {
+                    handler (this, new SongsNumberChangedEventArgs ((int) upcoming_songs_spin_button.Value));
+                }
             };
+            main_table.Attach (upcoming_songs_spin_button, 2, 3, 1, 2,
+                AttachOptions.Shrink | AttachOptions.Fill, AttachOptions.Fill, 0, 0);
+
+            // Translators: this label will be part of the following sentense: "and X upcoming tracks"
+            var upcoming_songs_label = new Label (Catalog.GetString ("upcoming tracks"));
+            upcoming_songs_label.Xalign = 0f;
+            main_table.Attach (upcoming_songs_label, 3, 4, 1, 2,
+                AttachOptions.Shrink | AttachOptions.Fill, AttachOptions.Fill,
+                main_table.ColumnSpacing, main_table.RowSpacing);
+
+            var refresh_button = new Button (Stock.Refresh);
+            refresh_button.Clicked += delegate {
+                var handler = RefreshButtonClicked;
+                if (handler != null) {
+                    handler (this, new EventArgs ());
+                }
+            };
+            var refresh_alignment = new Alignment (1f, .5f, 0f, 0f);
+            refresh_alignment.Add (refresh_button);
+            main_table.Attach (refresh_alignment, 4, 5, 0, 2);
+
+            Add (main_table);
+        }
+    }
+
+    public sealed class PopulateChangedEventArgs : EventArgs
+    {
+        private bool value;
 
-            // Translators: this label will be part of the following sentense: "Display: X recently played songs"
-            Label played_songs_label = new Label (Catalog.GetString ("_recently played songs"));
-            played_songs_label.MnemonicWidget = played_songs_spin_button;
+        public PopulateChangedEventArgs (bool value)
+        {
+            this.value = value;
+        }
+
+        public bool Value {
+            get { return this.value; }
+        }
+    }
 
-            main_box.PackStart (display_label, false, false, 0);
-            main_box.PackStart (played_songs_spin_button, false, false, 5);
-            main_box.PackStart (played_songs_label, false, false, 0);
+    public sealed class SourceChangedEventArgs : EventArgs
+    {
+        private ITrackModelSource value;
+
+        public SourceChangedEventArgs (ITrackModelSource value)
+        {
+            this.value = value;
+        }
+
+        public ITrackModelSource Value {
+            get { return this.value; }
+        }
+    }
+
+    public sealed class SongsNumberChangedEventArgs : EventArgs
+    {
+        private int value;
+
+        public SongsNumberChangedEventArgs (int value)
+        {
+            this.value = value;
+        }
 
-            Add (main_box);
+        public int Value {
+            get { return this.value; }
         }
     }
 }
diff --git a/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/PlayQueueSource.cs b/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/PlayQueueSource.cs
index 94f5f05..9c2e31d 100644
--- a/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/PlayQueueSource.cs
+++ b/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/PlayQueueSource.cs
@@ -28,6 +28,7 @@
 //
 
 using System;
+using System.Linq;
 
 using Mono.Unix;
 
@@ -58,10 +59,12 @@ namespace Banshee.PlayQueue
         private PlayQueueActions actions;
         private bool was_playing = false;
         private ConfigurationPane pane;
-        
-        protected override bool HasArtistAlbum {
-            get { return false; }
-        }
+
+        private bool populate = PopulateSchema.Get ();
+        private string populate_from_name = PopulateFromSchema.Get ();
+        private ITrackModelSource populate_from = null;
+        private int played_songs_number = PlayedSongsNumberSchema.Get ();
+        private int upcoming_songs_number = UpcomingSongsNumberSchema.Get ();
         
         public PlayQueueSource () : base (Catalog.GetString ("Play Queue"), null)
         {
@@ -99,7 +102,13 @@ namespace Banshee.PlayQueue
             ServiceManager.SourceManager.VideoLibrary.TracksDeleted += HandleTracksDeleted;
             
             TrackModel.Reloaded += OnReloaded;
-            
+
+            populate_from = ServiceManager.SourceManager.Sources.FirstOrDefault (
+                source => source.Name == populate_from_name) as ITrackModelSource;
+            if (populate_from != null) {
+                populate_from.Reload ();
+            }
+
             Reload ();
             int track_index = CurrentTrackSchema.Get ();
             if (track_index < Count) {
@@ -113,7 +122,33 @@ namespace Banshee.PlayQueue
         {
             base.Initialize ();
 
-            pane = new ConfigurationPane ();
+            pane = new ConfigurationPane (populate, populate_from_name, played_songs_number, upcoming_songs_number);
+            pane.PopulateChanged += delegate(object sender, PopulateChangedEventArgs e) {
+                populate = e.Value;
+                PopulateSchema.Set (e.Value);
+                UpdatePlayQueue ();
+            };
+            pane.SourceChanged += delegate(object sender, SourceChangedEventArgs e) {
+                populate_from = e.Value;
+                populate_from_name = e.Value.Name;
+                PopulateFromSchema.Set (e.Value.Name);
+                populate_from.Reload ();
+                OnRefresh ();
+            };
+            pane.PlayedSongsNumberChanged += delegate(object sender, SongsNumberChangedEventArgs e) {
+                played_songs_number = e.Value;
+                PlayedSongsNumberSchema.Set (e.Value);
+                UpdatePlayQueue ();
+            };
+            pane.UpcomingSongsNumberChanged += delegate(object sender, SongsNumberChangedEventArgs e) {
+                upcoming_songs_number = e.Value;
+                UpcomingSongsNumberSchema.Set (e.Value);
+                UpdatePlayQueue ();
+            };
+            pane.RefreshButtonClicked += delegate {
+                OnRefresh ();
+            };
+
             BaseClientWindow nereid = ServiceManager.Get<IService> ("NereidPlayerInterface") as Banshee.Gui.BaseClientWindow;
             if (nereid != null) {
                 nereid.ViewContainer.PackEnd (pane, false, false, 0);
@@ -270,6 +305,7 @@ namespace Banshee.PlayQueue
                     ServiceManager.PlayerEngine.OpenPlay (current_track);
                 }
             }
+            UpdatePlayQueue ();
         }
 
         protected override void RemoveTrackRange (DatabaseTrackListModel model, RangeCollection.Range range)
@@ -360,10 +396,28 @@ namespace Banshee.PlayQueue
         private void UpdatePlayQueue ()
         {
             int index = current_track == null ? Count : TrackModel.IndexOf (current_track);
-            if (index > PlayedSongsNumber) {
-                RemoveTrackRange (DatabaseTrackModel, new RangeCollection.Range (0, index - PlayedSongsNumber - 1));
+            if (index < Count && index > played_songs_number) {
+                // Remove played songs.
+                RemoveTrackRange (DatabaseTrackModel, new RangeCollection.Range (0, index - played_songs_number - 1));
+                index = played_songs_number;
                 OnTracksRemoved ();
             }
+            int tracks_to_add = index + upcoming_songs_number - Count + 1;
+            if (index < Count && tracks_to_add > 0 && populate && populate_from != null) {
+                // Add songs from the selected source.
+                for (int i = 0; i < tracks_to_add; i++) {
+                    var track = populate_from.TrackModel.GetRandom (DateTime.Now, false);
+                    if (track != null) {
+                        this.EnqueueTrack (track, false);
+                    }
+                }
+                OnTracksAdded ();
+                if (current_track == null && Count > 0) {
+                    // If the queue was empty, make the first added track the current one.
+                    current_track = TrackModel[0] as DatabaseTrackInfo;
+                    ServiceManager.PlayerEngine.OpenPlay (current_track);
+                }
+            }
             UpdateEnabledStatus ();
         }
 
@@ -375,6 +429,16 @@ namespace Banshee.PlayQueue
             }
         }
 
+        private void OnRefresh ()
+        {
+            // TODO: remove only auto-added tracks
+            int index = current_track == null ? Count : TrackModel.IndexOf (current_track);
+            if (index + 1 < Count) {
+                RemoveTrackRange (DatabaseTrackModel, new RangeCollection.Range (index + 1, Count - 1));
+                OnTracksRemoved ();
+            }
+        }
+
         private void OnActiveSourceChanged (SourceEventArgs args)
         {
             Banshee.Base.ThreadAssist.ProxyToMain (delegate {
@@ -403,24 +467,10 @@ namespace Banshee.PlayQueue
             }
         }
 
-        private static int played_songs_number = -1;
-        public static int PlayedSongsNumber {
-            get {
-                if (played_songs_number == -1) {
-                    played_songs_number = PlayedSongsNumberSchema.Get ();
-                }
-                return played_songs_number;
-            }
-            set {
-                played_songs_number = value;
-                PlayedSongsNumberSchema.Set (value);
-            }
-        }
-        
         public override bool CanRename {
             get { return false; }
         }
-        
+
         public override bool CanSearch {
             get { return false; }
         }
@@ -428,11 +478,15 @@ namespace Banshee.PlayQueue
         public override bool ShowBrowser {
             get { return false; }
         }
-        
+
+        protected override bool HasArtistAlbum {
+            get { return false; }
+        }
+
         public override bool ConfirmRemoveTracks {
             get { return false; }
         }
-        
+
         public override bool CanUnmap {
             get { return false; }
         }
@@ -451,11 +505,32 @@ namespace Banshee.PlayQueue
             "Current track in the Play Queue"
         );
 
+        public static readonly SchemaEntry<bool> PopulateSchema = new SchemaEntry<bool> (
+            "plugins.play_queue", "populate",
+            true,
+            "Populate the Play Queue",
+            "Randomly populate the Play Queue from a source"
+        );
+
+        public static readonly SchemaEntry<string> PopulateFromSchema = new SchemaEntry<string> (
+            "plugins.play_queue", "populate_from",
+            ServiceManager.SourceManager.MusicLibrary.Name,
+            "Source to poplulate from",
+            "Name of the source to populate the the Play Queue from"
+        );
+
         public static readonly SchemaEntry<int> PlayedSongsNumberSchema = new SchemaEntry<int> (
             "plugins.play_queue", "played_songs_number",
             10,
             "Played Songs Number",
             "Number of played songs to show in the Play Queue"
         );
+
+        public static readonly SchemaEntry<int> UpcomingSongsNumberSchema = new SchemaEntry<int> (
+            "plugins.play_queue", "upcoming_songs_number",
+            10,
+            "Upcoming Songs Number",
+            "Number of upcoming songs to show in the Play Queue"
+        );
     }
 }
diff --git a/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/QueueableSourceComboBox.cs b/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/QueueableSourceComboBox.cs
new file mode 100644
index 0000000..83d8362
--- /dev/null
+++ b/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/QueueableSourceComboBox.cs
@@ -0,0 +1,106 @@
+// QueueableSourceComboBox.cs
+//
+// Authors:
+//   Alexander Kojevnikov <alexander@kojevnikov.com>
+//
+// Copyright (C) 2009 Alexander Kojevnikov
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using Gtk;
+
+using Banshee.Library;
+using Banshee.ServiceStack;
+using Banshee.Sources;
+using Banshee.Sources.Gui;
+
+namespace Banshee.PlayQueue
+{
+    public class QueueableSourceComboBox : ComboBox
+    {
+        private readonly TreeModelFilter filter;
+
+        public QueueableSourceComboBox (string source_name)
+        {
+            SourceRowRenderer renderer = new SourceRowRenderer ();
+            renderer.ParentWidget = this;
+            PackStart (renderer, true);
+            SetCellDataFunc (renderer, new CellLayoutDataFunc (SourceRowRenderer.CellDataHandler));
+
+            var store = new SourceModel ();
+            filter = new TreeModelFilter (store, null);
+            filter.VisibleFunc = (model, iter) => IsQueueable (((SourceModel)model).GetSource (iter));
+            Model = filter;
+
+            store.Refresh ();
+
+            SetActiveSource (source_name);
+        }
+
+        private void SetActiveSource (string name)
+        {
+            TreeIter first;
+            if (filter.GetIterFirst (out first)) {
+                TreeIter iter = FindSource (name, first);
+                if (!iter.Equals (TreeIter.Zero)) {
+                    SetActiveIter (iter);
+                }
+            }
+        }
+
+        private bool IsQueueable (Source source)
+        {
+            return source != null && (
+                source is MusicLibrarySource || source.Parent is MusicLibrarySource ||
+                source is VideoLibrarySource || source.Parent is VideoLibrarySource);
+        }
+
+        private TreeIter FindSource (string name, TreeIter iter)
+        {
+            do {
+                var source = filter.GetValue (iter, 0) as ISource;
+                if (source != null && source.Name == name) {
+                    return iter;
+                }
+
+                TreeIter citer;
+                if (filter.IterChildren (out citer, iter)) {
+                    var yiter = FindSource (name, citer);
+                    if (!yiter.Equals (TreeIter.Zero)) {
+                        return yiter;
+                    }
+                }
+            } while (filter.IterNext (ref iter));
+
+            return TreeIter.Zero;
+        }
+
+        public ITrackModelSource Source {
+            get {
+                TreeIter iter;
+                if (GetActiveIter (out iter)) {
+                    return filter.GetValue(iter, 0) as ITrackModelSource;
+                }
+                return null;
+            }
+        }
+    }
+}
diff --git a/src/Extensions/Banshee.PlayQueue/Makefile.am b/src/Extensions/Banshee.PlayQueue/Makefile.am
index 47d985a..ebf44ad 100644
--- a/src/Extensions/Banshee.PlayQueue/Makefile.am
+++ b/src/Extensions/Banshee.PlayQueue/Makefile.am
@@ -7,7 +7,8 @@ SOURCES =  \
 	Banshee.PlayQueue/ConfigurationPane.cs \
 	Banshee.PlayQueue/IPlayQueue.cs \
 	Banshee.PlayQueue/PlayQueueActions.cs \
-	Banshee.PlayQueue/PlayQueueSource.cs 
+	Banshee.PlayQueue/PlayQueueSource.cs \
+	Banshee.PlayQueue/QueueableSourceComboBox.cs 
 
 RESOURCES =  \
 	Banshee.PlayQueue.addin.xml \
