Index: libs/libmythtv/programinfo.cpp
===================================================================
--- libs/libmythtv/programinfo.cpp	(revision 7252)
+++ libs/libmythtv/programinfo.cpp	(working copy)
@@ -3208,6 +3208,13 @@
         }
         message += "\n";
         delete confList;
+
+	if (gContext->GetNumSetting("OverTimePriority") == 3
+	    && (gContext->GetNumSetting("RecordOverTime") > 0 ||
+	        gContext->GetNumSetting("RecordPreRoll") > 0))
+	    message +=  QObject::tr("\nYou may be able to eliminate "
+		    "conflicts by changing your OverTime setting from "
+		    "\"Always\" to something less stringent.\n");
     }
 
     DialogBox diag(gContext->GetMainWindow(), message);
Index: programs/mythfrontend/globalsettings.cpp
===================================================================
--- programs/mythfrontend/globalsettings.cpp	(revision 7252)
+++ programs/mythfrontend/globalsettings.cpp	(working copy)
@@ -566,9 +566,7 @@
     bs->setLabel(QObject::tr("Time to record before start of show "
                  "(in seconds)"));
     bs->setHelpText(QObject::tr("This global setting allows the recorder "
-                    "to start before the scheduled start time. It does "
-                    "not affect the scheduler. It is ignored when two shows "
-                    "have been scheduled without enough time in between."));
+                    "to start before the scheduled start time."));
     bs->setValue(0);
     return bs;
 }
@@ -579,9 +577,7 @@
     bs->setLabel(QObject::tr("Time to record past end of show (in seconds)"));
     bs->setValue(0);
     bs->setHelpText(QObject::tr("This global setting allows the recorder "
-                    "to record beyond the scheduled end time. It does "
-                    "not affect the scheduler. It is ignored when two shows "
-                    "have been scheduled without enough time in between."));
+                    "to record beyond the scheduled end time."));
     return bs;
 }
 
@@ -592,7 +588,7 @@
     ge->setValue(QObject::tr("category name"));
     ge->setHelpText(QObject::tr("For a specific category (e.g. "
                                 "\"Sports event\"), request that shows "
-                                "be autoextended.  Only works if a "
+                                "be autoextended. Requires that the "
                                 "show's category can be determined."));
     return ge;
 }
@@ -603,11 +599,9 @@
                                           0, 180, 60, true);
     bs->setLabel(QObject::tr("Record past end of show (in minutes)"));
     bs->setValue(30);
-    bs->setHelpText(QObject::tr("For the specified category, an attempt "
-                                "will be made to extend the recording "
-                                "by the specified time.  It is ignored "
-                                "when two shows have been scheduled "
-                                "without enough time in between."));
+    bs->setHelpText(QObject::tr("For the specified category, attempt "
+                                "to extend the recording "
+                                "by the specified time."));
     return bs;
 }
 
@@ -616,13 +610,32 @@
     VerticalConfigurationGroup *vcg =
         new VerticalConfigurationGroup(false, false);
 
-    vcg->setLabel(QObject::tr("Category record over-time"));
+    vcg->setLabel(QObject::tr("Category record OverTime"));
     vcg->setUseLabel(true);
     vcg->addChild(OverTimeCategory());
     vcg->addChild(CategoryOverTime());
     return vcg;
 }
 
+
+static HostComboBox *OverTimePriority()
+{
+    HostComboBox *gc = new HostComboBox("OverTimePriority");
+    gc->setLabel(QObject::tr("Apply OverTime buffers"));
+    gc->addSelection(QObject::tr("Unless conflict, tuner, or reschedule req'd"), "0");
+    gc->addSelection(QObject::tr("Unless conflict or extra tuner req'd"), "1");
+    gc->addSelection(QObject::tr("Unless conflict"), "2");
+    gc->addSelection(QObject::tr("Always (may create conflicts)"), "3");
+    gc->setHelpText(QObject::tr("When to record the OverTime buffer "
+			    "specified above. If desired, "
+			    "MythTV can assign recordings to an idle "
+			    "tuner card, record an earlier/later showing, "
+			    "or even cause a conflict "
+			    "when necessary to honor the OverTime "
+			    "settings."));
+    return gc;
+}
+
 static HostCheckBox *PlayBoxOrdering()
 {
     HostCheckBox *gc = new HostCheckBox("PlayBoxOrdering");
@@ -3079,12 +3092,17 @@
         jobs->addChild(AutoRunUserJob(i));
     addChild(jobs);
 
+    VerticalConfigurationGroup* overtime = new VerticalConfigurationGroup(false);
+    overtime->setLabel(QObject::tr("General (OverTime Buffer)"));
+    overtime->addChild(RecordPreRoll());
+    overtime->addChild(RecordOverTime());
+    overtime->addChild(OverTimePriority());
+    overtime->addChild(CategoryOverTimeSettings());
+    addChild(overtime);
+
     VerticalConfigurationGroup* general2 = new VerticalConfigurationGroup(false);
     general2->setLabel(QObject::tr("General (Advanced)"));
     general2->addChild(AutoExpireExtraSpace());
-    general2->addChild(RecordPreRoll());
-    general2->addChild(RecordOverTime());
-    general2->addChild(CategoryOverTimeSettings());
     general2->addChild(ATSCCheckSignalThreshold());
     general2->addChild(ATSCCheckSignalWait());
     general2->addChild(HDRingbufferSize());
Index: programs/mythfrontend/main.cpp
===================================================================
--- programs/mythfrontend/main.cpp	(revision 7252)
+++ programs/mythfrontend/main.cpp	(working copy)
@@ -434,6 +434,9 @@
     {
         GeneralSettings settings;
         settings.exec();
+	
+	// Required if user altered OverTime settings
+	ScheduledRecording::signalChange(0);
     } 
     else if (sel == "settings maingeneral") 
     {
Index: programs/mythbackend/scheduler.cpp
===================================================================
--- programs/mythbackend/scheduler.cpp	(revision 7252)
+++ programs/mythbackend/scheduler.cpp	(working copy)
@@ -268,8 +268,23 @@
     retrylist.sort(comp_retry);
     VERBOSE(VB_SCHEDULE, "MoveHigherRecords...");
     MoveHigherRecords();
+    VERBOSE(VB_SCHEDULE, "Clear retrylist...");
     retrylist.clear();
 
+    // If user has a global setting to start recordings early or finish
+    // them late, we'll see if we can better honour this by finding
+    // alternate showings.
+    if(gContext->GetNumSetting("OverTimePriority") > 0
+       && (gContext->GetNumSetting("RecordOverTime") > 0 ||
+           gContext->GetNumSetting("RecordPreRoll") > 0))
+    {
+        VERBOSE(VB_SCHEDULE, "Sort by time...");
+	reclist.sort(comp_recstart);
+	
+	VERBOSE(VB_SCHEDULE, "ShuffleForOverrecord...");
+	ShuffleForOverrecord();
+    }
+    
     VERBOSE(VB_SCHEDULE, "ClearListMaps...");
     ClearListMaps();
 
@@ -588,8 +603,29 @@
     recordidlistmap.clear();
 }
 
-bool Scheduler::FindNextConflict(RecList &cardlist, ProgramInfo *p, RecIter &j)
+bool Scheduler::FindNextConflict(RecList &cardlist, ProgramInfo *p, RecIter &j, bool findSoftConflicts)
 {
+
+    int prerollseconds;
+    int overrecordseconds;
+
+    // A "soft conflict" is when two programs overlap only when the
+    // global underrecord and overrecord settings are taken into
+    // consideration.
+    // We consider them if either:
+    // (a) the user has specified that he ALWAYS wants the overrecord
+    //     buffers honoured; or
+    // (b) the user wants them honoured in some cases, and this is one
+    //     of those as indicated by the findSoftConflicts flag
+    if (gContext->GetNumSetting("OverTimePriority") == 3)
+	findSoftConflicts = 1;
+
+    if (findSoftConflicts)
+    {
+      prerollseconds    = gContext->GetNumSetting("RecordPreRoll");
+      overrecordseconds = gContext->GetNumSetting("RecordOverTime");
+    }
+
     for ( ; j != cardlist.end(); j++)
     {
         ProgramInfo *q = *j;
@@ -600,8 +636,19 @@
             continue;
         if (p->cardid != 0 && p->cardid != q->cardid)
             continue;
-        if (p->recendts <= q->recstartts || p->recstartts >= q->recendts)
-            continue;
+	if (findSoftConflicts)
+        {
+            if (p->recendts.addSecs(overrecordseconds) <=
+                        q->recstartts.addSecs((-1) * prerollseconds)
+               || p->recstartts.addSecs((-1) * prerollseconds) >=
+                        q->recendts.addSecs(overrecordseconds))
+		continue;
+        }
+        else
+        {
+            if (p->recendts <= q->recstartts || p->recstartts >= q->recendts)
+                continue;
+        }
         if (p->inputid == q->inputid && p->shareable)
             continue;
 
@@ -841,6 +888,62 @@
     }
 }
 
+void Scheduler::ShuffleForOverrecord(void)
+{
+    VERBOSE(VB_SCHEDULE, "Trying to accommodate pre-roll / overrecord:");
+
+    RecIter i = reclist.begin();
+
+    for ( ; i != reclist.end(); i++)
+    {
+	ProgramInfo *p = *i;
+
+	if (p->recstatus != rsRecording && p->recstatus != rsWillRecord)
+	    continue;
+
+        // Look for soft conflicts with any other scheduled program
+        RecIter k = reclist.begin();
+        if (FindNextConflict(reclist, p, k, true))
+        {
+            // There's a soft conflict, so let's see if a different
+            // showing would give us no conflicts at all.
+
+            // Get list of alternative showings
+            RecList &showinglist = titlelistmap[p->title];
+            RecIter j = showinglist.begin();
+
+            // Cycle through showings, looking for one that won't conflict
+            for ( ; j != showinglist.end(); j++)
+            {
+                ProgramInfo *q = *j;
+
+                // No need to re-check the same showing
+                if (q == p)
+                    continue;
+
+		// Don't consider showings that use a different tuner
+		// card if the user has specified he doesn't want this.
+		if (gContext->GetNumSetting("OverTimePriority") < 2
+		    && p->cardid != q->cardid)
+		    continue;
+			
+                k = reclist.begin();
+                if (!FindNextConflict(reclist, q, k, true))
+                {
+                    // This showing is completely conflict-free, so
+                    // substitute it.
+
+                    q->recstatus = rsWillRecord;
+                    MarkOtherShowings(q);
+                    PrintRec(p, "  -");
+                    PrintRec(q, "  +");
+                    break;
+		}
+            }
+	}
+    }
+}
+
 void Scheduler::getConflicting(ProgramInfo *pginfo, QStringList &strlist)
 {
     QMutexLocker lockit(reclist_lock);
Index: programs/mythbackend/scheduler.h
===================================================================
--- programs/mythbackend/scheduler.h	(revision 7252)
+++ programs/mythbackend/scheduler.h	(working copy)
@@ -73,7 +73,7 @@
     void PruneOverlaps(void);
     void BuildListMaps(void);
     void ClearListMaps(void);
-    bool FindNextConflict(RecList &cardlist, ProgramInfo *p, RecIter &iter);
+    bool FindNextConflict(RecList &cardlist, ProgramInfo *p, RecIter &iter, bool findSoftConflicts = false);
     void MarkOtherShowings(ProgramInfo *p);
     void MarkShowingsList(RecList &showinglist, ProgramInfo *p);
     void BackupRecStatus(void);
@@ -82,6 +82,7 @@
     void SchedNewRecords(void);
     void MoveHigherRecords(void);
     void PruneRedundants(void);
+    void ShuffleForOverrecord(void);
 
 
     void findAllScheduledPrograms(list<ProgramInfo *> &proglist);
