diff --git a/src/Core/Banshee.Services/Banshee.Sources/PrimarySource.cs b/src/Core/Banshee.Services/Banshee.Sources/PrimarySource.cs
index 9bf98d6..255ac00 100644
--- a/src/Core/Banshee.Services/Banshee.Sources/PrimarySource.cs
+++ b/src/Core/Banshee.Services/Banshee.Sources/PrimarySource.cs
@@ -545,6 +545,11 @@ namespace Banshee.Sources
             throw new Exception ("PrimarySource DeleteTrack method not implemented");
         }
 
+        protected virtual bool UpdateTrack (DatabaseTrackInfo track)
+        {
+            throw new Exception ("PrimarySource UpdateTrack method not implemented");
+        }
+
         public override bool AcceptsInputFromSource (Source source)
         {
             return base.AcceptsInputFromSource (source) && source.Parent != this
@@ -585,6 +590,23 @@ namespace Banshee.Sources
             return true;
         }
 
+        public bool UpdateTracks (Source dest, int prim_source_id)
+        {
+//            if (!AcceptsInputFromSource (source) || source.Count == 0) {
+//                return false;
+//            }
+//            
+            DatabaseTrackListModel model = (dest as ITrackModelSource).TrackModel as DatabaseTrackListModel;
+            CachedList<DatabaseTrackInfo> dest_cached_list = CachedList<DatabaseTrackInfo>.CreateFromModel (model);
+            //TODO:
+//            if (ThreadAssist.InMainThread) {
+//                System.Threading.ThreadPool.QueueUserWorkItem (AddTrackList, cached_list);
+//            } else {
+                UpdateTrackList (dest_cached_list, prim_source_id);
+//            }
+            return true;
+        }
+
         private static HyenaSqliteCommand get_track_id_cmd = new HyenaSqliteCommand ("SELECT TrackID FROM CoreTracks WHERE PrimarySourceId = ? AND Uri = ? LIMIT 1");
         public int GetTrackIdForUri (string uri)
         {
@@ -638,6 +660,71 @@ namespace Banshee.Sources
             is_adding = false;
         }
 
+        //protected virtual void UpdateTrackList (object lists)
+        protected virtual void UpdateTrackList (CachedList<DatabaseTrackInfo> dest, int primary_source_id)
+        {
+            //dest
+            foreach (DatabaseTrackInfo track in dest) {
+                Console.WriteLine ("______Track " + track.Artist + " - " + track.TrackTitle + " [" + track.Rating + "]");
+                int local_rating =
+                    ServiceManager.DbConnection.Query<int> ("SELECT Rating FROM CoreTracks WHERE MetadataHash = ? AND PrimarySourceId = ?",
+                                                            track.MetadataHash, primary_source_id);
+                if (track.Rating > 0 && local_rating == 0) {
+                    //FIXME: this doesn't refresh the primary source if it's being visualized currently
+                    ServiceManager.DbConnection.Execute (new HyenaSqliteCommand (
+                        "UPDATE CoreTracks SET Rating = ? WHERE MetadataHash = ? AND PrimarySourceId = ?",
+                        track.Rating,
+                        track.MetadataHash,
+                        primary_source_id
+                    ));
+                } else if (local_rating > 0 && track.Rating == 0) {
+                    track.Rating = local_rating;
+                    track.Save ();
+                    UpdateTrack (track);
+                    //ServiceManager.DbConnection.Query<int> ("INSERT INTO LastSyncedRatings(Rating,MetadataHash,DapId) VALUES (?, ?, ?)", local_rating, track.MetadataHash, ...);
+                }
+                //TODO: else {
+                //    int last_rating_synced =
+                //        ServiceManager.DbConnection.Query<int> ("SELECT Rating FROM LastSyncedRatings WHERE MetadataHash = ?, DapId = ?", track.MetadataHash, ...);
+                //    if (track.Rating == last_rating_synced) {
+                //        track.Rating = local_rating;
+                //        track.Save (); //save the iPodTrackInfo as well
+                //        ServiceManager.DbConnection.Query<int> ("UPDATE LastSyncedRatings SET Rating = ? WHERE MetadataHash = ?, DapId = ?", local_rating, track.MetadataHash, ...);
+                //    } else {
+                //        //TODO: display sync warning
+                //    }
+                //}
+                
+            }
+//            CachedList<DatabaseTrackInfo> list = cached_list as CachedList<DatabaseTrackInfo>;
+////            is_adding = true;
+////            AddTrackJob.Total += (int) list.Count;
+//
+//            foreach (DatabaseTrackInfo track in list) {
+//                if (AddTrackJob.IsCancelRequested) {
+//                    AddTrackJob.Finish ();
+//                    IncrementAddedTracks ();
+//                    break;
+//                }
+//                
+//                if (track == null) {
+//                    IncrementAddedTracks ();
+//                    continue;
+//                }
+//
+//                try {
+//                    AddTrackJob.Status = String.Format ("{0} - {1}", track.ArtistName, track.TrackTitle);
+//                    AddTrackAndIncrementCount (track);
+//                } catch (Exception e) {
+//                    IncrementAddedTracks ();
+//                    Log.Exception (e);
+//                    ErrorSource.AddMessage (e.Message, track.Uri.ToString ());
+//                }
+//            }
+//            is_adding = false;
+        }
+
+
         protected void IncrementAddedTracks ()
         {
             bool finished = false, notify = false;
diff --git a/src/Dap/Banshee.Dap.Ipod/Banshee.Dap.Ipod/IpodSource.cs b/src/Dap/Banshee.Dap.Ipod/Banshee.Dap.Ipod/IpodSource.cs
index d226cd5..4a79f90 100644
--- a/src/Dap/Banshee.Dap.Ipod/Banshee.Dap.Ipod/IpodSource.cs
+++ b/src/Dap/Banshee.Dap.Ipod/Banshee.Dap.Ipod/IpodSource.cs
@@ -417,6 +417,7 @@ namespace Banshee.Dap.Ipod
         
         private Queue<IpodTrackInfo> tracks_to_add = new Queue<IpodTrackInfo> ();
         private Queue<IpodTrackInfo> tracks_to_remove = new Queue<IpodTrackInfo> ();
+        private Queue<IpodTrackInfo> tracks_to_update = new Queue<IpodTrackInfo> ();
         
         private uint sync_timeout_id = 0;
         private object sync_timeout_mutex = new object ();
@@ -454,6 +455,23 @@ namespace Banshee.Dap.Ipod
                 return true;
             }
         }
+
+        protected override bool UpdateTrack (DatabaseTrackInfo track)
+        {
+            lock (sync_mutex) {
+                if (!tracks_map.ContainsKey (track.TrackId)) {
+                    return false;
+                }
+                
+                IpodTrackInfo ipod_track = tracks_map[track.TrackId];
+                if (ipod_track != null) {
+                    tracks_to_update.Enqueue (ipod_track);
+                    ipod_track.Rating = track.Rating;
+                }
+                
+                return true;
+            }
+        }
         
         protected override void AddTrackToDevice (DatabaseTrackInfo track, SafeUri fromUri)
         {
@@ -567,7 +585,14 @@ namespace Banshee.Dap.Ipod
                 }
             }
 
-            // TODO sync updated metadata to changed tracks
+            // TODO sync all updated metadata to changed tracks
+            while (tracks_to_update.Count > 0) {
+                IpodTrackInfo track = null;
+                lock (sync_mutex) {
+                    track = tracks_to_update.Dequeue ();
+                }
+                track.CommitToIpod (ipod_device);
+            }
             
             while (tracks_to_remove.Count > 0) {
                 IpodTrackInfo track = null;
diff --git a/src/Dap/Banshee.Dap/Banshee.Dap/DapLibrarySync.cs b/src/Dap/Banshee.Dap/Banshee.Dap/DapLibrarySync.cs
index 6b6849b..386a65a 100644
--- a/src/Dap/Banshee.Dap/Banshee.Dap/DapLibrarySync.cs
+++ b/src/Dap/Banshee.Dap/Banshee.Dap/DapLibrarySync.cs
@@ -53,7 +53,7 @@ namespace Banshee.Dap
         private SchemaEntry<bool> enabled, sync_entire_library;
         private SchemaEntry<string[]> playlist_ids;
         private SchemaPreference<bool> enabled_pref;
-        private SmartPlaylistSource sync_src, to_add, to_remove;
+        private SmartPlaylistSource sync_src, to_add, to_remove, to_update;
         private Section library_prefs_section;
         
         #region Public Properties
@@ -106,6 +106,9 @@ namespace Banshee.Dap
 
         internal void Dispose ()
         {
+            if (to_update != null)
+                to_update.Unmap ();
+
             if (to_add != null)
                 to_add.Unmap ();
 
@@ -154,17 +157,23 @@ namespace Banshee.Dap
                 "MetadataHash NOT IN (SELECT MetadataHash FROM CoreTracks WHERE PrimarySourceId = {0})", sync.Dap.DbId
             ));
 
+            var rel_condition = @"MetadataHash {0} IN (SELECT MetadataHash FROM CoreTracks, CoreSmartPlaylistEntries 
+                                  WHERE CoreSmartPlaylistEntries.SmartPlaylistID = {1}
+                                    AND CoreTracks.TrackID = CoreSmartPlaylistEntries.TrackID)";
+            
             // Any items on the device that aren't in the sync lists need to be removed
             to_remove = new SmartPlaylistSource ("to_remove", sync.Dap);
             to_remove.IsTemporary = true;
             to_remove.Save ();
             to_remove.AddCondition (library.AttributesCondition);
-            to_remove.AddCondition (String.Format (
-                @"MetadataHash NOT IN (SELECT MetadataHash FROM CoreTracks, CoreSmartPlaylistEntries 
-                    WHERE CoreSmartPlaylistEntries.SmartPlaylistID = {0} AND
-                        CoreTracks.TrackID = CoreSmartPlaylistEntries.TrackID)",
-                sync_src.DbId
-            ));
+            to_remove.AddCondition (String.Format (rel_condition, "NOT", sync_src.DbId));
+
+            // Items that are already on the device and also in our library
+            to_update = new SmartPlaylistSource ("to_update", sync.Dap);
+            to_update.IsTemporary = true;
+            to_update.Save ();
+            to_update.AddCondition (library.AttributesCondition);
+            to_update.AddCondition (String.Format (rel_condition, String.Empty, sync_src.DbId));
         }
         
         internal void CalculateSync ()
@@ -185,15 +194,20 @@ namespace Banshee.Dap
             sync_src.RefreshAndReload ();
             to_add.RefreshAndReload ();
             to_remove.RefreshAndReload ();
+            to_update.RefreshAndReload ();
             enabled_pref.Name = String.Format ("{0} ({1})",
                 enabled.ShortDescription,
-                String.Format (Catalog.GetString ("{0} to add, {1} to remove"), to_add.Count, to_remove.Count));
+                String.Format (Catalog.GetString ("{0} to add, {1} to remove, {2} to update"),
+                               to_add.Count, to_remove.Count, to_update.Count));
         }
 
         public override string ToString ()
         {
-            return String.Format ("Sync calculated for {1}: to add: {0} items, remove {2} items; sync_src.cacheid = {5}, to_add.cacheid = {3}, to_remove.cacheid = {4}", to_add.Count, library.Name, to_remove.Count,
-                                  to_add.DatabaseTrackModel.CacheId, to_remove.DatabaseTrackModel.CacheId, sync_src.DatabaseTrackModel.CacheId);
+            return String.Format (
+                "Sync calculated for {0}: to add: {1} items, remove {2} items, update {3} items;" + 
+                " sync_src.cacheid = {3}, to_add.cacheid = {4}, to_remove.cacheid = {5}, to_update.cacheid = {6}",
+                library.Name, to_add.Count, to_remove.Count, to_update.Count, sync_src.DatabaseTrackModel.CacheId,
+                to_add.DatabaseTrackModel.CacheId, to_remove.DatabaseTrackModel.CacheId, to_update.DatabaseTrackModel.CacheId);
         }
         
         internal void Sync ()
@@ -201,8 +215,11 @@ namespace Banshee.Dap
             if (Enabled) {
                 Banshee.Base.ThreadAssist.AssertNotInMainThread ();
 
+                CalculateSync ();
+
                 sync.Dap.DeleteAllTracks (to_remove);
                 sync.Dap.AddAllTracks (to_add);
+                sync.Dap.UpdateTracks (to_update, sync_src.PrimarySourceId);
 
                 if (library.SupportsPlaylists && sync.Dap.SupportsPlaylists) {
                     // Now create the playlists, taking snapshots of smart playlists and saving them
