? banshee-ipod-playlists.patch
? banshee-ipod-playlists_rev2.patch
? banshee-ipod-playlists_rev3.patch
? banshee-ipod-playlists_rev4.patch
? devel-main
? data/translators.xml
? entagged-sharp/Makefile
? entagged-sharp/Makefile.in
? entagged-sharp/entagged-sharp.dll
? entagged-sharp/entagged-sharp.dll.mdb
? src/Banshee.Hyena/Makefile
? src/Banshee.Hyena/Makefile.in
? src/Banshee.Hyena/hyena.exe.mdb
? src/Banshee.MediaEngine/Gstreamer/GStreamerPlayerEngine.dll
? src/Banshee.MediaEngine/Gstreamer/GStreamerPlayerEngine.dll.config
? src/Banshee.MediaEngine/Gstreamer/GStreamerPlayerEngine.dll.mdb
? src/Gnome.Keyring/Gnome.Keyring.dll
? src/Gnome.Keyring/Gnome.Keyring.dll.mdb
? src/Gnome.Keyring/Makefile
? src/Gnome.Keyring/Makefile.in
? src/Last.FM/Last.FM.dll
? src/Last.FM/Last.FM.dll.mdb
? src/Last.FM/Makefile
? src/Last.FM/Makefile.in
? taglib-sharp/Makefile
? taglib-sharp/Makefile.in
? tests/Makefile
? tests/Makefile.in
? tools/Makefile
? tools/Makefile.in
? tools/banshee-import
Index: data/images/Makefile.am
===================================================================
RCS file: /cvs/gnome/banshee/data/images/Makefile.am,v
retrieving revision 1.38
diff -u -r1.38 Makefile.am
--- data/images/Makefile.am	5 Sep 2006 21:55:25 -0000	1.38
+++ data/images/Makefile.am	13 Sep 2006 05:39:51 -0000
@@ -50,6 +50,7 @@
 	source-cd-audio.png \
 	source-library.png \
 	source-playlist.png \
+	source-playlist-uncommited.png \
 	source-localqueue.png \
 	sync-needed.png \
 	tray-icon.png \
Index: src/PlayerInterface.cs
===================================================================
RCS file: /cvs/gnome/banshee/src/PlayerInterface.cs,v
retrieving revision 1.216
diff -u -r1.216 PlayerInterface.cs
--- src/PlayerInterface.cs	12 Sep 2006 04:53:09 -0000	1.216
+++ src/PlayerInterface.cs	13 Sep 2006 05:39:51 -0000
@@ -110,6 +110,11 @@
         
         private SpecialKeys special_keys;
 
+        private static TargetEntry [] sourceViewSourceEntries = 
+             new TargetEntry [] {
+                 Banshee.Gui.DragDrop.DragDropTarget.Source
+        };
+        
         private static TargetEntry [] playlistViewSourceEntries = 
             new TargetEntry [] {
                 Banshee.Gui.DragDrop.DragDropTarget.PlaylistRows,
@@ -397,7 +402,10 @@
             SourceManager.SourceViewChanged += OnSourceManagerSourceViewChanged;
             SourceManager.SourceTrackAdded += OnSourceTrackAdded;
             SourceManager.SourceTrackRemoved += OnSourceTrackRemoved;
-
+	    sourceView.EnableModelDragSource(
+                 Gdk.ModifierType.Button1Mask | Gdk.ModifierType.Button3Mask,
+                 sourceViewSourceEntries, 
+                 DragAction.Copy);
             InterfaceElements.MainContainer = gxml["MainContainer"] as VBox;
 
             // Playlist View
@@ -2021,7 +2029,7 @@
             
             switch(md.Run()) {
                 case (int)ResponseType.Ok:
-                    dapSource.Device.Save(Globals.Library.Tracks.Values);
+                    dapSource.Device.Save( LibrarySource.Instance);
                     break;
                 case (int)ResponseType.Apply:
                     dapSource.Device.Save();
Index: src/SourceView.cs
===================================================================
RCS file: /cvs/gnome/banshee/src/SourceView.cs,v
retrieving revision 1.55
diff -u -r1.55 SourceView.cs
--- src/SourceView.cs	4 Sep 2006 22:37:59 -0000	1.55
+++ src/SourceView.cs	13 Sep 2006 05:39:51 -0000
@@ -270,6 +270,10 @@
             
             SetCursor(store.GetPath(iter), focus_column, true);
         }
+
+	//protected override void OnDragBegin (Gdk.DragContext context)
+	//{
+	//}
         
         private void OnCursorChanged(object o, EventArgs args)
         {                
@@ -334,12 +338,13 @@
             Gdk.Drag.Status(context, Gdk.DragAction.Copy, time);
 
             // FIXME: We need to handle this nicer
-            if(Gtk.Drag.GetSourceWidget(context) != this && 
-                !(SourceManager.ActiveSource is LibrarySource ||
-                SourceManager.ActiveSource is PlaylistSource ||
-                SourceManager.ActiveSource is IImportable)) {
-                return false;
-            }
+            //FIXME: IPOD SUPPORT!
+            //if(Gtk.Drag.GetSourceWidget(context) != this && 
+             //   !(SourceManager.ActiveSource is LibrarySource ||
+            //   SourceManager.ActiveSource is PlaylistSource ||
+            //    SourceManager.ActiveSource is IImportable)) {
+            //    return false;
+           // }
         
             if(!newPlaylistVisible && Gtk.Drag.GetSourceWidget(context) != this) {
                 TreeIter library = FindSource(LibrarySource.Instance);
@@ -356,14 +361,14 @@
             if(GetDestRowAtPos(x, y, out path, out pos)) {
                 Source source = GetSource(path);
                 SetDragDestRow(path, TreeViewDropPosition.IntoOrAfter);
-                
-                if((source is LibrarySource && (SourceManager.ActiveSource is IImportable 
-                    || SourceManager.ActiveSource is IImportSource)) ||
-                    (source is PlaylistSource) || (source is DapSource) || source.AcceptsInput) {
-                    return true;
-                }
+                //FIXME: IPOD SUPPORT!
+                //if((source is LibrarySource && (SourceManager.ActiveSource is IImportable 
+                //    || SourceManager.ActiveSource is IImportSource)) ||
+                //    (source is PlaylistSource) || (source is DapSource) || source.AcceptsInput) {
+                //    return true;
+               // }
 
-                Gdk.Drag.Status(context, 0, time);
+                //Gdk.Drag.Status(context, 0, time);
                 return true;
             }
             
Index: src/Banshee.Base/Makefile.am
===================================================================
RCS file: /cvs/gnome/banshee/src/Banshee.Base/Makefile.am,v
retrieving revision 1.57
diff -u -r1.57 Makefile.am
--- src/Banshee.Base/Makefile.am	12 Sep 2006 02:35:31 -0000	1.57
+++ src/Banshee.Base/Makefile.am	13 Sep 2006 05:39:51 -0000
@@ -119,6 +119,7 @@
 	$(srcdir)/Dap/DapCore.cs \
 	$(srcdir)/Dap/DapTrackInfo.cs \
 	$(srcdir)/Dap/DapMisc.cs \
+	$(srcdir)/Sources/DapPlaylistSource.cs \
 	$(srcdir)/Dap/DapPropertiesDialog.cs 
 
 SOURCES_SOURCES = \
Index: src/Banshee.Base/Dap/Dap.cs
===================================================================
RCS file: /cvs/gnome/banshee/src/Banshee.Base/Dap/Dap.cs,v
retrieving revision 1.20
diff -u -r1.20 Dap.cs
--- src/Banshee.Base/Dap/Dap.cs	28 Jul 2006 21:25:36 -0000	1.20
+++ src/Banshee.Base/Dap/Dap.cs	13 Sep 2006 05:39:51 -0000
@@ -131,15 +131,21 @@
         private DapProperties type_properties;
 
         protected List<TrackInfo> tracks = new List<TrackInfo>(); 
+        //protected List<TrackInfo> playlists = new List<TrackInfo>(); 
+        private ArrayList playlists = new ArrayList();
         
         public event DapTrackListUpdatedHandler TrackAdded;
         public event DapTrackListUpdatedHandler TrackRemoved;
         public event EventHandler TracksCleared;
+	public event EventHandler PlaylistAdded;
+	public event EventHandler PlaylistRemoved;
+	public event EventHandler PlaylistsCleared;
         public event EventHandler PropertiesChanged;
         public event EventHandler Ejected;
         public event EventHandler SaveStarted;
         public event EventHandler SaveFinished;
         public event EventHandler Reactivate;
+	public event EventHandler Loaded;
         
         public Hal.Device HalDevice;
         private Source source;
@@ -189,6 +195,14 @@
                 handler(this, new EventArgs());
             }
         }
+
+	protected void OnLoaded()
+	{
+	    EventHandler handler = Loaded;
+	    if(handler != null) {
+		handler(this, new EventArgs());
+	    }
+	}
         
         protected void InstallProperty(string name, string value)
         {
@@ -216,12 +230,7 @@
                 handler(this, new DapTrackListUpdatedArgs(track));
             }
         }
-        
-        public virtual void Dispose()
-        {
-            SourceManager.RemoveSource(source);
-        }
-        
+
         public void ClearTracks()
         {
             ClearTracks(true);
@@ -238,6 +247,57 @@
                 }
             }
         }
+
+	public void AddPlaylist(DapPlaylistSource dps)
+	{
+	    if(dps == null)
+		return;
+
+	    playlists.Add(dps);
+	    OnPlaylistAdded (dps);
+	}
+
+	public void AddPlaylist(PlaylistSource ps)
+	{
+	    if(ps == null)
+		return;
+
+	    DapPlaylistSource dps = new DapPlaylistSource(ps.Name);
+
+	    // FIXME: Also add tracks we need if there is enough disk space
+	    foreach(TrackInfo ti in ps.Tracks) {
+		if (TrackExistsInList(ti, tracks))
+		    dps.AddTrack(ti);
+	    }
+
+	    AddPlaylist(dps);
+	}
+        
+	public void RemovePlaylist(DapPlaylistSource dps)
+	{
+	    dps.Delete();
+	    playlists.Remove(dps);
+	    OnPlaylistRemoved(dps);
+	}
+
+	public void ClearPlaylists()
+	{
+	    foreach(DapPlaylistSource dps in playlists)
+		dps.Delete();
+
+	    playlists.Clear();
+	    OnPlaylistsCleared();
+
+    	    EventHandler handler = PlaylistsCleared;
+	    if(handler != null) {
+		handler(null, new EventArgs());
+	    }
+	}
+
+        public virtual void Dispose()
+        {
+            SourceManager.RemoveSource(source);
+        }
         
         protected virtual void OnTrackAdded (TrackInfo track)
         {
@@ -254,6 +314,26 @@
         protected virtual void OnTracksCleared()
         {
         }
+
+        protected virtual void OnPlaylistAdded(DapPlaylistSource dps)
+        {
+            EventHandler handler = PlaylistAdded;
+	    if(handler != null) {
+		handler(dps, new EventArgs());
+	    }
+        }
+        
+        protected virtual void OnPlaylistRemoved(DapPlaylistSource dps)
+        {
+            EventHandler handler = PlaylistRemoved;
+	    if(handler != null) {
+		handler(dps, new EventArgs());
+	    }
+        }
+
+	protected virtual void OnPlaylistsCleared()
+	{
+	}
         
         public virtual void Activate()
         {
@@ -281,7 +361,7 @@
                 a.TrackNumber == b.TrackNumber;
         }
         
-        protected bool TrackExistsInList(TrackInfo track, ICollection<TrackInfo> list)
+        protected bool TrackExistsInList(TrackInfo track, IEnumerable<TrackInfo> list)
         {
             try {
                 foreach(TrackInfo track_b in list) {
@@ -295,12 +375,12 @@
             return false;
         }
 
-        public void Save(ICollection<TrackInfo> library)
+        public void Save(LibrarySource library)
         {
             Queue remove_queue = new Queue();
             
-            foreach(TrackInfo ti in Tracks) {
-                if(TrackExistsInList(ti, library)) {
+            foreach(TrackInfo ti in library.Tracks) {
+                if(TrackExistsInList(ti, library.Tracks)) {
                     continue;
                 }
                 
@@ -311,13 +391,21 @@
                 RemoveTrack(remove_queue.Dequeue() as TrackInfo);
             }
             
-            foreach(TrackInfo ti in library) {
-                if(TrackExistsInList(ti, Tracks) || ti.Uri == null) {
+            foreach(TrackInfo ti in library.Tracks) {
+                if(TrackExistsInList(ti, library.Tracks) || ti.Uri == null) {
                     continue;
                 }
                 
                 AddTrack(ti);
             }
+
+	    foreach(ChildSource cs in source.Children) {
+		if(!(cs is PlaylistSource))
+		    continue;
+
+		PlaylistSource ps = cs as PlaylistSource;
+		AddPlaylist(ps);
+	    }
             
             Save();
         }
@@ -576,6 +664,12 @@
         public IList<TrackInfo> Tracks {
             get { return tracks; }
         }
+        
+        public IList Playlists {
+	    get {
+		return playlists;
+	    }
+	}
         
         public bool IsSyncing {
             get { return is_syncing; }
Index: src/Banshee.Base/Sources/DapPlaylistSource.cs
===================================================================
RCS file: src/Banshee.Base/Sources/DapPlaylistSource.cs
diff -N src/Banshee.Base/Sources/DapPlaylistSource.cs
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/Banshee.Base/Sources/DapPlaylistSource.cs	13 Sep 2006 05:39:51 -0000
@@ -0,0 +1,202 @@
+/***************************************************************************
+ *  DapPlaylistSource.cs
+ *
+ *  Copyright (C) 2006 Novell, Inc.
+ *  Written by Lukas Lipka <lukaslipka@gmail.com>
+ ****************************************************************************/
+
+/*  THIS FILE IS LICENSED UNDER THE MIT LICENSE AS OUTLINED IMMEDIATELY BELOW: 
+ *
+ *  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 System;
+using System.Data;
+using System.Collections;
+using System.Collections.Generic;
+using Mono.Unix;
+
+using Banshee.Base;
+
+namespace Banshee.Sources
+{
+    public class DapPlaylistSource : ChildSource
+    {
+        //private ArrayList tracks = new ArrayList();
+        private List<TrackInfo> tracks = new List<TrackInfo>();
+        private Queue remove_queue = new Queue();
+        private Queue append_queue = new Queue();
+
+        public DapPlaylistSource() : base(Catalog.GetString("New Playlist"), 500)
+        {
+        }
+
+        public DapPlaylistSource(string name) : base(name, 500)
+        {
+        }
+      
+        protected override bool UpdateName(string oldName, string newName)
+        {
+            if(oldName.Equals(newName)) {
+                return false;
+            }
+            
+	    // FIXME: Check for same name
+            /*if(PlaylistUtil.PlaylistExists(newName)) {
+                LogCore.Instance.PushWarning(
+                    Catalog.GetString("Cannot Rename Playlist"),
+                    Catalog.GetString("A playlist with this name already exists. Please choose another name."));
+                return false;
+		}*/
+            
+            Name = newName;
+            return true;
+        }
+ 	
+        public override void AddTrack(TrackInfo track)
+        {
+            if(track is LibraryTrackInfo) {
+                lock(TracksMutex) {
+                    tracks.Add(track);
+                    append_queue.Enqueue(track);
+                }
+                OnUpdated();
+            }
+        }
+
+        public override void RemoveTrack(TrackInfo track)
+        {
+            lock(TracksMutex) {
+                tracks.Remove(track);
+                remove_queue.Enqueue(track);
+            }
+        }
+
+        public override void Commit()
+        {
+        }
+
+        public void Delete()
+        {
+            tracks.Clear();
+            append_queue.Clear();
+            remove_queue.Clear();
+            SourceManager.RemoveSource(this);
+        }
+        
+        /*public override void Reorder(TrackInfo track, int position)
+        {
+            lock(TracksMutex) {
+                int sql_position = 1;
+            
+                if(position > 0) {
+                    TrackInfo sibling = tracks[position] as TrackInfo;
+                    if(sibling == track || sibling == null) {
+                        return;
+                    }
+                    
+                    sql_position = Convert.ToInt32(Globals.Library.Db.QuerySingle(String.Format(
+                        @"SELECT ViewOrder
+                            FROM PlaylistEntries
+                            WHERE PlaylistID = '{0}'
+                                AND TrackID = '{1}'
+                            LIMIT 1", id, sibling.TrackId)
+                    ));
+                } else if(tracks[position] == track) {
+                    return;
+                } 
+                
+                Globals.Library.Db.Execute(String.Format(
+                    @"UPDATE PlaylistEntries
+                        SET ViewOrder = ViewOrder + 1
+                        WHERE PlaylistID = '{0}'
+                            AND ViewOrder >= '{1}'",
+                    id, sql_position
+                ));
+                
+                Globals.Library.Db.Execute(String.Format(
+                    @"UPDATE PlaylistEntries
+                        SET ViewOrder = '{1}'
+                        WHERE PlaylistID = '{0}'
+                            AND TrackID = '{2}'",
+                    id, sql_position, track.TrackId
+                ));
+                
+                tracks.Remove(track);
+                tracks.Insert(position, track);
+            }
+        }*/
+        
+        private void OnLibraryTrackRemoved(object o, LibraryTrackRemovedArgs args)
+        {
+            if(args.Track != null) {
+                if(tracks.Contains(args.Track)) {
+                    RemoveTrack(args.Track);
+                    
+                    if(Count == 0) {
+                        Delete();
+                    } else {
+                        Commit();
+                    }
+                }          
+            } else if (args.Tracks == null) {
+		return;
+	    }
+            
+            int removed_count = 0;
+            
+            lock(TracksMutex) {
+                foreach(TrackInfo track in args.Tracks) {
+                    if(tracks.Contains(track)) {
+                        tracks.Remove(track);
+                        remove_queue.Enqueue(track);
+                        removed_count++;
+                    }
+                }
+            }
+            
+            if(removed_count > 0) {
+                if(Count == 0) {
+                    Delete();
+                } else {
+                    Commit();
+                }
+            }
+        }
+        
+       public override IEnumerable<TrackInfo> Tracks {
+            get { return tracks; }
+        }
+        
+        public override object TracksMutex {
+            get { return ((IList)tracks).SyncRoot; }
+        }
+        
+        public override int Count {
+            get { return tracks.Count; }
+        }  
+        
+        private static Gdk.Pixbuf commited_icon = IconThemeUtils.LoadIcon(22, "source-playlist");
+        private static Gdk.Pixbuf uncommited_icon = IconThemeUtils.LoadIcon(22, "source-playlist-uncommited");
+
+        public override Gdk.Pixbuf Icon {
+            get { return commited_icon; }
+        }
+    }
+}
Index: src/Banshee.Base/Sources/DapSource.cs
===================================================================
RCS file: /cvs/gnome/banshee/src/Banshee.Base/Sources/DapSource.cs,v
retrieving revision 1.12
diff -u -r1.12 DapSource.cs
--- src/Banshee.Base/Sources/DapSource.cs	28 Jul 2006 22:05:48 -0000	1.12
+++ src/Banshee.Base/Sources/DapSource.cs	13 Sep 2006 05:39:51 -0000
@@ -50,9 +50,12 @@
         public DapSource(Banshee.Dap.DapDevice device) : base(device.Name, 400)
         {
             this.device = device;
+
             device.SaveStarted += OnDapSaveStarted;
             device.SaveFinished += OnDapSaveFinished;
             device.Reactivate += OnDapReactivate;
+	    device.Loaded += OnDapLoaded;
+
             CanRename = device.CanSetName;
         }
         
@@ -130,6 +133,13 @@
             OnViewChanged();
             OnUpdated();
         }
+
+	private void OnDapLoaded(object o, EventArgs args)
+	{
+	    foreach(DapPlaylistSource dps in device.Playlists) {
+		AddChildSource(dps);
+	    }
+	}
         
         public override void Activate()
         {
Index: src/Banshee.Dap/Ipod/IpodDap.cs
===================================================================
RCS file: /cvs/gnome/banshee/src/Banshee.Dap/Ipod/IpodDap.cs,v
retrieving revision 1.17
diff -u -r1.17 IpodDap.cs
--- src/Banshee.Dap/Ipod/IpodDap.cs	26 Aug 2006 17:37:44 -0000	1.17
+++ src/Banshee.Dap/Ipod/IpodDap.cs	13 Sep 2006 05:39:52 -0000
@@ -36,7 +36,8 @@
 
 using Banshee.Base;
 using Banshee.Dap;
- 
+using Banshee.Sources;
+
 namespace Banshee.Dap.Ipod
 {
     [DapProperties(DapType = DapType.NonGeneric, PipelineName="Ipod")]
@@ -144,6 +145,17 @@
                     IpodDapTrackInfo ti = new IpodDapTrackInfo(track);
                     AddTrack(ti);            
                 }
+
+		foreach(Playlist playlist in device.TrackDatabase.Playlists) {
+		    DapPlaylistSource dps = new DapPlaylistSource (playlist.Name);
+
+		    foreach(Track song in playlist.Tracks) {
+			IpodDapTrackInfo track = new IpodDapTrackInfo(song);
+			dps.AddTrack(track);
+		    }
+
+		    AddPlaylist(dps);
+		}
             } else {
                 BuildDatabaseUnsupportedWidget();
             }
@@ -151,9 +163,36 @@
             if(previous_database_supported != database_supported) {
                 OnPropertiesChanged();
             }
+
+	    OnLoaded();
         }
-        
-        public override void Eject()
+
+	// FIXME: Lame comparsion
+        private string ToLower(string str)
+	{
+            return str == null ? null : str.ToLower();
+	}
+
+        private bool TrackSongCompare(TrackInfo a, Track b)
+        {
+            Console.WriteLine ("Comparing " + a + " to " + b);
+            return ToLower(a.Title) == ToLower(b.Title) &&
+                ToLower(a.Album) == ToLower(b.Album) &&
+                ToLower(a.Artist) == ToLower(b.Artist) &&
+                a.Year == b.Year &&
+                a.TrackNumber == b.TrackNumber;
+        }
+
+	private void DeleteAllPlaylists (TrackDatabase db)
+	{
+	   IEnumerator ie = db.Playlists.GetEnumerator();
+	   while (ie.MoveNext() ){
+		Console.WriteLine (ie.ToString());
+		db.RemovePlaylist ((Playlist) ie.Current);
+	   }
+	}
+	
+	public override void Eject()
         {
             try {
                 device.Eject();
@@ -178,7 +217,12 @@
                     track.Track.Uri = new Uri(track.Uri.AbsoluteUri);
                 }
             }
-            
+            DeleteAllPlaylists (device.TrackDatabase);
+	    Console.WriteLine (device.TrackDatabase.Playlists);
+	    foreach(DapPlaylistSource ps in Playlists) {
+		CommitPlaylistToDevice (ps);
+	    }
+	    
             device.TrackDatabase.SaveProgressChanged += delegate(object o, TrackSaveProgressArgs args)
             {
                 double progress = args.CurrentTrack == null ? 0.0 : args.TotalProgress;
@@ -281,6 +325,32 @@
                 track.SetCoverArt (format, ArtworkHelpers.ToBytes (format, pixbuf));
             }
         }
+	
+	private void CommitPlaylistToDevice (DapPlaylistSource source)
+	{
+	    Playlist playlist = device.TrackDatabase.LookupPlaylist (source.Name);
+	    
+	    // FIXME: Incrementally update. Maybe later :-)
+	    
+	    if (playlist == null)
+	    	playlist = device.TrackDatabase.CreatePlaylist (source.Name);
+	    	//device.TrackDatabase.RemovePlaylist (playlist);
+	    Console.WriteLine (source.Name);
+	    
+	    //Console.WriteLine (playlist);
+	    foreach (TrackInfo track in source.Tracks) {
+		
+		foreach(Track track2 in device.TrackDatabase.Tracks) {
+		    
+		    Console.WriteLine ("Comparing: " + track + " to " + track2);
+		    if (!TrackSongCompare (track, track2))
+			continue;
+		    Console.WriteLine ("Adding: " + track2);
+		    playlist.AddTrack (track2);
+		}
+	    }
+       }
+
         
         public override Gdk.Pixbuf GetIcon(int size)
         {
