Index: indico/MaKaC/conference.py
===================================================================
--- indico/MaKaC/conference.py	(revision 9a0611240112adb5d280692b4041b757431e759e)
+++ indico/MaKaC/conference.py	(revision e83ea5588c8328653b341540fe8bd86a2ce74c28)
@@ -2683,5 +2683,5 @@
                 try:
                     Logger.get('Conference').error("Exception while notifying the observer %s of of a conference deletion for conference %s: %s"%
-                                                   (observer.getName(), self.getId(), str(e)))
+                                                   (observer.getObserverName(), self.getId(), str(e)))
                 except Exception, e2:
                     Logger.get('Conference').error("Exception while notifying a conference deletion: %s (origin: %s)"%(str(e2), str(e)))
@@ -2733,16 +2733,29 @@
             return
         self.unindexConf()
-        self.setStartDate(sDate, check=0, moveEntries=moveEntries,index=False)
-        self.setEndDate(eDate, check=0, index=False)
+        
+        self.setStartDate(sDate, check=0, moveEntries = moveEntries, index=False, notifyObservers = False)
+        self.setEndDate(eDate, check=0, index=False, notifyObservers = False)
+        
         self._checkInnerSchedule()
         self.indexConf()
         self.cleanCategoryCache()
+        
+        for observer in self.getDateChangeObservers():
+            try:
+                observer.notifyEventDateChanges(oldStartDate, self.getStartDate(), oldEndDate, self.getEndDate())
+            except Exception, e:
+                try:
+                    Logger.get('Conference').error("Exception while notifying the observer %s of a start and end date change from %s - %s to %s - %s for conference %s: %s"%
+                                                   (observer.getObserverName(), formatDateTime(oldStartDate), formatDateTime(oldEndDate),
+                                                    formatDateTime(self.getStartDate()), formatDateTime(self.getEndDate()), self.getId(), str(e)))
+                except Exception, e2:
+                    Logger.get('Conference').error("Exception while notifying a start and end date change: %s (origin: %s)"%(str(e2), str(e)))
 
     def _checkInnerSchedule( self ):
         self.getSchedule().checkSanity()
 
-    def setStartDate(self,sDate,check=1,moveEntries=0,index=True):
-        """changes the current conference starting date to the one specified by
-            the parameters"""
+    def setStartDate(self, sDate, check = 1, moveEntries = 0, index = True, notifyObservers = True):
+        """ Changes the current conference starting date/time to the one specified by the parameters.
+        """
         if not sDate.tzname():
             raise MaKaCError("date should be timezone aware")
@@ -2762,8 +2775,5 @@
         oldSdate = self.getStartDate()
         diff = sDate - oldSdate
-        try:
-           tz = str(sDate.tzinfo)
-        except:
-           tz = "Undef"
+        
         if index:
             self.unindexConf()
@@ -2786,13 +2796,14 @@
 
         #if everything went well, we notify the observers that the start date has changed
-        for observer in self.getDateChangeObservers():
-            try:
-                observer.notifyStartDateChange(oldSdate, sDate)
-            except Exception, e:
+        if notifyObservers:
+            for observer in self.getDateChangeObservers():
                 try:
-                    Logger.get('Conference').error("Exception while notifying the observer %s of a start date change from %s to %s for conference %s: %s"%
-                                                   (observer.getName(), formatDateTime(oldSdate), formatDateTime(sDate), self.getId(), str(e)))
-                except Exception, e2:
-                    Logger.get('Conference').error("Exception while notifying a start date change: %s (origin: %s)"%(str(e2), str(e)))
+                    observer.notifyEventDateChanges(oldSdate, sDate, None, None)
+                except Exception, e:
+                    try:
+                        Logger.get('Conference').error("Exception while notifying the observer %s of a start date change from %s to %s for conference %s: %s"%
+                                                       (observer.getObserverName(), formatDateTime(oldSdate), formatDateTime(sDate), self.getId(), str(e)))
+                    except Exception, e2:
+                        Logger.get('Conference').error("Exception while notifying a start date change: %s (origin: %s)"%(str(e2), str(e)))
 
 
@@ -2801,5 +2812,8 @@
             raise MaKaCError( _("End date cannot be before the Start date"), _("Event"))
 
-    def setStartTime(self, hours=0, minutes=0):
+    def setStartTime(self, hours=0, minutes=0, notifyObservers = True):
+        """ Changes the current conference starting time (not date) to the one specified by the parameters.
+        """
+        
         sdate = self.getStartDate()
         self.startDate = datetime( sdate.year, sdate.month, sdate.day,
@@ -2809,13 +2823,14 @@
 
         #if everything went well, we notify the observers that the start date has changed
-        for observer in self.getDateChangeObservers():
-            try:
-                observer.notifyStartDateChange(sdate, self.startDate)
-            except Exception, e:
+        if notifyObservers:
+            for observer in self.getDateChangeObservers():
                 try:
-                    Logger.get('Conference').error("Exception while notifying the observer %s of a start date change from %s to %s for conference %s: "%
-                                                   (observer.getName(), formatDateTime(sdate), formatDateTime(self.startDate), self.getId(), str(e)))
-                except Exception, e2:
-                    Logger.get('Conference').error("Exception while notifying a start time change: %s (origin: %s)"%(str(e2), str(e)))
+                    observer.notifyEventDateChanges(sdate, self.startDate, None, None)
+                except Exception, e:
+                    try:
+                        Logger.get('Conference').error("Exception while notifying the observer %s of a start date change from %s to %s for conference %s: "%
+                                                       (observer.getObserverName(), formatDateTime(sdate), formatDateTime(self.startDate), self.getId(), str(e)))
+                    except Exception, e2:
+                        Logger.get('Conference').error("Exception while notifying a start time change: %s (origin: %s)"%(str(e2), str(e)))
 
     def getStartDate(self):
@@ -2873,7 +2888,7 @@
             raise MaKaCError(_("Cannot change end date to %s: some entries in the timetable would be outside this date (%s)") % (edate,self.getSchedule().getEntries()[-1].getStartDate()), _("Event"))
 
-    def setEndDate(self, eDate,check=1, index=True):
-        """changes the current conference ending date to the one specified by
-            the parameters"""
+    def setEndDate(self, eDate, check = 1, index = True, notifyObservers = True):
+        """ Changes the current conference end date/time to the one specified by the parameters.
+        """
         if not eDate.tzname():
             raise MaKaCError("date should be timezone aware")
@@ -2896,31 +2911,34 @@
 
         #if everything went well, we notify the observers that the start date has changed
-        for observer in self.getDateChangeObservers():
-            try:
-                observer.notifyEndDateChange(oldEdate, eDate)
-            except Exception, e:
+        if notifyObservers:
+            for observer in self.getDateChangeObservers():
                 try:
-                    Logger.get('Conference').error("Exception while notifying the observer %s of a end date change from %s to %s for conference %s: "%
-                                                   (observer.getName(), formatDateTime(oldEdate), formatDateTime(eDate), self.getId(), str(e)))
-                except Exception, e2:
-                    Logger.get('Conference').error("Exception while notifying a end date change: %s (origin: %s)"%(str(e2), str(e)))
-
-    def setEndTime(self, hours=0, minutes=0):
+                    observer.notifyEventDateChanges(None, None, oldEdate, eDate)
+                except Exception, e:
+                    try:
+                        Logger.get('Conference').error("Exception while notifying the observer %s of a end date change from %s to %s for conference %s: "%
+                                                       (observer.getObserverName(), formatDateTime(oldEdate), formatDateTime(eDate), self.getId(), str(e)))
+                    except Exception, e2:
+                        Logger.get('Conference').error("Exception while notifying a end date change: %s (origin: %s)"%(str(e2), str(e)))
+
+    def setEndTime(self, hours = 0, minutes = 0, notifyObservers = True):
+        """ Changes the current conference end time (not date) to the one specified by the parameters.
+        """
         edate = self.getEndDate()
-        self.endDate = datetime( edate.year, edate.month, edate.day, \
-                                                    int(hours), int(minutes) )
+        self.endDate = datetime( edate.year, edate.month, edate.day, int(hours), int(minutes) )
         self.verifyEndDate(self.endDate)
         self.notifyModification()
 
         #if everything went well, we notify the observers that the start date has changed
-        for observer in self.getDateChangeObservers():
-            try:
-                observer.notifyEndDateChange(edate, self.endDate)
-            except Exception, e:
+        if notifyObservers:
+            for observer in self.getDateChangeObservers():
                 try:
-                    Logger.get('Conference').error("Exception while notifying the observer %s of a end timet change from %s to %s for conference %s: "%
-                                                   (observer.getName(), formatDateTime(edate), formatDateTime(self.endDate), self.getId(), str(e)))
-                except Exception, e2:
-                    Logger.get('Conference').error("Exception while notifying a end time change: %s (origin: %s)"%(str(e2), str(e)))
+                    observer.notifyEventDateChanges(None, None, edate, self.endDate)
+                except Exception, e:
+                    try:
+                        Logger.get('Conference').error("Exception while notifying the observer %s of a end timet change from %s to %s for conference %s: "%
+                                                       (observer.getObserverName(), formatDateTime(edate), formatDateTime(self.endDate), self.getId(), str(e)))
+                    except Exception, e2:
+                        Logger.get('Conference').error("Exception while notifying a end time change: %s (origin: %s)"%(str(e2), str(e)))
 
     def getEndDate(self):
@@ -3043,5 +3061,5 @@
                 try:
                     Logger.get('Conference').error("Exception while notifying the observer %s of of a conference title change for conference %s: %s"%
-                                                   (observer.getName(), self.getId(), str(e)))
+                                                   (observer.getObserverName(), self.getId(), str(e)))
                 except Exception, e2:
                     Logger.get('Conference').error("Exception while notifying a conference title change: %s (origin: %s)"%(str(e2), str(e)))
@@ -4911,16 +4929,21 @@
         return None
 
-class TitleChangeObserver(object):
-    """ Base class for objects who want to be notified of a Conference object being deleted.
-        Inheriting classes have to implement the notifyDeletion method, and probably the __init__ method too.
+class Observer(object):
+    """ Base class for Observer objects.
+        Provides the getObserverName method (used when writing info to the Indico log)
     """
     def getObserverName(self):
-        name = "'title change observer of class" + self.__class__.__name__
-        try:
-            conference = self.getConference()
-            name = name + " of conference " + conference.getId()
+        name = "'Observer of class" + self.__class__.__name__
+        try:
+            conf = self.getOwner()
+            name = name + " of event " + conf.getId() + "'"
         except AttributeError:
             pass
         return name
+
+class TitleChangeObserver(Observer):
+    """ Base class for objects who want to be notified of a Conference object being deleted.
+        Inheriting classes have to implement the notifyTitleChange method, and probably the __init__ method too.
+    """
 
     def notifyTitleChange(self, oldTitle, newTitle):
@@ -4930,5 +4953,5 @@
         raise MaKaCError("Class " + str(self.__class__.__name__) + " did not implement method notifyTitleChange")
 
-class DateChangeObserver(object):
+class DateChangeObserver(Observer):
     """ Base class for objects who want to be notified of a change in the start date / end date
         of an object (for example a Conference object).
@@ -4936,45 +4959,28 @@
         and probably the __init__ method too.
     """
-    def getObserverName(self):
-        name = "'date observer of class" + self.__class__.__name__
-        try:
-            conference = self.getConference()
-            name = name + " of conference " + conference.getId()
-        except AttributeError:
-            pass
-        return name
-
-    def notifyStartDateChange(self, oldStartDate, newStartDate):
+
+    def notifyEventDateChanges(self, oldStartDate = None, newStartDate = None, oldEndDate = None, newEndDate = None):
         """ To be implemented by inheriting classes
-            Notifies the observer that the start date of the object it is attached to has changed
+            Notifies the observer that the start and / or end dates of the object it is attached to has changed.
+            If the observer finds any problems during whatever he needs to do as a consequence of
+            the event dates changing, he should write strings describing the problems
+            in the 'dateChangeNotificationProblems' context variable (which is a list of strings).
         """
         raise MaKaCError("Class " + str(self.__class__.__name__) + " did not implement method notifyStartDateChange")
 
-    def notifyEndDateChange(self, oldEndDate, newEndDate):
-        """ To be implemented by inheriting classes
-            Notifies the observer that the end date of the object it is attached to has changed
-        """
-        raise MaKaCError("Class " + str(self.__class__.__name__) + " did not implement method notifyStartDateChange")
-
     def notifyTimezoneChange(self, oldTimezone, newTimezone):
-        """ To be implemented by inheriting classes
-            Notifies the observer that the end date of the object it is attached to has changed
+        """ To be implemented by inheriting classes.
+            Notifies the observer that the end date of the object it is attached to has changed.
+            This method has to return a list of strings describing problems encountered during
+            whatever the DateChangeObserver object does as a consequence of the notification.
+            If there are no problems, the DateChangeObserver should return an empty list.
         """
         raise MaKaCError("Class " + str(self.__class__.__name__) + " did not implement method notifyTimezoneChange")
 
 
-class DeleteObserver(object):
+class DeleteObserver(Observer):
     """ Base class for objects who want to be notified of a Conference object being deleted.
         Inheriting classes have to implement the notifyDeletion method, and probably the __init__ method too.
     """
-    def getObserverName(self):
-        name = "'delete observer of class" + self.__class__.__name__
-        try:
-            conference = self.getConference()
-            name = name + " of conference " + conference.getId()
-        except AttributeError:
-            pass
-        return name
-
     def notifyDeletion(self):
         """ To be implemented by inheriting classes
