diff --git a/mythtv/libs/libmyth/programinfo.cpp b/mythtv/libs/libmyth/programinfo.cpp
index 83e0d21..b6c24a1 100644
--- a/mythtv/libs/libmyth/programinfo.cpp
+++ b/mythtv/libs/libmyth/programinfo.cpp
@@ -2678,7 +2678,8 @@ void ProgramInfo::SaveDeletePendingFlag(bool deleteFlag)
     MSqlQuery query(MSqlQuery::InitCon());
 
     query.prepare("UPDATE recorded"
-                  " SET deletepending = :DELETEFLAG"
+                  " SET deletepending = :DELETEFLAG, "
+                  "     duplicate = 0 "
                   " WHERE chanid = :CHANID"
                   " AND starttime = :STARTTIME ;");
     query.bindValue(":CHANID", chanid);
diff --git a/mythtv/libs/libmythtv/eitscanner.cpp b/mythtv/libs/libmythtv/eitscanner.cpp
index 6135e08..cde2f69 100644
--- a/mythtv/libs/libmythtv/eitscanner.cpp
+++ b/mythtv/libs/libmythtv/eitscanner.cpp
@@ -177,7 +177,7 @@ void EITScanner::RescheduleRecordings(void)
         QDateTime::currentDateTime().addSecs(kMinRescheduleInterval);
     resched_lock.unlock();
 
-    ScheduledRecording::signalChange(-1);
+    ScheduledRecording::RescheduleMatch(0, 0, 0, QDateTime(), "EITScanner");
 }
 
 /** \fn EITScanner::StartPassiveScan(ChannelBase*, EITSource*, bool)
diff --git a/mythtv/libs/libmythtv/recordinginfo.cpp b/mythtv/libs/libmythtv/recordinginfo.cpp
index 73cc9ef..2c42e2d 100644
--- a/mythtv/libs/libmythtv/recordinginfo.cpp
+++ b/mythtv/libs/libmythtv/recordinginfo.cpp
@@ -1155,7 +1155,7 @@ void RecordingInfo::ReactivateRecording(void)
     if (!result.exec())
         MythDB::DBError("ReactivateRecording", result);
 
-    ScheduledRecording::signalChange(0);
+    ScheduledRecording::ReschedulePlace("Reactivate");
 }
 
 /**
@@ -1223,7 +1223,7 @@ void RecordingInfo::AddHistory(bool resched, bool forcedup, bool future)
     // The adding of an entry to oldrecorded may affect near-future
     // scheduling decisions, so recalculate if told
     if (resched)
-        ScheduledRecording::signalChange(0);
+        ScheduledRecording::RescheduleCheck(*this, "AddHistory");
 }
 
 /** \fn RecordingInfo::DeleteHistory(void)
@@ -1257,7 +1257,7 @@ void RecordingInfo::DeleteHistory(void)
 
     // The removal of an entry from oldrecorded may affect near-future
     // scheduling decisions, so recalculate
-    ScheduledRecording::signalChange(0);
+    ScheduledRecording::RescheduleCheck(*this, "DeleteHistory");
 }
 
 /** \fn RecordingInfo::ForgetHistory(void)
@@ -1321,7 +1321,7 @@ void RecordingInfo::ForgetHistory(void)
 
     // The removal of an entry from oldrecorded may affect near-future
     // scheduling decisions, so recalculate
-    ScheduledRecording::signalChange(0);
+    ScheduledRecording::RescheduleCheck(*this, "ForgetHistory");
 }
 
 /** \fn RecordingInfo::SetDupHistory(void)
@@ -1347,7 +1347,7 @@ void RecordingInfo::SetDupHistory(void)
     if (!result.exec())
         MythDB::DBError("setDupHistory", result);
 
-    ScheduledRecording::signalChange(0);
+    ScheduledRecording::RescheduleCheck(*this, "SetHistory");
 }
 
 /**
diff --git a/mythtv/libs/libmythtv/recordinginfo.h b/mythtv/libs/libmythtv/recordinginfo.h
index 5ca56bf..4c8378a 100644
--- a/mythtv/libs/libmythtv/recordinginfo.h
+++ b/mythtv/libs/libmythtv/recordinginfo.h
@@ -228,8 +228,6 @@ class MTV_PUBLIC RecordingInfo : public ProgramInfo
     void ApplyTranscoderProfileChange(const QString &profile) const;//pi
     void ApplyTranscoderProfileChangeById(int);
 
-    static void signalChange(int recordid);
-
     RecStatusType oldrecstatus;
     RecStatusType savedrecstatus;
     bool future;
diff --git a/mythtv/libs/libmythtv/recordingrule.cpp b/mythtv/libs/libmythtv/recordingrule.cpp
index f7a9981..907f92b 100644
--- a/mythtv/libs/libmythtv/recordingrule.cpp
+++ b/mythtv/libs/libmythtv/recordingrule.cpp
@@ -8,7 +8,7 @@
 #include "mythcorecontext.h"
 
 // libmythtv
-#include "scheduledrecording.h" // For signalChange()
+#include "scheduledrecording.h" // For RescheduleMatch()
 #include "playgroup.h" // For GetInitialName()
 #include "recordingprofile.h" // For constants
 #include "mythmiscutil.h"
@@ -380,7 +380,8 @@ bool RecordingRule::Save(bool sendSig)
         m_recordID = query.lastInsertId().toInt();
 
     if (sendSig)
-        ScheduledRecording::signalChange(m_recordID);
+        ScheduledRecording::RescheduleMatch(m_recordID, 0, 0, QDateTime(),
+            QString("SaveRule %1").arg(m_title));
 
     return true;
 }
@@ -408,7 +409,8 @@ bool RecordingRule::Delete(bool sendSig)
     }
 
     if (sendSig)
-        ScheduledRecording::signalChange(m_recordID);
+        ScheduledRecording::RescheduleMatch(m_recordID, 0, 0, QDateTime(),
+            QString("DeleteRule %1").arg(m_title));
 
     // Set m_recordID to zero, the rule is no longer in the database so it's
     // not valid. Should you want, this allows a rule to be removed from the
diff --git a/mythtv/libs/libmythtv/scheduledrecording.cpp b/mythtv/libs/libmythtv/scheduledrecording.cpp
index 4e162b2..0c0fa1c 100644
--- a/mythtv/libs/libmythtv/scheduledrecording.cpp
+++ b/mythtv/libs/libmythtv/scheduledrecording.cpp
@@ -9,22 +9,56 @@ ScheduledRecording::~ScheduledRecording()
 {
 }
 
-void ScheduledRecording::signalChange(int recordid)
+void ScheduledRecording::SendReschedule(const QStringList &request)
 {
     if (gCoreContext->IsBackend())
     {
-        MythEvent me(QString("RESCHEDULE_RECORDINGS %1").arg(recordid));
+        MythEvent me(QString("RESCHEDULE_RECORDINGS"), request);
         gCoreContext->dispatch(me);
     }
     else
     {
         QStringList slist;
-        slist << QString("RESCHEDULE_RECORDINGS %1").arg(recordid);
+        slist << QString("RESCHEDULE_RECORDINGS");
+        slist << request;
         if (!gCoreContext->SendReceiveStringList(slist))
             LOG(VB_GENERAL, LOG_ERR,
-                QString("Error rescheduling id %1 in "
-                        "ScheduledRecording::signalChange") .arg(recordid));
+                QString("Error rescheduling %1 in "
+                        "ScheduledRecording::SendReschedule").arg(request[0]));
     }
 }
 
+QStringList ScheduledRecording::BuildMatchRequest(uint recordid, 
+                uint sourceid, uint mplexid, const QDateTime &maxstarttime, 
+                const QString &why)
+{
+    return QStringList(QString("MATCH %1 %2 %3 %4 %5")
+                       .arg(recordid).arg(sourceid).arg(mplexid)
+                       .arg(maxstarttime.isValid() ?
+                            maxstarttime.toString(Qt::ISODate) :
+                            "-")
+                       .arg(why));
+};
+
+QStringList ScheduledRecording::BuildCheckRequest(const RecordingInfo &recinfo,
+                                                  const QString &why)
+{
+    return QStringList(QString("CHECK %1 %2 %3 %4")
+                       .arg(recinfo.GetRecordingStatus())
+                       .arg(recinfo.GetParentRecordingRuleID() ?
+                            recinfo.GetParentRecordingRuleID() :
+                            recinfo.GetRecordingRuleID())
+                       .arg(recinfo.GetFindID())
+                       .arg(why))
+        << recinfo.GetTitle()
+        << recinfo.GetSubtitle()
+        << recinfo.GetDescription()
+        << recinfo.GetProgramID();
+};
+
+QStringList ScheduledRecording::BuildPlaceRequest(const QString &why)
+{
+    return QStringList(QString("PLACE %1").arg(why));
+};
+
 /* vim: set expandtab tabstop=4 shiftwidth=4: */
diff --git a/mythtv/libs/libmythtv/scheduledrecording.h b/mythtv/libs/libmythtv/scheduledrecording.h
index 4a230fb..2f14d2e 100644
--- a/mythtv/libs/libmythtv/scheduledrecording.h
+++ b/mythtv/libs/libmythtv/scheduledrecording.h
@@ -2,18 +2,43 @@
 #define SCHEDULEDRECORDING_H
 
 #include "mythtvexp.h"
+#include "qdatetime.h"
+#include "recordinginfo.h"
 
 class MTV_PUBLIC ScheduledRecording
 {
+    friend class Scheduler;
+
   public:
+    // Use when a recording rule or program data changes.  Use 0 for
+    // recordid when all recordids are potentially affected, Use
+    // invalid starttime and 0 for chanids when not time nor channel
+    // specific.
+    static void RescheduleMatch(uint recordid, uint sourceid, uint mplexid,
+                             const QDateTime &maxstarttime, const QString &why)
+        { SendReschedule(BuildMatchRequest(recordid, sourceid, mplexid,
+                                           maxstarttime, why)); };
+
+    // Use when previous or current recorded duplicate status changes.
+    static void RescheduleCheck(const RecordingInfo &recinfo, 
+                                const QString &why)
+        { SendReschedule(BuildCheckRequest(recinfo, why)); };
+
+    // Use when none of recording rule, program data or duplicate
+    // status changes.
+    static void ReschedulePlace(const QString &why)
+        { SendReschedule(BuildPlaceRequest(why)); };
+
+  private:
     ScheduledRecording();
     ~ScheduledRecording();
 
-    static void signalChange(int recordid);
-    // Use -1 for recordid when all recordids are potentially
-    // affected, such as when the program table is updated.
-    // Use 0 for recordid when a reschdule isn't specific to a single
-    // recordid, such as when a recording type priority is changed.
+    static void SendReschedule(const QStringList &request);
+    static QStringList BuildMatchRequest(uint recordid, uint sourceid, 
+              uint mplexid, const QDateTime &maxstarttime, const QString &why);
+    static QStringList BuildCheckRequest(const RecordingInfo &recinfo,
+                                         const QString &why);
+    static QStringList BuildPlaceRequest(const QString &why);
 };
 
 #endif
diff --git a/mythtv/libs/libmythtv/tv_rec.cpp b/mythtv/libs/libmythtv/tv_rec.cpp
index bf15151..1e88080 100644
--- a/mythtv/libs/libmythtv/tv_rec.cpp
+++ b/mythtv/libs/libmythtv/tv_rec.cpp
@@ -2668,7 +2668,7 @@ void TVRec::NotifySchedulerOfRecording(RecordingInfo *rec)
     rec->AddHistory(false);
 
     // + save RecordingRule so that we get a recordid
-    //   (don't allow signalChange(), avoiding unneeded reschedule)
+    //   (don't allow RescheduleMatch(), avoiding unneeded reschedule)
     rec->GetRecordingRule()->Save(false);
 
     // + save recordid to recorded entry
diff --git a/mythtv/programs/mythbackend/main_helpers.cpp b/mythtv/programs/mythbackend/main_helpers.cpp
index 5017af4..9bcac95 100644
--- a/mythtv/programs/mythbackend/main_helpers.cpp
+++ b/mythtv/programs/mythbackend/main_helpers.cpp
@@ -381,7 +381,8 @@ int handle_command(const MythBackendCommandLineParser &cmdline)
         if (gCoreContext->ConnectToMasterServer())
         {
             LOG(VB_GENERAL, LOG_INFO, "Connected to master for reschedule");
-            ScheduledRecording::signalChange(-1);
+            ScheduledRecording::RescheduleMatch(0, 0, 0, QDateTime(),
+                                                "MythBackendCommand");
             ok = true;
         }
         else
diff --git a/mythtv/programs/mythbackend/mainserver.cpp b/mythtv/programs/mythbackend/mainserver.cpp
index ff002b4..802232c 100644
--- a/mythtv/programs/mythbackend/mainserver.cpp
+++ b/mythtv/programs/mythbackend/mainserver.cpp
@@ -525,10 +525,8 @@ void MainServer::ProcessRequestWork(MythSocket *sock)
     }
     else if (command == "RESCHEDULE_RECORDINGS")
     {
-        if (tokens.size() != 2)
-            LOG(VB_GENERAL, LOG_ERR, "Bad RESCHEDULE_RECORDINGS request");
-        else
-            HandleRescheduleRecordings(tokens[1].toInt(), pbs);
+        listline.pop_front();
+        HandleRescheduleRecordings(listline, pbs);
     }
     else if (command == "FORGET_RECORDING")
     {
@@ -1007,17 +1005,8 @@ void MainServer::customEvent(QEvent *e)
 
         if (me->Message().left(21) == "RESCHEDULE_RECORDINGS" && m_sched)
         {
-            QStringList tokens = me->Message()
-                .split(" ", QString::SkipEmptyParts);
-
-            if (tokens.size() != 2)
-            {
-                LOG(VB_GENERAL, LOG_ERR, "Bad RESCHEDULE_RECORDINGS message");
-                return;
-            }
-
-            int recordid = tokens[1].toInt();
-            m_sched->Reschedule(recordid);
+            QStringList request = me->ExtraDataList();
+            m_sched->Reschedule(request);
             return;
         }
 
@@ -1444,7 +1433,7 @@ void MainServer::HandleAnnounce(QStringList &slist, QStringList commands,
         }
 
         if (!wasAsleep && m_sched)
-            m_sched->Reschedule(0);
+            m_sched->ReschedulePlace("SlaveConnected");
 
         QString message = QString("LOCAL_SLAVE_BACKEND_ONLINE %2")
                                   .arg(commands[2]);
@@ -2001,9 +1990,6 @@ void MainServer::DoDeleteThread(DeleteStruct *ds)
 
     DoDeleteInDB(ds);
 
-    if (pginfo.GetRecordingGroup() != "LiveTV")
-        ScheduledRecording::signalChange(0);
-
     deletelock.unlock();
 
     if (slowDeletes && fd >= 0)
@@ -2513,7 +2499,7 @@ void MainServer::DoHandleDeleteRecording(
         if (forgetHistory)
             recinfo.ForgetHistory();
         else if (m_sched)
-            m_sched->Reschedule(0);
+            m_sched->RescheduleCheck(recinfo, "DoHandleDelete1");
         QStringList outputlist( QString::number(0) );
         SendResponse(pbssock, outputlist);
         return;
@@ -2534,7 +2520,7 @@ void MainServer::DoHandleDeleteRecording(
             else if (m_sched && 
                      recinfo.GetRecordingGroup() != "Deleted" &&
                      recinfo.GetRecordingGroup() != "LiveTV")
-                m_sched->Reschedule(0);
+                m_sched->RescheduleCheck(recinfo, "DoHandleDelete2");
 
             if (pbssock)
             {
@@ -2594,7 +2580,7 @@ void MainServer::DoHandleDeleteRecording(
     else if (m_sched && 
              recinfo.GetRecordingGroup() != "Deleted" &&
              recinfo.GetRecordingGroup() != "LiveTV")
-        m_sched->Reschedule(0);
+        m_sched->RescheduleCheck(recinfo, "DoHandleDelete3");
 
     // Tell MythTV frontends that the recording list needs to be updated.
     if (fileExists || !recinfo.GetFilesize() || forceMetadataDelete)
@@ -2651,12 +2637,13 @@ void MainServer::DoHandleUndeleteRecording(
     SendResponse(pbssock, outputlist);
 }
 
-void MainServer::HandleRescheduleRecordings(int recordid, PlaybackSock *pbs)
+void MainServer::HandleRescheduleRecordings(const QStringList &request, 
+                                            PlaybackSock *pbs)
 {
     QStringList result;
     if (m_sched)
     {
-        m_sched->Reschedule(recordid);
+        m_sched->Reschedule(request);
         result = QStringList( QString::number(1) );
     }
     else
@@ -3151,7 +3138,8 @@ void MainServer::HandleGetPendingRecordings(PlaybackSock *pbs,
                     record->m_recordID = recordid;
                     if (record->Load() &&
                         record->m_searchType == kManualSearch)
-                        HandleRescheduleRecordings(recordid, NULL);
+                        m_sched->RescheduleMatch(recordid, 0, 0, QDateTime(),
+                                                 "Speculation");
                     delete record;
                 }
                 query.prepare("DELETE FROM program WHERE manualid = :RECID;");
@@ -3413,7 +3401,7 @@ void MainServer::HandleLockTuner(PlaybackSock *pbs, int cardid)
                         << query.value(2).toString();
 
                 if (m_sched)
-                    m_sched->Reschedule(0);
+                    m_sched->ReschedulePlace("LockTuner");
 
                 SendResponse(pbssock, strlist);
                 return;
@@ -3459,7 +3447,7 @@ void MainServer::HandleFreeTuner(int cardid, PlaybackSock *pbs)
         LOG(VB_GENERAL, LOG_INFO, msg);
 
         if (m_sched)
-            m_sched->Reschedule(0);
+            m_sched->ReschedulePlace("FreeTuner");
 
         strlist << "OK";
     }
@@ -6224,7 +6212,7 @@ void MainServer::HandleSlaveDisconnectedEvent(const MythEvent &event)
             m_sched->SlaveDisconnected(event.ExtraData(i).toUInt());
 
         if (needsReschedule)
-            m_sched->Reschedule(0);
+            m_sched->ReschedulePlace("SlaveDisconnected");
     }
 }
 
diff --git a/mythtv/programs/mythbackend/mainserver.h b/mythtv/programs/mythbackend/mainserver.h
index 0349f8e..e27c9ae 100644
--- a/mythtv/programs/mythbackend/mainserver.h
+++ b/mythtv/programs/mythbackend/mainserver.h
@@ -163,7 +163,8 @@ class MainServer : public QObject, public MythSocketCBs
     void HandleUndeleteRecording(QStringList &slist, PlaybackSock *pbs);
     void DoHandleUndeleteRecording(RecordingInfo &recinfo, PlaybackSock *pbs);
     void HandleForgetRecording(QStringList &slist, PlaybackSock *pbs);
-    void HandleRescheduleRecordings(int recordid, PlaybackSock *pbs);
+    void HandleRescheduleRecordings(const QStringList &request, 
+                                    PlaybackSock *pbs);
     void HandleGoToSleep(PlaybackSock *pbs);
     void HandleQueryFreeSpace(PlaybackSock *pbs, bool allBackends);
     void HandleQueryFreeSpaceSummary(PlaybackSock *pbs);
diff --git a/mythtv/programs/mythbackend/scheduler.cpp b/mythtv/programs/mythbackend/scheduler.cpp
index 23db70c..469570d 100644
--- a/mythtv/programs/mythbackend/scheduler.cpp
+++ b/mythtv/programs/mythbackend/scheduler.cpp
@@ -400,19 +400,19 @@ bool Scheduler::FillRecordList(void)
 
 /** \fn Scheduler::FillRecordListFromDB(int)
  *  \param recordid Record ID of recording that has changed,
- *                  or -1 if anything might have been changed.
+ *                  or 0 if anything might have been changed.
  */
-void Scheduler::FillRecordListFromDB(int recordid)
+void Scheduler::FillRecordListFromDB(uint recordid)
 {
     struct timeval fillstart, fillend;
-    float matchTime, placeTime;
+    float matchTime, checkTime, placeTime;
 
     MSqlQuery query(dbConn);
     QString thequery;
     QString where = "";
 
     // This will cause our temp copy of recordmatch to be empty
-    if (recordid == -1)
+    if (recordid == 0)
         where = "WHERE recordid IS NULL ";
 
     thequery = QString("CREATE TEMPORARY TABLE recordmatch ") +
@@ -449,17 +449,27 @@ void Scheduler::FillRecordListFromDB(int recordid)
     QMutexLocker locker(&schedLock);
 
     gettimeofday(&fillstart, NULL);
-    UpdateMatches(recordid);
+    UpdateMatches(recordid, 0, 0, QDateTime());
     gettimeofday(&fillend, NULL);
     matchTime = ((fillend.tv_sec - fillstart.tv_sec ) * 1000000 +
                  (fillend.tv_usec - fillstart.tv_usec)) / 1000000.0;
 
+    CreateTempTables();
+
+    gettimeofday(&fillstart, NULL);
+    UpdateDuplicates();
+    gettimeofday(&fillend, NULL);
+    checkTime = ((fillend.tv_sec - fillstart.tv_sec ) * 1000000 +
+                 (fillend.tv_usec - fillstart.tv_usec)) / 1000000.0;
+
     gettimeofday(&fillstart, NULL);
     FillRecordList();
     gettimeofday(&fillend, NULL);
     placeTime = ((fillend.tv_sec - fillstart.tv_sec ) * 1000000 +
                  (fillend.tv_usec - fillstart.tv_usec)) / 1000000.0;
 
+    DeleteTempTables();
+
     MSqlQuery queryDrop(dbConn);
     queryDrop.prepare("DROP TABLE recordmatch;");
     if (!queryDrop.exec())
@@ -469,9 +479,11 @@ void Scheduler::FillRecordListFromDB(int recordid)
     }
 
     QString msg;
-    msg.sprintf("Speculative scheduled %d items in "
-                "%.1f = %.2f match + %.2f place", (int)reclist.size(),
-                matchTime + placeTime, matchTime, placeTime);
+    msg.sprintf("Speculative scheduled %d items in %.1f "
+                "= %.2f match + %.2f check + %.2f place", 
+                (int)reclist.size(),
+                matchTime + checkTime + placeTime, 
+                matchTime, checkTime, placeTime);
     LOG(VB_GENERAL, LOG_INFO, msg);
 }
 
@@ -593,7 +605,7 @@ void Scheduler::UpdateRecStatus(RecordingInfo *pginfo)
                 p->AddHistory(false);
                 if (resched)
                 {
-                    reschedQueue.enqueue(0);
+                    EnqueueCheck(*p, "UpdateRecStatus1");
                     reschedWait.wakeOne();
                 }
                 else
@@ -643,7 +655,7 @@ void Scheduler::UpdateRecStatus(uint cardid, uint chanid,
                 p->AddHistory(false);
                 if (resched)
                 {
-                    reschedQueue.enqueue(0);
+                    EnqueueCheck(*p, "UpdateRecStatus2");
                     reschedWait.wakeOne();
                 }
                 else
@@ -665,7 +677,7 @@ bool Scheduler::ChangeRecordingEnd(RecordingInfo *oldp, RecordingInfo *newp)
         return false;
 
     RecordingType oldrectype = oldp->GetRecordingRuleType();
-    int oldrecordid = oldp->GetRecordingRuleID();
+    uint oldrecordid = oldp->GetRecordingRuleID();
     QDateTime oldrecendts = oldp->GetRecordingEndTime();
 
     oldp->SetRecordingRuleType(newp->GetRecordingRuleType());
@@ -1613,16 +1625,10 @@ void Scheduler::GetAllScheduled(QStringList &strList)
     }
 }
 
-void Scheduler::Reschedule(int recordid)
+void Scheduler::Reschedule(const QStringList &request)
 {
     QMutexLocker locker(&schedLock);
-
-    if (recordid == -1)
-        reschedQueue.clear();
-
-    if (recordid != 0 || reschedQueue.empty())
-        reschedQueue.enqueue(recordid);
-
+    reschedQueue.enqueue(request);
     reschedWait.wakeOne();
 }
 
@@ -1661,7 +1667,8 @@ void Scheduler::AddRecording(const RecordingInfo &pi)
     new_pi->GetRecordingRule();
 
     // Trigger reschedule..
-    reschedQueue.enqueue(pi.GetRecordingRuleID());
+    EnqueueMatch(pi.GetRecordingRuleID(), 0, 0, QDateTime(),
+                 QString("AddRecording %1").arg(pi.GetTitle()));
     reschedWait.wakeOne();
 }
 
@@ -1743,7 +1750,7 @@ void Scheduler::OldRecordedFixups(void)
     // during normal processing.
     query.prepare("UPDATE oldrecorded SET future = 0 "
                   "WHERE future > 0 AND "
-                  "      endtime < (NOW() - INTERVAL 8 HOUR)");
+                  "      endtime < (NOW() - INTERVAL 475 MINUTE)");
     if (!query.exec())
         MythDB::DBError("UpdateFuture", query);
 }
@@ -1768,7 +1775,7 @@ void Scheduler::run(void)
     QMutexLocker lockit(&schedLock);
 
     reschedQueue.clear();
-    reschedQueue.enqueue(-1);
+    EnqueueMatch(0, 0, 0, QDateTime(), "SchedulerInit");
 
     int       prerollseconds  = 0;
     int       wakeThreshold   = 300;
@@ -1992,36 +1999,160 @@ int Scheduler::CalcTimeToNextHandleRecordingEvent(
     return min(msecs, max_sleep);
 }
 
+void Scheduler::ResetDuplicates(uint recordid, uint findid, 
+                                const QString &title, const QString &subtitle,
+                                const QString &descrip, 
+                                const QString &programid)
+{
+    MSqlQuery query(dbConn);
+    QString filterClause;
+    MSqlBindings bindings;
+
+    // "**any**" is special value set in ProgLister::DeleteOldSeries()
+    if (programid != "**any**")
+    {
+        filterClause = "AND (0 ";
+        if (!subtitle.isEmpty())
+        {
+            // Need to check both for kDupCheckSubThenDesc
+            filterClause += "OR p.subtitle = :SUBTITLE "
+                            "OR p.description = :SUBTITLE ";
+            bindings[":SUBTITLE"] = subtitle;
+        }
+        if (!descrip.isEmpty())
+        {
+            // Need to check both for kDupCheckSubThenDesc
+            filterClause += "OR p.description = :DESCRIP "
+                            "OR p.subtitle = :DESCRIP ";
+            bindings[":DESCRIP"] = descrip;
+        }
+        if (!programid.isEmpty())
+        {
+            filterClause += "OR p.programid = :PROGRAMID ";
+            bindings[":PROGRAMID"] = programid;
+        }
+        filterClause += ") ";
+    }
+
+    query.prepare(QString("UPDATE recordmatch rm "
+                          "INNER JOIN %1 r "
+                          "      ON rm.recordid = r.recordid "
+                          "INNER JOIN program p "
+                          "      ON rm.chanid = p.chanid "
+                          "         AND rm.starttime = p.starttime "
+                          "         AND rm.manualid = p.manualid "
+                          "SET oldrecduplicate = -1 "
+                          "WHERE p.title = :TITLE"
+                          "      AND p.generic = 0 "
+                          "      AND r.type NOT IN (%2, %3, %4) ")
+                  .arg(recordTable)
+                  .arg(kSingleRecord)
+                  .arg(kOverrideRecord)
+                  .arg(kDontRecord)
+                  + filterClause);
+    query.bindValue(":TITLE", title);
+    MSqlBindings::const_iterator it;
+    for (it = bindings.begin(); it != bindings.end(); ++it)
+        query.bindValue(it.key(), it.value());
+    if (!query.exec())
+        MythDB::DBError("ResetDuplicates1", query);
+
+    if (findid && programid != "**any**")
+    {
+        query.prepare("UPDATE recordmatch rm "
+                      "SET oldrecduplicate = -1 "
+                      "WHERE rm.recordid = :RECORDID "
+                      "      AND rm.findid = :FINDID");
+        query.bindValue("RECORDID", recordid);
+        query.bindValue("FINDID", findid);
+        if (!query.exec())
+            MythDB::DBError("ResetDuplicates2", query);
+    }
+ }
+
 bool Scheduler::HandleReschedule(void)
 {
     // We might have been inactive for a long time, so make
     // sure our DB connection is fresh before continuing.
     dbConn = MSqlQuery::SchedCon();
 
-    struct timeval fillstart;
+    struct timeval fillstart, fillend;
+    float matchTime, checkTime, placeTime;
+
     gettimeofday(&fillstart, NULL);
     QString msg;
     bool deleteFuture = false;
+    bool runCheck = false;
 
     while (!reschedQueue.empty())
     {
-        int recordid = reschedQueue.dequeue();
+        QStringList request = reschedQueue.dequeue();
+        QStringList tokens;
+        if (request.size() >= 1)
+            tokens = request[0].split(' ', QString::SkipEmptyParts);
 
-        LOG(VB_GENERAL, LOG_INFO, QString("Reschedule requested for id %1.")
-                .arg(recordid));
+        if (request.size() < 1 || tokens.size() < 1)
+        {
+            LOG(VB_GENERAL, LOG_ERR, "Empty Reschedule request received");
+            return false;
+        }
 
-        if (recordid != 0)
+        LOG(VB_GENERAL, LOG_INFO, QString("Reschedule requested for %1 %2")
+            .arg(request[0]).arg((request.size() > 1) ? request[1] : ""));
+
+        if (tokens[0] == "MATCH")
         {
-            if (recordid == -1)
-                reschedQueue.clear();
+            if (tokens.size() < 5)
+            {
+                LOG(VB_GENERAL, LOG_ERR, 
+                    QString("Invalid RescheduleMatch request received (%1)")
+                    .arg(request[0]));
+                continue;
+            }
 
+            uint recordid = tokens[1].toUInt();
+            uint sourceid = tokens[2].toUInt();
+            uint mplexid = tokens[3].toUInt();
+            QDateTime maxstarttime = 
+                QDateTime::fromString(tokens[4], Qt::ISODate);
             deleteFuture = true;
+            runCheck = true;
             schedLock.unlock();
             recordmatchLock.lock();
-            UpdateMatches(recordid);
+            UpdateMatches(recordid, sourceid, mplexid, maxstarttime);
             recordmatchLock.unlock();
             schedLock.lock();
         }
+        else if (tokens[0] == "CHECK")
+        {
+            if (tokens.size() < 4 || request.size() < 5)
+            {
+                LOG(VB_GENERAL, LOG_ERR, 
+                    QString("Invalid RescheduleCheck request received (%1)")
+                    .arg(request[0]));
+                continue;
+            }
+
+            uint recordid = tokens[2].toUInt();
+            uint findid = tokens[3].toUInt();
+            QString title = request[1];
+            QString subtitle = request[2];
+            QString descrip = request[3];
+            QString programid = request[4];
+            runCheck = true;
+            schedLock.unlock();
+            recordmatchLock.lock();
+            ResetDuplicates(recordid, findid, title, subtitle, descrip, 
+                            programid);
+            recordmatchLock.unlock();
+            schedLock.lock();
+        }
+        else if (tokens[0] != "PLACE")
+        {
+            LOG(VB_GENERAL, LOG_ERR, 
+                QString("Unknown Reschedule request received (%1)")
+                .arg(request[0]));
+        }
     }
 
     // Delete future oldrecorded entries that no longer
@@ -2039,15 +2170,27 @@ bool Scheduler::HandleReschedule(void)
             MythDB::DBError("DeleteFuture", query);
     }
 
-    struct timeval fillend;
     gettimeofday(&fillend, NULL);
+    matchTime = ((fillend.tv_sec - fillstart.tv_sec ) * 1000000 +
+                 (fillend.tv_usec - fillstart.tv_usec)) / 1000000.0;
+
+    CreateTempTables();
 
-    float matchTime = ((fillend.tv_sec - fillstart.tv_sec ) * 1000000 +
-                       (fillend.tv_usec - fillstart.tv_usec)) / 1000000.0;
+    gettimeofday(&fillstart, NULL);
+    if (runCheck)
+        UpdateDuplicates();
+    gettimeofday(&fillend, NULL);
+    checkTime = ((fillend.tv_sec - fillstart.tv_sec ) * 1000000 +
+                 (fillend.tv_usec - fillstart.tv_usec)) / 1000000.0;
 
     gettimeofday(&fillstart, NULL);
     bool worklistused = FillRecordList();
     gettimeofday(&fillend, NULL);
+    placeTime = ((fillend.tv_sec - fillstart.tv_sec ) * 1000000 +
+                 (fillend.tv_usec - fillstart.tv_usec)) / 1000000.0;
+
+    DeleteTempTables();
+
     if (worklistused)
     {
         UpdateNextRecord();
@@ -2056,16 +2199,14 @@ bool Scheduler::HandleReschedule(void)
     else
     {
         LOG(VB_GENERAL, LOG_INFO, "Reschedule interrupted, will retry");
-        reschedQueue.enqueue(0);
+        EnqueuePlace("Interrupted");
         return false;
     }
 
-    float placeTime = ((fillend.tv_sec - fillstart.tv_sec ) * 1000000 +
-                       (fillend.tv_usec - fillstart.tv_usec)) / 1000000.0;
-
-    msg.sprintf("Scheduled %d items in %.1f = %.2f match + %.2f place",
-                (int)reclist.size(), matchTime + placeTime, matchTime,
-                placeTime);
+    msg.sprintf("Scheduled %d items in %.1f "
+                "= %.2f match + %.2f check + %.2f place",
+                (int)reclist.size(), matchTime + checkTime + placeTime, 
+                matchTime, checkTime, placeTime);
     LOG(VB_GENERAL, LOG_INFO, msg);
 
     fsInfoCacheFillTime = QDateTime::currentDateTime().addSecs(-1000);
@@ -2216,7 +2357,7 @@ void Scheduler::HandleWakeSlave(RecordingInfo &ri, int prerollseconds)
                 .arg(nexttv->GetHostName()).arg(ri.GetTitle()));
 
         if (!WakeUpSlave(nexttv->GetHostName()))
-            reschedQueue.enqueue(0);
+            EnqueuePlace("HandleWakeSlave1");
     }
     else if ((nexttv->IsWaking()) &&
              ((secsleft - prerollseconds) < 210) &&
@@ -2229,7 +2370,7 @@ void Scheduler::HandleWakeSlave(RecordingInfo &ri, int prerollseconds)
                 .arg(nexttv->GetHostName()));
 
         if (!WakeUpSlave(nexttv->GetHostName(), false))
-            reschedQueue.enqueue(0);
+            EnqueuePlace("HandleWakeSlave2");
     }
     else if ((nexttv->IsWaking()) &&
              ((secsleft - prerollseconds) < 150) &&
@@ -2249,7 +2390,7 @@ void Scheduler::HandleWakeSlave(RecordingInfo &ri, int prerollseconds)
                 (*it)->SetSleepStatus(sStatus_Undefined);
         }
 
-        reschedQueue.enqueue(0);
+        EnqueuePlace("HandleWakeSlave3");
     }
 }
 
@@ -2287,7 +2428,7 @@ bool Scheduler::HandleRecording(
             livetvTime = (livetvTime < nextrectime) ?
                 nextrectime : livetvTime;
 
-            reschedQueue.enqueue(0);
+            EnqueuePlace("PrepareToRecord");
         }
     }
 
@@ -2370,7 +2511,7 @@ bool Scheduler::HandleRecording(
                     enc->SetSleepStatus(sStatus_Undefined);
             }
 
-            reschedQueue.enqueue(0);
+            EnqueuePlace("SlaveNotAwake");
         }
 
         return false;
@@ -3029,7 +3170,7 @@ void Scheduler::WakeUpSlaves(void)
     }
 }
 
-void Scheduler::UpdateManuals(int recordid)
+void Scheduler::UpdateManuals(uint recordid)
 {
     MSqlQuery query(dbConn);
 
@@ -3108,10 +3249,10 @@ void Scheduler::UpdateManuals(int recordid)
             if (weekday && startdt.date().dayOfWeek() >= 6)
                 continue;
 
-            query.prepare("REPLACE INTO program (chanid,starttime,endtime,"
-                          " title,subtitle,manualid) "
-                          "VALUES (:CHANID,:STARTTIME,:ENDTIME,:TITLE,"
-                          " :SUBTITLE,:RECORDID)");
+            query.prepare("REPLACE INTO program (chanid, starttime, endtime,"
+                          " title, subtitle, manualid, generic) "
+                          "VALUES (:CHANID, :STARTTIME, :ENDTIME, :TITLE,"
+                          " :SUBTITLE, :RECORDID, 1)");
             query.bindValue(":CHANID", chanidlist[i]);
             query.bindValue(":STARTTIME", startdt);
             query.bindValue(":ENDTIME", startdt.addSecs(duration * 60));
@@ -3128,7 +3269,7 @@ void Scheduler::UpdateManuals(int recordid)
     }
 }
 
-void Scheduler::BuildNewRecordsQueries(int recordid, QStringList &from,
+void Scheduler::BuildNewRecordsQueries(uint recordid, QStringList &from,
                                        QStringList &where,
                                        MSqlBindings &bindings)
 {
@@ -3138,7 +3279,7 @@ void Scheduler::BuildNewRecordsQueries(int recordid, QStringList &from,
 
     query = QString("SELECT recordid,search,subtitle,description "
                     "FROM %1 WHERE search <> %2 AND "
-                    "(recordid = %3 OR %4 = -1) ")
+                    "(recordid = %3 OR %4 = 0) ")
         .arg(recordTable).arg(kNoSearch).arg(recordid).arg(recordid);
 
     result.prepare(query);
@@ -3231,10 +3372,10 @@ void Scheduler::BuildNewRecordsQueries(int recordid, QStringList &from,
         count++;
     }
 
-    if (recordid == -1 || from.count() == 0)
+    if (recordid == 0 || from.count() == 0)
     {
         QString recidmatch = "";
-        if (recordid != -1)
+        if (recordid != 0)
             recidmatch = "RECTABLE.recordid = :NRRECORDID AND ";
         QString s1 = recidmatch +
             "RECTABLE.search = :NRST AND "
@@ -3253,54 +3394,95 @@ void Scheduler::BuildNewRecordsQueries(int recordid, QStringList &from,
         from << "";
         where << s2;
         bindings[":NRST"] = kNoSearch;
-        if (recordid != -1)
+        if (recordid != 0)
             bindings[":NRRECORDID"] = recordid;
     }
 }
 
-void Scheduler::UpdateMatches(int recordid) {
-    struct timeval dbstart, dbend;
+static QString progdupinit = QString(
+"(CASE "
+"  WHEN RECTABLE.type IN (%1, %2, %3) THEN  0 "
+"  WHEN RECTABLE.type IN (%4, %5, %6) THEN  -1 "
+"  ELSE (program.generic - 1) "
+" END) ")
+    .arg(kSingleRecord).arg(kOverrideRecord).arg(kDontRecord)
+    .arg(kFindOneRecord).arg(kFindDailyRecord).arg(kFindWeeklyRecord);
 
-    if (recordid == 0)
-        return;
+static QString progfindid = QString(
+"(CASE RECTABLE.type "
+"  WHEN %1 "
+"   THEN RECTABLE.findid "
+"  WHEN %2 "
+"   THEN to_days(date_sub(program.starttime, interval "
+"                time_format(RECTABLE.findtime, '%H:%i') hour_minute)) "
+"  WHEN %3 "
+"   THEN floor((to_days(date_sub(program.starttime, interval "
+"               time_format(RECTABLE.findtime, '%H:%i') hour_minute)) - "
+"               RECTABLE.findday)/7) * 7 + RECTABLE.findday "
+"  WHEN %4 "
+"   THEN RECTABLE.findid "
+"  ELSE 0 "
+" END) ")
+        .arg(kFindOneRecord)
+        .arg(kFindDailyRecord)
+        .arg(kFindWeeklyRecord)
+        .arg(kOverrideRecord);
+
+void Scheduler::UpdateMatches(uint recordid, uint sourceid, uint mplexid,
+                              const QDateTime maxstarttime) {
+    struct timeval dbstart, dbend;
 
     MSqlQuery query(dbConn);
+    MSqlBindings bindings;
+    QString deleteClause;
+    QString filterClause = QString(" AND program.endtime > "
+                                   "(NOW() - INTERVAL 480 MINUTE)");
 
-    if (recordid == -1)
-        query.prepare("DELETE FROM recordmatch");
-    else
+    if (recordid)
     {
-        query.prepare("DELETE FROM recordmatch WHERE recordid = :RECORDID");
-        query.bindValue(":RECORDID", recordid);
+        deleteClause += " AND recordmatch.recordid = :RECORDID";
+        bindings[":RECORDID"] = recordid;
     }
-
-    if (!query.exec())
+    if (sourceid)
     {
-        MythDB::DBError("UpdateMatches", query);
-        return;
+        deleteClause += " AND channel.sourceid = :SOURCEID";
+        filterClause += " AND channel.sourceid = :SOURCEID";
+        bindings[":SOURCEID"] = sourceid;
     }
-
-    if (recordid == -1)
-        query.prepare("DELETE FROM program WHERE manualid <> 0");
-    else
+    if (mplexid)
     {
-        query.prepare("DELETE FROM program WHERE manualid = :RECORDID");
-        query.bindValue(":RECORDID", recordid);
+        deleteClause += " AND channel.mplexid = :MPLEXID";
+        filterClause += " AND channel.mplexid = :MPLEXID";
+        bindings[":MPLEXID"] = mplexid;
     }
+    if (maxstarttime.isValid())
+    {
+        deleteClause += " AND recordmatch.starttime <= :MAXSTARTTIME";
+        filterClause += " AND program.starttime <= :MAXSTARTTIME";
+        bindings[":MAXSTARTTIME"] = maxstarttime;
+    }
+
+    query.prepare(QString("DELETE recordmatch FROM recordmatch, channel "
+                          "WHERE recordmatch.chanid = channel.chanid")
+                  + deleteClause);
+    MSqlBindings::const_iterator it;
+    for (it = bindings.begin(); it != bindings.end(); ++it)
+        query.bindValue(it.key(), it.value());
     if (!query.exec())
     {
-        MythDB::DBError("UpdateMatches", query);
+        MythDB::DBError("UpdateMatches1", query);
         return;
     }
+    if (recordid)
+        bindings.remove(":RECORDID");
 
-    QString filterClause;
     query.prepare("SELECT filterid, clause FROM recordfilter "
                   "WHERE filterid >= 0 AND filterid < :NUMFILTERS AND "
                   "      TRIM(clause) <> ''");
     query.bindValue(":NUMFILTERS", RecordingRule::kNumFilters);
     if (!query.exec())
     {
-        MythDB::DBError("UpdateMatches", query);
+        MythDB::DBError("UpdateMatches2", query);
         return;
     }
     while (query.next())
@@ -3315,7 +3497,7 @@ void Scheduler::UpdateMatches(int recordid) {
     query.bindValue(":FINDONE", kFindOneRecord);
     if (!query.exec())
     {
-        MythDB::DBError("UpdateMatches", query);
+        MythDB::DBError("UpdateMatches3", query);
         return;
     }
     else if (query.size())
@@ -3327,12 +3509,11 @@ void Scheduler::UpdateMatches(int recordid) {
         query.bindValue(":FINDID", findtoday);
         query.bindValue(":FINDONE", kFindOneRecord);
         if (!query.exec())
-            MythDB::DBError("UpdateMatches", query);
+            MythDB::DBError("UpdateMatches4", query);
     }
 
     int clause;
     QStringList fromclauses, whereclauses;
-    MSqlBindings bindings;
 
     BuildNewRecordsQueries(recordid, fromclauses, whereclauses, bindings);
 
@@ -3349,9 +3530,11 @@ void Scheduler::UpdateMatches(int recordid) {
     for (clause = 0; clause < fromclauses.count(); ++clause)
     {
         QString query = QString(
-"REPLACE INTO recordmatch (recordid, chanid, starttime, manualid) "
+"REPLACE INTO recordmatch (recordid, chanid, starttime, manualid, "
+"                          oldrecduplicate, findid) "
 "SELECT RECTABLE.recordid, program.chanid, program.starttime, "
-" IF(search = %1, RECTABLE.recordid, 0) ").arg(kManualSearch) + QString(
+" IF(search = %1, RECTABLE.recordid, 0), ").arg(kManualSearch) +
+            progdupinit + ", " + progfindid + QString(
 "FROM (RECTABLE, program INNER JOIN channel "
 "      ON channel.chanid = program.chanid) ") + fromclauses[clause] + QString(
 " WHERE ") + whereclauses[clause] +
@@ -3395,12 +3578,7 @@ void Scheduler::UpdateMatches(int recordid) {
             .arg(kWeekslotRecord)
             .arg(kNotRecording);
 
-        while (1)
-        {
-            int i = query.indexOf("RECTABLE");
-            if (i == -1) break;
-            query = query.replace(i, strlen("RECTABLE"), recordTable);
-        }
+        query.replace("RECTABLE", recordTable);
 
         LOG(VB_SCHEDULE, LOG_INFO, QString(" |-- Start DB Query %1...")
                 .arg(clause));
@@ -3409,7 +3587,6 @@ void Scheduler::UpdateMatches(int recordid) {
         MSqlQuery result(dbConn);
         result.prepare(query);
 
-        MSqlBindings::const_iterator it;
         for (it = bindings.begin(); it != bindings.end(); ++it)
         {
             if (query.contains(it.key()))
@@ -3435,6 +3612,178 @@ void Scheduler::UpdateMatches(int recordid) {
     LOG(VB_SCHEDULE, LOG_INFO, " +-- Done.");
 }
 
+void Scheduler::CreateTempTables(void)
+{
+    MSqlQuery result(dbConn);
+
+    if (recordTable == "record")
+    {
+        result.prepare("DROP TABLE IF EXISTS sched_temp_record;");
+        if (!result.exec())
+        {
+            MythDB::DBError("Dropping sched_temp_record table", result);
+            return;
+        }
+        result.prepare("CREATE TEMPORARY TABLE sched_temp_record "
+                           "LIKE record;");
+        if (!result.exec())
+        {
+            MythDB::DBError("Creating sched_temp_record table", result);
+            return;
+        }
+        result.prepare("INSERT sched_temp_record SELECT * from record;");
+        if (!result.exec())
+        {
+            MythDB::DBError("Populating sched_temp_record table", result);
+            return;
+        }
+    }
+
+    result.prepare("DROP TABLE IF EXISTS sched_temp_recorded;");
+    if (!result.exec())
+    {
+        MythDB::DBError("Dropping sched_temp_recorded table", result);
+        return;
+    }
+    result.prepare("CREATE TEMPORARY TABLE sched_temp_recorded "
+                       "LIKE recorded;");
+    if (!result.exec())
+    {
+        MythDB::DBError("Creating sched_temp_recorded table", result);
+        return;
+    }
+    result.prepare("INSERT sched_temp_recorded SELECT * from recorded;");
+    if (!result.exec())
+    {
+        MythDB::DBError("Populating sched_temp_recorded table", result);
+        return;
+    }
+}
+
+void Scheduler::DeleteTempTables(void)
+{
+    MSqlQuery result(dbConn);
+
+    if (recordTable == "record")
+    {
+        result.prepare("DROP TABLE IF EXISTS sched_temp_record;");
+        if (!result.exec())
+            MythDB::DBError("DeleteTempTables sched_temp_record", result);
+    }
+
+    result.prepare("DROP TABLE IF EXISTS sched_temp_recorded;");
+    if (!result.exec())
+        MythDB::DBError("DeleteTempTables drop table", result);
+}
+
+void Scheduler::UpdateDuplicates(void)
+{
+    QString schedTmpRecord = recordTable;
+    if (schedTmpRecord == "record")
+        schedTmpRecord = "sched_temp_record";
+
+    QString rmquery = QString(
+"UPDATE recordmatch "
+" INNER JOIN RECTABLE ON (recordmatch.recordid = RECTABLE.recordid) "
+" INNER JOIN program p ON (recordmatch.chanid = p.chanid AND "
+"                          recordmatch.starttime = p.starttime AND "
+"                          recordmatch.manualid = p.manualid) "
+" LEFT JOIN oldrecorded ON "
+"  ( "
+"    RECTABLE.dupmethod > 1 AND "
+"    oldrecorded.duplicate <> 0 AND "
+"    p.title = oldrecorded.title AND "
+"    p.generic = 0 "
+"     AND "
+"     ( "
+"      (p.programid <> '' "
+"       AND p.programid = oldrecorded.programid) "
+"      OR "
+"      ( ") +
+        (ProgramInfo::UsingProgramIDAuthority() ?
+"       (p.programid = '' OR oldrecorded.programid = '' OR "
+"         LEFT(p.programid, LOCATE('/', p.programid)) <> "
+"         LEFT(oldrecorded.programid, LOCATE('/', oldrecorded.programid))) " :
+"       (p.programid = '' OR oldrecorded.programid = '') " )
+        + QString(
+"       AND "
+"       (((RECTABLE.dupmethod & 0x02) = 0) OR (p.subtitle <> '' "
+"          AND p.subtitle = oldrecorded.subtitle)) "
+"       AND "
+"       (((RECTABLE.dupmethod & 0x04) = 0) OR (p.description <> '' "
+"          AND p.description = oldrecorded.description)) "
+"       AND "
+"       (((RECTABLE.dupmethod & 0x08) = 0) OR "
+"          (p.subtitle <> '' AND "
+"             (p.subtitle = oldrecorded.subtitle OR "
+"              (oldrecorded.subtitle = '' AND "
+"               p.subtitle = oldrecorded.description))) OR "
+"          (p.subtitle = '' AND p.description <> '' AND "
+"             (p.description = oldrecorded.subtitle OR "
+"              (oldrecorded.subtitle = '' AND "
+"               p.description = oldrecorded.description)))) "
+"      ) "
+"     ) "
+"  ) "
+" LEFT JOIN sched_temp_recorded recorded ON "
+"  ( "
+"    RECTABLE.dupmethod > 1 AND "
+"    recorded.duplicate <> 0 AND "
+"    p.title = recorded.title AND "
+"    p.generic = 0 AND "
+"    recorded.recgroup NOT IN ('LiveTV','Deleted') "
+"     AND "
+"     ( "
+"      (p.programid <> '' "
+"       AND p.programid = recorded.programid) "
+"      OR "
+"      ( ") +
+        (ProgramInfo::UsingProgramIDAuthority() ?
+"       (p.programid = '' OR recorded.programid = '' OR "
+"         LEFT(p.programid, LOCATE('/', p.programid)) <> "
+"         LEFT(recorded.programid, LOCATE('/', recorded.programid))) " :
+"       (p.programid = '' OR recorded.programid = '') ")
+        + QString(
+"       AND "
+"       (((RECTABLE.dupmethod & 0x02) = 0) OR (p.subtitle <> '' "
+"          AND p.subtitle = recorded.subtitle)) "
+"       AND "
+"       (((RECTABLE.dupmethod & 0x04) = 0) OR (p.description <> '' "
+"          AND p.description = recorded.description)) "
+"       AND "
+"       (((RECTABLE.dupmethod & 0x08) = 0) OR "
+"          (p.subtitle <> '' AND "
+"             (p.subtitle = recorded.subtitle OR "
+"              (recorded.subtitle = '' AND "
+"               p.subtitle = recorded.description))) OR "
+"          (p.subtitle = '' AND p.description <> '' AND "
+"             (p.description = recorded.subtitle OR "
+"              (recorded.subtitle = '' AND "
+"               p.description = recorded.description)))) "
+"      ) "
+"     ) "
+"  ) "
+" LEFT JOIN oldfind ON "
+"  (oldfind.recordid = recordmatch.recordid AND "
+"   oldfind.findid = recordmatch.findid) "
+" SET oldrecduplicate = (oldrecorded.endtime IS NOT NULL), "
+"     recduplicate = (recorded.endtime IS NOT NULL), "
+"     findduplicate = (oldfind.findid IS NOT NULL), "
+"     oldrecstatus = oldrecorded.recstatus "
+" WHERE p.endtime >= (NOW() - INTERVAL 480 MINUTE) "
+"       AND oldrecduplicate = -1 "
+);
+    rmquery.replace("RECTABLE", schedTmpRecord);
+
+    MSqlQuery result(dbConn);
+    result.prepare(rmquery);
+    if (!result.exec())
+    {
+        MythDB::DBError("UpdateDuplicates", result);
+        return;
+    }
+}
+
 void Scheduler::AddNewRecords(void)
 {
     struct timeval dbstart, dbend;
@@ -3548,65 +3897,10 @@ void Scheduler::AddNewRecords(void)
         "(FIND_IN_SET('VISUALIMPAIR', program.audioprop) > 0) * %1").arg(adpriority);
 
     QString schedTmpRecord = recordTable;
-
-    MSqlQuery result(dbConn);
-
     if (schedTmpRecord == "record")
-    {
         schedTmpRecord = "sched_temp_record";
 
-        result.prepare("DROP TABLE IF EXISTS sched_temp_record;");
-
-        if (!result.exec())
-        {
-            MythDB::DBError("Dropping sched_temp_record table", result);
-            return;
-        }
-
-        result.prepare("CREATE TEMPORARY TABLE sched_temp_record "
-                           "LIKE record;");
-
-        if (!result.exec())
-        {
-            MythDB::DBError("Creating sched_temp_record table",
-                                 result);
-            return;
-        }
-
-        result.prepare("INSERT sched_temp_record SELECT * from record;");
-
-        if (!result.exec())
-        {
-            MythDB::DBError("Populating sched_temp_record table",
-                                 result);
-            return;
-        }
-    }
-
-    result.prepare("DROP TABLE IF EXISTS sched_temp_recorded;");
-
-    if (!result.exec())
-    {
-        MythDB::DBError("Dropping sched_temp_recorded table", result);
-        return;
-    }
-
-    result.prepare("CREATE TEMPORARY TABLE sched_temp_recorded "
-                       "LIKE recorded;");
-
-    if (!result.exec())
-    {
-        MythDB::DBError("Creating sched_temp_recorded table", result);
-        return;
-    }
-
-    result.prepare("INSERT sched_temp_recorded SELECT * from recorded;");
-
-    if (!result.exec())
-    {
-        MythDB::DBError("Populating sched_temp_recorded table", result);
-        return;
-    }
+    MSqlQuery result(dbConn);
 
     result.prepare(QString("SELECT recpriority, selectclause FROM %1;")
                            .arg(priorityTable));
@@ -3630,122 +3924,8 @@ void Scheduler::AddNewRecords(void)
     }
     pwrpri += QString(" AS powerpriority ");
 
-    QString progfindid = QString(
-"(CASE RECTABLE.type "
-"  WHEN %1 "
-"   THEN RECTABLE.findid "
-"  WHEN %2 "
-"   THEN to_days(date_sub(program.starttime, interval "
-"                time_format(RECTABLE.findtime, '%H:%i') hour_minute)) "
-"  WHEN %3 "
-"   THEN floor((to_days(date_sub(program.starttime, interval "
-"               time_format(RECTABLE.findtime, '%H:%i') hour_minute)) - "
-"               RECTABLE.findday)/7) * 7 + RECTABLE.findday "
-"  WHEN %4 "
-"   THEN RECTABLE.findid "
-"  ELSE 0 "
-" END) ")
-        .arg(kFindOneRecord)
-        .arg(kFindDailyRecord)
-        .arg(kFindWeeklyRecord)
-        .arg(kOverrideRecord);
-
-    QString rmquery = QString(
-"UPDATE recordmatch "
-" INNER JOIN RECTABLE ON (recordmatch.recordid = RECTABLE.recordid) "
-" INNER JOIN program ON (recordmatch.chanid = program.chanid AND "
-"                        recordmatch.starttime = program.starttime AND "
-"                        recordmatch.manualid = program.manualid) "
-" LEFT JOIN oldrecorded ON "
-"  ( "
-"    RECTABLE.dupmethod > 1 AND "
-"    oldrecorded.duplicate <> 0 AND "
-"    program.title = oldrecorded.title AND "
-"    program.generic = 0 "
-"     AND "
-"     ( "
-"      (program.programid <> '' "
-"       AND program.programid = oldrecorded.programid) "
-"      OR "
-"      ( ") +
-        (ProgramInfo::UsingProgramIDAuthority() ?
-"       (program.programid = '' OR oldrecorded.programid = '' OR "
-"         LEFT(program.programid, LOCATE('/', program.programid)) <> "
-"         LEFT(oldrecorded.programid, LOCATE('/', oldrecorded.programid))) " :
-"       (program.programid = '' OR oldrecorded.programid = '') " )
-        + QString(
-"       AND "
-"       (((RECTABLE.dupmethod & 0x02) = 0) OR (program.subtitle <> '' "
-"          AND program.subtitle = oldrecorded.subtitle)) "
-"       AND "
-"       (((RECTABLE.dupmethod & 0x04) = 0) OR (program.description <> '' "
-"          AND program.description = oldrecorded.description)) "
-"       AND "
-"       (((RECTABLE.dupmethod & 0x08) = 0) OR "
-"          (program.subtitle <> '' AND "
-"             (program.subtitle = oldrecorded.subtitle OR "
-"              (oldrecorded.subtitle = '' AND "
-"               program.subtitle = oldrecorded.description))) OR "
-"          (program.subtitle = '' AND program.description <> '' AND "
-"             (program.description = oldrecorded.subtitle OR "
-"              (oldrecorded.subtitle = '' AND "
-"               program.description = oldrecorded.description)))) "
-"      ) "
-"     ) "
-"  ) "
-" LEFT JOIN sched_temp_recorded recorded ON "
-"  ( "
-"    RECTABLE.dupmethod > 1 AND "
-"    recorded.duplicate <> 0 AND "
-"    program.title = recorded.title AND "
-"    program.generic = 0 AND "
-"    recorded.recgroup NOT IN ('LiveTV','Deleted') "
-"     AND "
-"     ( "
-"      (program.programid <> '' "
-"       AND program.programid = recorded.programid) "
-"      OR "
-"      ( ") +
-        (ProgramInfo::UsingProgramIDAuthority() ?
-"       (program.programid = '' OR recorded.programid = '' OR "
-"         LEFT(program.programid, LOCATE('/', program.programid)) <> "
-"         LEFT(recorded.programid, LOCATE('/', recorded.programid))) " :
-"       (program.programid = '' OR recorded.programid = '') ")
-        + QString(
-"       AND "
-"       (((RECTABLE.dupmethod & 0x02) = 0) OR (program.subtitle <> '' "
-"          AND program.subtitle = recorded.subtitle)) "
-"       AND "
-"       (((RECTABLE.dupmethod & 0x04) = 0) OR (program.description <> '' "
-"          AND program.description = recorded.description)) "
-"       AND "
-"       (((RECTABLE.dupmethod & 0x08) = 0) OR "
-"          (program.subtitle <> '' AND "
-"             (program.subtitle = recorded.subtitle OR "
-"              (recorded.subtitle = '' AND "
-"               program.subtitle = recorded.description))) OR "
-"          (program.subtitle = '' AND program.description <> '' AND "
-"             (program.description = recorded.subtitle OR "
-"              (recorded.subtitle = '' AND "
-"               program.description = recorded.description)))) "
-"      ) "
-"     ) "
-"  ) "
-" LEFT JOIN oldfind ON "
-"  (oldfind.recordid = recordmatch.recordid AND "
-"   oldfind.findid = ") + progfindid + QString(") "
-"  SET oldrecduplicate = (oldrecorded.endtime IS NOT NULL), "
-"      recduplicate = (recorded.endtime IS NOT NULL), "
-"      findduplicate = (oldfind.findid IS NOT NULL), "
-"      oldrecstatus = oldrecorded.recstatus "
-" WHERE program.endtime >= NOW() - INTERVAL 9 HOUR "
-);
-    rmquery.replace("RECTABLE", schedTmpRecord);
-
     pwrpri.replace("program.","p.");
     pwrpri.replace("channel.","c.");
-    progfindid.replace("program.","p.");
-    progfindid.replace("channel.","c.");
     QString query = QString(
         "SELECT "
         "    c.chanid,         c.sourceid,           p.starttime,       "// 0-2
@@ -3763,14 +3943,14 @@ void Scheduler::AddNewRecords(void)
         "    capturecard.cardid, cardinput.cardinputid,p.seriesid,      "//24-26
         "    p.programid,       RECTABLE.inetref,    p.category_type,   "//27-29
         "    p.airdate,         p.stars,             p.originalairdate, "//30-32
-        "    RECTABLE.inactive, RECTABLE.parentid,") + progfindid + ",  "//33-35
+        "    RECTABLE.inactive, RECTABLE.parentid,   recordmatch.findid, "//33-35
         "    RECTABLE.playgroup, oldrecstatus.recstatus, "//36-37
         "    oldrecstatus.reactivate, p.videoprop+0,     "//38-39
         "    p.subtitletypes+0, p.audioprop+0,   RECTABLE.storagegroup, "//40-42
         "    capturecard.hostname, recordmatch.oldrecstatus, "
         "                                           RECTABLE.avg_delay, "//43-45
-        "    oldrecstatus.future, cardinput.schedorder, "                //46-47
-        + pwrpri + QString(
+        "    oldrecstatus.future, cardinput.schedorder, ") +             //46-47
+        pwrpri + QString(
         "FROM recordmatch "
         "INNER JOIN RECTABLE ON (recordmatch.recordid = RECTABLE.recordid) "
         "INNER JOIN program AS p "
@@ -3785,19 +3965,13 @@ void Scheduler::AddNewRecords(void)
         "ON ( oldrecstatus.station   = c.callsign  AND "
         "     oldrecstatus.starttime = p.starttime AND "
         "     oldrecstatus.title     = p.title ) "
-        "WHERE p.endtime >= NOW() - INTERVAL 1 DAY "
+        "WHERE p.endtime > (NOW() - INTERVAL 480 MINUTE) "
         "ORDER BY RECTABLE.recordid DESC ");
     query.replace("RECTABLE", schedTmpRecord);
 
     LOG(VB_SCHEDULE, LOG_INFO, QString(" |-- Start DB Query..."));
 
     gettimeofday(&dbstart, NULL);
-    result.prepare(rmquery);
-    if (!result.exec())
-    {
-        MythDB::DBError("AddNewRecords recordmatch", result);
-        return;
-    }
     result.prepare(query);
     if (!result.exec())
     {
@@ -3989,17 +4163,6 @@ void Scheduler::AddNewRecords(void)
     RecIter tmp = tmpList.begin();
     for ( ; tmp != tmpList.end(); ++tmp)
         worklist.push_back(*tmp);
-
-    if (schedTmpRecord == "sched_temp_record")
-    {
-        result.prepare("DROP TABLE IF EXISTS sched_temp_record;");
-        if (!result.exec())
-            MythDB::DBError("AddNewRecords sched_temp_record", result);
-    }
-
-    result.prepare("DROP TABLE IF EXISTS sched_temp_recorded;");
-    if (!result.exec())
-        MythDB::DBError("AddNewRecords drop table", result);
 }
 
 void Scheduler::AddNotListed(void) {
diff --git a/mythtv/programs/mythbackend/scheduler.h b/mythtv/programs/mythbackend/scheduler.h
index 8203c9f..2df7b68 100644
--- a/mythtv/programs/mythbackend/scheduler.h
+++ b/mythtv/programs/mythbackend/scheduler.h
@@ -22,6 +22,7 @@ using namespace std;
 #include "mythdeque.h"
 #include "mythscheduler.h"
 #include "mthread.h"
+#include "scheduledrecording.h"
 
 class EncoderLink;
 class MainServer;
@@ -41,9 +42,18 @@ class Scheduler : public MThread, public MythScheduler
 
     void SetExpirer(AutoExpire *autoExpirer) { m_expirer = autoExpirer; }
 
-    void Reschedule(int recordid);
+    void Reschedule(const QStringList &request);
+    void RescheduleMatch(uint recordid, uint sourceid, uint mplexid,
+                         const QDateTime &maxstarttime, const QString &why)
+    { Reschedule(ScheduledRecording::BuildMatchRequest(recordid, sourceid, 
+                                               mplexid, maxstarttime, why)); };
+    void RescheduleCheck(const RecordingInfo &recinfo, const QString &why)
+    { Reschedule(ScheduledRecording::BuildCheckRequest(recinfo, why)); };
+    void ReschedulePlace(const QString &why)
+    { Reschedule(ScheduledRecording::BuildPlaceRequest(why)); };
+
     void AddRecording(const RecordingInfo&);
-    void FillRecordListFromDB(int recordid = -1);
+    void FillRecordListFromDB(uint recordid = 0);
     void FillRecordListFromMaster(void);
 
     void UpdateRecStatus(RecordingInfo *pginfo);
@@ -92,15 +102,19 @@ class Scheduler : public MThread, public MythScheduler
 
     bool VerifyCards(void);
 
+    void CreateTempTables(void);
+    void DeleteTempTables(void);
+    void UpdateDuplicates(void);
     bool FillRecordList(void);
-    void UpdateMatches(int recordid);
-    void UpdateManuals(int recordid);
+    void UpdateMatches(uint recordid, uint sourceid, uint mplexid, 
+                       const QDateTime maxstarttime);
+    void UpdateManuals(uint recordid);
     void BuildWorkList(void);
     bool ClearWorkList(void);
     void AddNewRecords(void);
     void AddNotListed(void);
-    void BuildNewRecordsQueries(int recordid, QStringList &from, QStringList &where,
-                                MSqlBindings &bindings);
+    void BuildNewRecordsQueries(uint recordid, QStringList &from, 
+                                QStringList &where, MSqlBindings &bindings);
     void PruneOverlaps(void);
     void BuildListMaps(void);
     void ClearListMaps(void);
@@ -150,6 +164,9 @@ class Scheduler : public MThread, public MythScheduler
         RecConstIter startIter, const RecList &reclist,
         int prerollseconds, int max_sleep /*ms*/);
     void OldRecordedFixups(void);
+    void ResetDuplicates(uint recordid, uint findid, const QString &title,
+                         const QString &subtitle, const QString &descrip,
+                         const QString &programid);
     bool HandleReschedule(void);
     bool HandleRunSchedulerStartup(
         int prerollseconds, int idleWaitForRecordingTime);
@@ -166,8 +183,17 @@ class Scheduler : public MThread, public MythScheduler
         int idleTimeoutSecs, int idleWaitForRecordingTime,
         bool &statuschanged);
 
-
-    MythDeque<int> reschedQueue;
+    void EnqueueMatch(uint recordid, uint sourceid, uint mplexid,
+                      const QDateTime maxstarttime, const QString &why)
+    { reschedQueue.enqueue(ScheduledRecording::BuildMatchRequest(recordid, 
+                                     sourceid, mplexid, maxstarttime, why)); };
+    void EnqueueCheck(const RecordingInfo &recinfo, const QString &why)
+    { reschedQueue.enqueue(ScheduledRecording::BuildCheckRequest(recinfo, 
+                                                                 why)); };
+    void EnqueuePlace(const QString &why)
+    { reschedQueue.enqueue(ScheduledRecording::BuildPlaceRequest(why)); };
+
+    MythDeque<QStringList> reschedQueue;
     mutable QMutex schedLock;
     QMutex recordmatchLock;
     QWaitCondition reschedWait;
@@ -175,7 +201,7 @@ class Scheduler : public MThread, public MythScheduler
     RecList worklist;
     RecList retrylist;
     RecList conflictlist;
-    QMap<int, RecList> recordidlistmap;
+    QMap<uint, RecList> recordidlistmap;
     QMap<QString, RecList> titlelistmap;
     InputGroupMap igrp;
 
diff --git a/mythtv/programs/mythfilldatabase/main.cpp b/mythtv/programs/mythfilldatabase/main.cpp
index 57d4709..1552a1a 100644
--- a/mythtv/programs/mythfilldatabase/main.cpp
+++ b/mythtv/programs/mythfilldatabase/main.cpp
@@ -760,7 +760,8 @@ int main(int argc, char *argv[])
             "===============================================================");
 
     if (grab_data || mark_repeats)
-        ScheduledRecording::signalChange(-1);
+        ScheduledRecording::RescheduleMatch(0, 0, 0, QDateTime(),
+                                            "MythFillDatabase");
 
     gCoreContext->SendMessage("CLEAR_SETTINGS_CACHE");
 
diff --git a/mythtv/programs/mythfrontend/channelrecpriority.cpp b/mythtv/programs/mythfrontend/channelrecpriority.cpp
index 180bd7e..085ed0f 100644
--- a/mythtv/programs/mythfrontend/channelrecpriority.cpp
+++ b/mythtv/programs/mythfrontend/channelrecpriority.cpp
@@ -238,7 +238,7 @@ void ChannelRecPriority::saveRecPriority(void)
             applyChannelRecPriorityChange(QString::number(chanInfo->chanid),
                                           chanInfo->recpriority);
     }
-    ScheduledRecording::signalChange(0);
+    ScheduledRecording::ReschedulePlace("SaveChannelPriority");
 }
 
 void ChannelRecPriority::FillList(void)
diff --git a/mythtv/programs/mythfrontend/custompriority.cpp b/mythtv/programs/mythfrontend/custompriority.cpp
index e595090..4c5c2b0 100644
--- a/mythtv/programs/mythfrontend/custompriority.cpp
+++ b/mythtv/programs/mythfrontend/custompriority.cpp
@@ -306,7 +306,7 @@ void CustomPriority::installClicked(void)
     if (!query.exec())
         MythDB::DBError("Install power search insert", query);
     else
-        ScheduledRecording::signalChange(0);
+        ScheduledRecording::ReschedulePlace("InstallCustomPriority");
 
     Close();
 }
@@ -324,7 +324,7 @@ void CustomPriority::deleteClicked(void)
     if (!query.exec())
         MythDB::DBError("Delete power search query", query);
     else
-        ScheduledRecording::signalChange(0);
+        ScheduledRecording::ReschedulePlace("DeleteCustomPriority");
 
     Close();
 }
diff --git a/mythtv/programs/mythfrontend/main.cpp b/mythtv/programs/mythfrontend/main.cpp
index 019bb3a..d9042d6 100644
--- a/mythtv/programs/mythfrontend/main.cpp
+++ b/mythtv/programs/mythfrontend/main.cpp
@@ -1044,7 +1044,7 @@ static void TVMenuCallback(void *data, QString &selection)
 
         if (sel == "settings general" ||
             sel == "settings generalrecpriorities")
-            ScheduledRecording::signalChange(0);
+            ScheduledRecording::ReschedulePlace("TVMenuCallback");
         GetMythMainWindow()->ShowPainterWindow();
     }
 }
diff --git a/mythtv/programs/mythfrontend/proglist.cpp b/mythtv/programs/mythfrontend/proglist.cpp
index ddda2af..f2e10c1 100644
--- a/mythtv/programs/mythfrontend/proglist.cpp
+++ b/mythtv/programs/mythfrontend/proglist.cpp
@@ -675,7 +675,7 @@ void ProgLister::DeleteOldEpisode(bool ok)
     if (!query.exec())
         MythDB::DBError("ProgLister::DeleteOldEpisode", query);
 
-    ScheduledRecording::signalChange(0);
+    ScheduledRecording::RescheduleCheck(*pi, "DeleteOldEpisode");
     FillItemList(true);
 }
 
@@ -704,7 +704,11 @@ void ProgLister::DeleteOldSeries(bool ok)
     if (!query.exec())
         MythDB::DBError("ProgLister::DeleteOldSeries -- delete", query);
 
-    ScheduledRecording::signalChange(0);
+    // Set the programid to the special value of "**any**" which the
+    // scheduler recognizes to mean the entire series was deleted.
+    RecordingInfo tempri(*pi);
+    tempri.SetProgramID("**any**");
+    ScheduledRecording::RescheduleCheck(tempri, "DeleteOldSeries");
     FillItemList(true);
 }
 
diff --git a/mythtv/programs/mythfrontend/programrecpriority.cpp b/mythtv/programs/mythfrontend/programrecpriority.cpp
index 1ea874c..a33acf8 100644
--- a/mythtv/programs/mythfrontend/programrecpriority.cpp
+++ b/mythtv/programs/mythfrontend/programrecpriority.cpp
@@ -1027,7 +1027,10 @@ void ProgramRecPriority::deactivate(void)
             }
             else
             {
-                ScheduledRecording::signalChange(0);
+                ScheduledRecording::ReschedulePlace(
+                    QString("DeactivateRule %1 %2")
+                    .arg(pgRecInfo->GetRecordingRuleID())
+                    .arg(pgRecInfo->GetTitle()));
                 pgRecInfo->recstatus = inactive ? rsInactive : rsUnknown;
                 item->DisplayState("disabled", "status");
             }
diff --git a/mythtv/programs/mythutil/backendutils.cpp b/mythtv/programs/mythutil/backendutils.cpp
index 151fa7d..f4f43ea 100644
--- a/mythtv/programs/mythutil/backendutils.cpp
+++ b/mythtv/programs/mythutil/backendutils.cpp
@@ -3,18 +3,21 @@
 #include "mythcorecontext.h"
 #include "mythlogging.h"
 #include "remoteutil.h"
+#include "scheduledrecording.h"
 
 // local headers
 #include "backendutils.h"
 
-static int RawSendEvent(const QString &eventString)
+static int RawSendEvent(const QStringList &eventStringList)
 {
-    if (eventString.isEmpty())
+    if (eventStringList.isEmpty() || eventStringList[0].isEmpty())
         return GENERIC_EXIT_INVALID_CMDLINE;
 
     if (gCoreContext->ConnectToMasterServer(false, false))
     {
-        gCoreContext->SendMessage(eventString);
+        QStringList message("MESSAGE");
+        message << eventStringList;
+        gCoreContext->SendReceiveStringList(message);
         return GENERIC_EXIT_OK;
     }
     return GENERIC_EXIT_CONNECT_ERROR;
@@ -36,28 +39,22 @@ static int ClearSettingsCache(const MythUtilCommandLineParser &cmdline)
 
 static int SendEvent(const MythUtilCommandLineParser &cmdline)
 {
-    return RawSendEvent(cmdline.toString("event"));
+    return RawSendEvent(cmdline.toStringList("event"));
 }
 
 static int SendSystemEvent(const MythUtilCommandLineParser &cmdline)
 {
-    return RawSendEvent(QString("SYSTEM_EVENT %1 SENDER %2")
-                                .arg(cmdline.toString("systemevent"))
-                                .arg(gCoreContext->GetHostName()));
+    return RawSendEvent(QStringList(QString("SYSTEM_EVENT %1 SENDER %2")
+                                    .arg(cmdline.toString("systemevent"))
+                                    .arg(gCoreContext->GetHostName())));
 }
 
 static int Reschedule(const MythUtilCommandLineParser &cmdline)
 {
     if (gCoreContext->ConnectToMasterServer(false, false))
     {
-        QStringList slist("RESCHEDULE_RECORDINGS -1");
-        if (gCoreContext->SendReceiveStringList(slist))
-        {
-            LOG(VB_GENERAL, LOG_ERR,
-                "Error sending reschedule command to master backend");
-            return GENERIC_EXIT_CONNECT_ERROR;
-        }
-
+        ScheduledRecording::RescheduleMatch(0, 0, 0, QDateTime(),
+                                            "MythUtilCommand");
         LOG(VB_GENERAL, LOG_INFO, "Reschedule command sent to master");
         return GENERIC_EXIT_OK;
     }
diff --git a/mythtv/programs/mythutil/commandlineparser.cpp b/mythtv/programs/mythutil/commandlineparser.cpp
index 7f00e50..897be65 100644
--- a/mythtv/programs/mythutil/commandlineparser.cpp
+++ b/mythtv/programs/mythutil/commandlineparser.cpp
@@ -83,7 +83,8 @@ void MythUtilCommandLineParser::LoadArguments(void)
                 "access those files to do so. If enabled, this will also "
                 "trigger the bulk metadata scanner upon completion.")
                 ->SetGroup("Backend")
-        << add("--event", "event", "", "Send a backend event test message.", "")
+        << add("--event", "event", QVariant::StringList, 
+                "Send a backend event test message.", "")
                 ->SetGroup("Backend")
         << add("--systemevent", "systemevent", "",
                 "Send a backend SYSTEM_EVENT test message.", "")
