Index: main/waeup.ikoba/trunk/src/waeup/ikoba/mandates/container.py
===================================================================
--- main/waeup.ikoba/trunk/src/waeup/ikoba/mandates/container.py	(revision 12816)
+++ main/waeup.ikoba/trunk/src/waeup/ikoba/mandates/container.py	(revision 14221)
@@ -31,4 +31,14 @@
     grok.provides(IMandatesContainer)
 
+    @property
+    def count(self):
+        """Count active and expired mandates.
+        """
+        now = datetime.utcnow()
+        total = len(self)
+        expired = len([i for i in self.values() if i.expires < now])
+        active = total - expired
+        return active, expired, total
+
     def addMandate(self, mandate):
         if not IMandate.providedBy(mandate):
@@ -42,8 +52,10 @@
         """
         num_deleted = 0
-        for mandate in self.keys():
+        keys = list(self.keys())
+        for mandate in keys:
             if self[mandate].expires < datetime.utcnow():
                 del self[mandate]
                 num_deleted += 1
+        grok.getSite().logger.info('%s mandates purged' % num_deleted)
         return num_deleted
 
Index: main/waeup.ikoba/trunk/src/waeup/ikoba/mandates/interfaces.py
===================================================================
--- main/waeup.ikoba/trunk/src/waeup/ikoba/mandates/interfaces.py	(revision 12816)
+++ main/waeup.ikoba/trunk/src/waeup/ikoba/mandates/interfaces.py	(revision 14221)
@@ -25,4 +25,6 @@
     """
 
+    count = Attribute('Count active and expired mandates.')
+
     def addMandate(mandate):
         """Add mandate.
Index: main/waeup.ikoba/trunk/src/waeup/ikoba/mandates/mandate.py
===================================================================
--- main/waeup.ikoba/trunk/src/waeup/ikoba/mandates/mandate.py	(revision 12816)
+++ main/waeup.ikoba/trunk/src/waeup/ikoba/mandates/mandate.py	(revision 14221)
@@ -67,7 +67,8 @@
     def execute(self):
         msg = _('Wrong mandate parameters.')
+        redirect_path = ''
         if self.expires < datetime.utcnow():
             msg = _('Mandate expired.')
-        if self._setPassword():
+        elif self._setPassword():
             msg = _('Password has been successfully set. '
                     'Login with your new password.')
@@ -75,4 +76,5 @@
             grok.getSite().logger.info(
                 'PasswordMandate used: %s ' % username)
+            redirect_path = 'login'
         del self.__parent__[self.mandate_id]
-        return msg
+        return msg, redirect_path
Index: main/waeup.ikoba/trunk/src/waeup/ikoba/mandates/tests.py
===================================================================
--- main/waeup.ikoba/trunk/src/waeup/ikoba/mandates/tests.py	(revision 12816)
+++ main/waeup.ikoba/trunk/src/waeup/ikoba/mandates/tests.py	(revision 14221)
@@ -89,12 +89,18 @@
         # Add and execute a mandate with missing parameters.
         mandate = PasswordMandate()
+        IUserAccount(customer).setPassword('old_pw')
         self.app['mandates'].addMandate(mandate)
-        msg = mandate.execute()
+        (msg, redirect_path) = mandate.execute()
         self.assertEqual(msg, u'Wrong mandate parameters.')
         # Add and execute an expired mandate.
         mandate = PasswordMandate(days=0)
+        mandate.params['user'] = customer
+        mandate.params['password'] = 'mypwd1'
         self.app['mandates'].addMandate(mandate)
-        msg = mandate.execute()
+        (msg, redirect_path) = mandate.execute()
         self.assertEqual(msg, u'Mandate expired.')
+        self.assertEqual(redirect_path, '')
+        # Password has not been set
+        self.assertTrue(IUserAccount(customer).checkPassword('old_pw'))
         # Add and execute a perfect mandate
         mandate = PasswordMandate()
@@ -102,5 +108,5 @@
         mandate.params['password'] = 'mypwd1'
         self.app['mandates'].addMandate(mandate)
-        msg = mandate.execute()
+        (msg, redirect_path) = mandate.execute()
         # Password has been set.
         self.assertEqual(msg, 'Password has been successfully set. Login with your new password.')
@@ -120,5 +126,5 @@
         mandate.params['password'] = 'mypwd1'
         self.app['mandates'].addMandate(mandate)
-        msg = mandate.execute()
+        (msg, redirect_path) = mandate.execute()
         # Password has been set.
         self.assertEqual(msg, 'Password has been successfully set. Login with your new password.')
@@ -142,4 +148,24 @@
         self.assertEqual(len(self.app['mandates'].keys()), 1)
         self.assertEqual([i for i in self.app['mandates'].keys()], [u'23456'])
+        logfile = os.path.join(
+            self.app['datacenter'].storage, 'logs', 'main.log')
+        logcontent = open(logfile).read()
+        self.assertTrue('system - 1 mandates purged' in logcontent)
+
+    def test_purge_mandates(self):
+        # mandate1 is an old mandate which just expired.
+        mandate1 = PasswordMandate(days=0)
+        self.app['mandates'].addMandate(mandate1)
+        # mandate2 is a new mandate with default time delta.
+        mandate2 = PasswordMandate(mandate_id='23456')
+        self.app['mandates'].addMandate(mandate2)
+        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+        self.browser.open('http://localhost/app/configuration')
+        self.assertEqual(self.app['mandates'].count, (1, 1, 2))
+        self.assertTrue('<span>expired</span>' in self.browser.contents)
+        self.browser.getControl("Purge mandates").click()
+        self.assertTrue('1 mandate(s) were purged' in self.browser.contents)
+        self.assertEqual(self.app['mandates'].count, (1, 0, 1))
+        return
 
     def test_browser(self):
