Index: main/waeup.kofa/trunk/src/waeup/kofa/browser/viewlets.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/browser/viewlets.py	(revision 11849)
+++ main/waeup.kofa/trunk/src/waeup/kofa/browser/viewlets.py	(revision 11862)
@@ -476,4 +476,21 @@
     grok.order(3)
 
+class ClearDepartmentStudentsActionButton(ManageActionButton):
+    """ 'Clear all students' button for departments.
+    """
+    grok.context(IDepartment)
+    grok.view(DepartmentPage)
+    grok.name('cleardepartmentstudents')
+    grok.require('waeup.clearAllStudents')
+    icon = 'actionicon_accept.png'
+    text = _('Clear all students')
+    target = 'clearallstudents'
+    grok.order(4)
+
+    @property
+    def onclick(self):
+        return "return window.confirm(%s);" % _(
+            "'All students, who requested clearance in this department, will be cleared. Are you sure?'")
+
 class ManageCourseActionButton(ManageActionButton):
     """ 'Edit settings' button for courses.
Index: main/waeup.kofa/trunk/src/waeup/kofa/permissions.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/permissions.py	(revision 11849)
+++ main/waeup.kofa/trunk/src/waeup/kofa/permissions.py	(revision 11862)
@@ -59,4 +59,7 @@
     grok.name('waeup.showStudents')
 
+class ClearAllStudents(grok.Permission):
+    grok.name('waeup.clearAllStudents')
+
 class EditScores(grok.Permission):
     grok.name('waeup.editScores')
@@ -128,5 +131,6 @@
     grok.permissions('waeup.showStudents',
                      'waeup.viewAcademics',
-                     'waeup.exportData')
+                     'waeup.exportData',
+                     'waeup.clearAllStudents')
 
 class LocalStudentsManager(grok.Role):
@@ -158,5 +162,6 @@
     grok.permissions('waeup.showStudents',
                      'waeup.viewAcademics',
-                     'waeup.exportData')
+                     'waeup.exportData',
+                     'waeup.clearAllStudents')
 
 class PGClearanceOfficer(grok.Role):
@@ -168,5 +173,6 @@
     grok.permissions('waeup.showStudents',
                      'waeup.viewAcademics',
-                     'waeup.exportData')
+                     'waeup.exportData',
+                     'waeup.clearAllStudents')
 
 class CourseAdviser100(grok.Role):
@@ -336,4 +342,5 @@
                      'waeup.clearStudent', 'waeup.payStudent',
                      'waeup.uploadStudentFile', 'waeup.showStudents',
+                     'waeup.clearAllStudents',
                      'waeup.editScores',
                      'waeup.triggerTransition',
@@ -369,4 +376,5 @@
                      'waeup.clearStudent', 'waeup.payStudent',
                      'waeup.uploadStudentFile', 'waeup.showStudents',
+                     'waeup.clearAllStudents',
                      'waeup.editScores',
                      #'waeup.triggerTransition',
Index: main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py	(revision 11849)
+++ main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py	(revision 11862)
@@ -3004,4 +3004,31 @@
         return list(set(hitlist))
 
+class ClearAllStudentsInDepartmentPage(UtilityView, grok.View):
+    """ Clear all students of a department in state 'clearance requested'.
+    """
+    grok.context(IDepartment)
+    grok.name('clearallstudents')
+    grok.require('waeup.clearAllStudents')
+
+    def update(self):
+        cat = queryUtility(ICatalog, name='students_catalog')
+        students = cat.searchResults(
+            depcode=(self.context.code, self.context.code),
+            state=(REQUESTED, REQUESTED)
+            )
+        num = 0
+        for student in students:
+            if getUtility(IStudentsUtils).clearance_disabled_message(student):
+                continue
+            IWorkflowInfo(student).fireTransition('clear')
+            num += 1
+        self.flash(_('%d students have been cleared.' % num))
+        self.redirect(self.url(self.context))
+        return
+
+    def render(self):
+        return
+
+
 class EditScoresPage(KofaPage):
     """Page that filters and lists students.
Index: main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py	(revision 11849)
+++ main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py	(revision 11862)
@@ -1384,5 +1384,5 @@
         return
 
-    def test_handle_clearance_by_co(self):
+    def init_clearance_officer(self):
         # Create clearance officer
         self.app['users'].addUser('mrclear', 'mrclearsecret')
@@ -1394,8 +1394,15 @@
         #prmglobal.assignRoleToPrincipal('waeup.StudentsOfficer', 'mrclear')
         # Assign local ClearanceOfficer role
-        department = self.app['faculties']['fac1']['dep1']
-        prmlocal = IPrincipalRoleManager(department)
+        self.department = self.app['faculties']['fac1']['dep1']
+        prmlocal = IPrincipalRoleManager(self.department)
         prmlocal.assignRoleToPrincipal('waeup.local.ClearanceOfficer', 'mrclear')
         IWorkflowState(self.student).setState('clearance started')
+        # Add another student for testing
+        other_student = Student()
+        other_student.firstname = u'Dep2'
+        other_student.lastname = u'Student'
+        self.app['students'].addStudent(other_student)
+        self.other_student_path = (
+            'http://localhost/app/students/%s' % other_student.student_id)
         # Login as clearance officer
         self.browser.open(self.login_path)
@@ -1403,4 +1410,7 @@
         self.browser.getControl(name="form.password").value = 'mrclearsecret'
         self.browser.getControl("Login").click()
+
+    def test_handle_clearance_by_co(self):
+        self.init_clearance_officer()
         self.assertMatches('...You logged in...', self.browser.contents)
         # CO is landing on index page
@@ -1419,5 +1429,5 @@
         # has changed
         notify(LocalRoleSetEvent(
-            department, 'waeup.local.ClearanceOfficer', 'mrclear', granted=True))
+            self.department, 'waeup.local.ClearanceOfficer', 'mrclear', granted=True))
         self.browser.open('http://localhost/app/users/mrclear/my_roles')
         self.assertTrue('Clearance Officer' in self.browser.contents)
@@ -1430,12 +1440,6 @@
         self.assertEqual(self.browser.url, self.clearance_path)
         # ... but not other students
-        other_student = Student()
-        other_student.firstname = u'Dep2'
-        other_student.lastname = u'Student'
-        self.app['students'].addStudent(other_student)
-        other_student_path = (
-            'http://localhost/app/students/%s' % other_student.student_id)
         self.assertRaises(
-            Unauthorized, self.browser.open, other_student_path)
+            Unauthorized, self.browser.open, self.other_student_path)
         # Clearance is disabled for this session
         self.browser.open(self.clearance_path)
@@ -1536,4 +1540,30 @@
         IWorkflowInfo(self.student).fireTransition('clear')
         self.assertEqual(self.student.officer_comment, None)
+        return
+
+    def test_handle_mass_clearance_by_co(self):
+        self.init_clearance_officer()
+        # Additional setups according to test above
+        notify(LocalRoleSetEvent(
+            self.department, 'waeup.local.ClearanceOfficer', 'mrclear', granted=True))
+        self.app['configuration']['2004'].clearance_enabled = True
+        IWorkflowState(self.student).setState('clearance requested')
+        # Update the catalog
+        notify(grok.ObjectModifiedEvent(self.student))
+        # The CO can go to the department and clear all students in department
+        self.browser.open('http://localhost/app/faculties/fac1/dep1')
+        self.browser.getLink("Clear all students").click()
+        self.assertTrue('1 students have been cleared' in self.browser.contents)
+        self.browser.open(self.history_path)
+        self.assertTrue('Cleared by Carlo Pitter' in self.browser.contents)
+        logfile = os.path.join(
+            self.app['datacenter'].storage, 'logs', 'students.log')
+        logcontent = open(logfile).read()
+        self.assertTrue(
+            'INFO - mrclear - K1000000 - Cleared' in logcontent)
+        self.browser.open('http://localhost/app/faculties/fac1/dep1')
+        self.browser.getLink("Clear all students").click()
+        self.assertTrue('0 students have been cleared' in self.browser.contents)
+        return
 
     def test_handle_courses_by_ca(self):
