diff -ru ../123/mythplugins/mythmusic/mythmusic/main.cpp mythplugins/mythmusic/mythmusic/main.cpp
--- ../123/mythplugins/mythmusic/mythmusic/main.cpp	2005-10-26 00:55:11.000000000 -0700
+++ mythplugins/mythmusic/mythmusic/main.cpp	2005-10-26 10:38:42.183483352 -0700
@@ -6,6 +6,8 @@
 #include <qapplication.h>
 #include <qsqldatabase.h>
 #include <qregexp.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <unistd.h>
 
 #include <cdaudio.h>
@@ -93,10 +95,36 @@
     query.exec();
 }
 
+void UpdateFileInDB (const QString &directory, const QString &filename)
+{
+    Decoder *decoder = getDecoder (filename);
+    
+    if (decoder)
+    {
+        Metadata *db_meta = decoder->getMetadata ();
+        Metadata *disk_meta = decoder->readMetadata ();
+        
+        if (db_meta && disk_meta)
+        {
+            disk_meta->setID (db_meta->ID ());
+            disk_meta->updateDatabase (directory);
+        }
+        
+        if (disk_meta)
+            delete disk_meta;
+        
+        if (db_meta)
+            delete db_meta;
+        
+        delete decoder;
+    }
+}
+
 enum MusicFileLocation
 {
     kFileSystem,
     kDatabase,
+    kNeedUpdate,
     kBoth
 };
 
@@ -139,6 +167,18 @@
     }
 }
 
+bool HasFileChanged (const QString &filename, const QString &date_modified)
+{
+    struct stat sbuf;
+    if (stat (filename.ascii (), &sbuf) == 0) {
+        if (sbuf.st_mtime > (time_t)QDateTime::fromString (date_modified, 
+                                                           Qt::ISODate).toTime_t ()) {
+            return true;
+        }
+    }
+    return false;
+}
+
 void SavePending(int pending)
 {
     //  Temporary Hack until mythmusic
@@ -208,7 +248,7 @@
     delete busy;
 
     MSqlQuery query(MSqlQuery::InitCon());
-    query.exec("SELECT filename FROM musicmetadata "
+    query.exec("SELECT filename, date_modified FROM musicmetadata "
                     "WHERE filename NOT LIKE ('%://%');");
 
     int counter = 0;
@@ -224,10 +264,15 @@
             QString name = directory + QString::fromUtf8(query.value(0).toString());
             if (name != QString::null)
             {
-                if ((iter = music_files.find(name)) != music_files.end())
-                    music_files.remove(iter);
-                else
+                if ((iter = music_files.find(name)) != music_files.end()) {
+                    if (HasFileChanged(name, query.value(1).toString())) {
+                        music_files[name] = kNeedUpdate;
+                    } else {
+                        music_files.remove(iter);
+                    }
+                } else {
                     music_files[name] = kDatabase;
+                }
             }
             file_checking->setProgress(++counter);
         }
@@ -238,14 +283,28 @@
 
     file_checking = new MythProgressDialog(QObject::tr("Updating music database"), 
                                            music_files.size());
-
-    QRegExp quote_regex("\"");
+    counter = 0;
+    /*
+      This can be optimised quite a bit by consolidating all commands
+      via a lot of refactoring.
+      
+      1) group all files of the same decoder type, and don't
+      create/delete a Decoder pr. AddFileToDB. Or make Decoders be
+      singletons, it should be a fairly simple change.
+      
+      2) RemoveFileFromDB should group the remove into one big SQL.
+      
+      3) UpdateFileInDB, same as 1.
+    */
+    
     for (iter = music_files.begin(); iter != music_files.end(); iter++)
     {
         if (*iter == kFileSystem)
             AddFileToDB(directory, iter.key());
         else if (*iter == kDatabase)
             RemoveFileFromDB(directory, iter.key ());
+        else if (*iter == kNeedUpdate) 
+            UpdateFileInDB(directory, iter.key ());
 
         file_checking->setProgress(++counter);
     }
@@ -301,6 +360,18 @@
     AllMusic *all_music;
 };
 
+void RebuildMusicTree (MusicData *mdata) {
+    MythBusyDialog busy (QObject::tr("Rebuilding music tree"));
+    busy.start ();
+    mdata->all_music->startLoading ();
+    while (!mdata->all_music->doneLoading ()) {
+        qApp->processEvents ();
+        usleep (50000);
+    }
+    mdata->all_playlists->postLoad();
+    busy.Close ();
+}
+
 void MusicCallback(void *data, QString &selection)
 {
     MusicData *mdata = (MusicData *)data;
@@ -320,8 +391,7 @@
             //  Reconcile with the database
             SearchDir(mdata->startdir);
             //  Tell the metadata to reset itself
-            mdata->all_music->resync();
-            mdata->all_playlists->postLoad();
+            RebuildMusicTree(mdata);
         }
     }
     else if (sel == "settings_scan")
@@ -329,8 +399,7 @@
         if ("" != mdata->startdir)
         {
             SearchDir(mdata->startdir);
-            mdata->all_music->resync();
-            mdata->all_playlists->postLoad();
+            RebuildMusicTree(mdata);
         }
     }
     else if (sel == "music_set_general")
@@ -602,8 +671,7 @@
         // if startRipper returns true, then new files should be present
         // so we should look for them.
         SearchDir(mdata.startdir);
-        mdata.all_music->resync();
-        mdata.all_playlists->postLoad();
+        RebuildMusicTree(&mdata);
     }
     postMusic(&mdata);
 }
diff -ru ../123/mythplugins/mythmusic/mythmusic/metadata.cpp mythplugins/mythmusic/mythmusic/metadata.cpp
--- ../123/mythplugins/mythmusic/mythmusic/metadata.cpp	2005-10-25 23:50:04.000000000 -0700
+++ mythplugins/mythmusic/mythmusic/metadata.cpp	2005-10-26 00:08:57.000000000 -0700
@@ -1,4 +1,5 @@
 #include <iostream> 
+#include <qapplication.h>
 #include <qregexp.h> 
 #include <qdatetime.h>
 #include <qdir.h>
@@ -194,9 +195,10 @@
         return;
 
     query.prepare("INSERT INTO musicmetadata (artist,compilation_artist,album,title,"
-                  "genre,year,tracknum,length,filename,compilation,date_added) VALUES "
+                  "genre,year,tracknum,length,filename,compilation,date_added,"
+                  "date_modified) VALUES "
                   "(:ARTIST, :COMPILATION_ARTIST, :ALBUM, :TITLE, :GENRE, :YEAR, :TRACKNUM, "
-                  ":LENGTH, :FILENAME, :COMPILATION, :DATE_ADDED );");
+                  ":LENGTH, :FILENAME, :COMPILATION, :DATE_ADDED, :DATE_MODIFIED );");
     query.bindValue(":ARTIST", artist.utf8());
     query.bindValue(":COMPILATION_ARTIST", compilation_artist.utf8());
     query.bindValue(":ALBUM", album.utf8());
@@ -207,7 +209,8 @@
     query.bindValue(":LENGTH", length);
     query.bindValue(":FILENAME", sqlfilename.utf8());
     query.bindValue(":COMPILATION", compilation);
-    query.bindValue(":DATE_ADDED", QDate::currentDate());
+    query.bindValue(":DATE_ADDED", QDateTime::currentDateTime());
+    query.bindValue(":DATE_MODIFIED", QDateTime::currentDateTime());
     
     query.exec();
 
@@ -364,7 +367,8 @@
                   "compilation_artist = :COMPILATION_ARTIST, "
                   "title = :TITLE, genre = :GENRE, year = :YEAR, "
                   "tracknum = :TRACKNUM, rating = :RATING, " 
-                  "compilation = :COMPILATION "
+                  "compilation = :COMPILATION, "
+                  "date_modified= :DATE_MODIFIED "
                   "WHERE intid = :ID;");
     query.bindValue(":ARTIST", artist.utf8());
     query.bindValue(":COMPILATION_ARTIST", compilation_artist.utf8());
@@ -375,6 +379,7 @@
     query.bindValue(":TRACKNUM", tracknum);
     query.bindValue(":RATING", rating);
     query.bindValue(":COMPILATION", compilation);
+    query.bindValue(":DATE_MODIFIED", QDateTime::currentDateTime());
     query.bindValue(":ID", id);
 
     if (!query.exec())
@@ -683,8 +688,8 @@
     //  loading and sorting
     //
     
-    metadata_loader = new MetadataLoadingThread(this);
-    metadata_loader->start();
+    metadata_loader = NULL;
+    startLoading ();
 
     all_music.setAutoDelete(true);
     top_nodes.setAutoDelete(true);
@@ -718,6 +723,22 @@
     return false;
 }
 
+bool AllMusic::startLoading () {
+    // Set this to false early rather than letting it be delayed till
+    // the thread calls resync.
+    done_loading = false;
+
+    if (metadata_loader) {
+        cleanOutThreads ();
+        delete metadata_loader;
+    }
+
+    metadata_loader = new MetadataLoadingThread(this);
+    metadata_loader->start ();    
+    
+    return true;
+}
+
 void AllMusic::resync()
 {
     done_loading = false;
@@ -1161,6 +1182,7 @@
         if( *it != "genre"  &&
             *it != "artist" &&
             *it != "splitartist" && 
+            *it != "splitartist1" && 
             *it != "album"  &&
             *it != "title")
         {
diff -ru ../123/mythplugins/mythmusic/mythmusic/metadata.h mythplugins/mythmusic/mythmusic/metadata.h
--- ../123/mythplugins/mythmusic/mythmusic/metadata.h	2005-10-25 20:15:00.000000000 -0700
+++ mythplugins/mythmusic/mythmusic/metadata.h	2005-10-26 10:18:43.086773760 -0700
@@ -274,6 +274,16 @@
     Metadata*   getMetadata(int an_id);
     bool        updateMetadata(int an_id, Metadata *the_track);
     void        save();
+	/** \brief Start loading metadata.
+		Makes the AllMusic object run it's resync in a thread. Once done, it's
+		doneLoading method will return true.
+
+		\note Alternatively, it could be made to emit a signal so the
+		caller won't have to poll for completion.
+
+		\returns true if the loader thread was started
+	*/
+	bool        startLoading ();
     void        resync();   //  After a CD rip, for example
     void        clearCDData();
     void        addCDTrack(Metadata *the_track);
