Index: main/waeup.kofa/trunk/src/waeup/kofa/students/batching.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/students/batching.py	(revision 9000)
+++ main/waeup.kofa/trunk/src/waeup/kofa/students/batching.py	(revision 9001)
@@ -184,4 +184,5 @@
 
         # Update password
+        # XXX: Tale DELETION_MARKER into consideration
         if row.has_key('password'):
             passwd = row.get('password', IGNORE_MARKER)
Index: main/waeup.kofa/trunk/src/waeup/kofa/university/batching.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/university/batching.py	(revision 9000)
+++ main/waeup.kofa/trunk/src/waeup/kofa/university/batching.py	(revision 9001)
@@ -30,7 +30,9 @@
 from zope.catalog.interfaces import ICatalog
 from zope.event import notify
-from zope.securitypolicy.interfaces import IPrincipalRoleManager
+from zope.securitypolicy.interfaces import (
+    IPrincipalRoleManager, IPrincipalRoleMap)
 from waeup.kofa.authentication import LocalRoleSetEvent
-from waeup.kofa.interfaces import IBatchProcessor, IGNORE_MARKER, FatalCSVError
+from waeup.kofa.interfaces import (
+    IBatchProcessor, IGNORE_MARKER, DELETION_MARKER, FatalCSVError)
 from waeup.kofa.university.interfaces import (
     IFacultiesContainer, IFaculty, ICourse, IDepartment, ICertificate,
@@ -95,14 +97,23 @@
         items_changed = ''
 
-        if row.has_key('local_roles'):
-            local_roles = eval(row['local_roles'])
-            for rolemap in local_roles:
-                user = rolemap['user_name']
-                local_role = rolemap['local_role']
-                role_manager = IPrincipalRoleManager(obj)
-                role_manager.assignRoleToPrincipal(local_role, user)
-                notify(LocalRoleSetEvent(obj, local_role, user, granted=True))
-                items_changed += (
-                    '%s=%s, ' % ('local_roles', '%s|%s' % (user,local_role)))
+        if row.has_key('local_roles') and row['local_roles'] not in (
+            None, IGNORE_MARKER):
+            role_manager = IPrincipalRoleManager(obj)
+            role_map = IPrincipalRoleMap(obj)
+            # Remove all existing local roles.
+            for local_role, user_name, setting in role_map.getPrincipalsAndRoles():
+                role_manager.unsetRoleForPrincipal(local_role, user_name)
+                notify(LocalRoleSetEvent(
+                        obj, local_role, user_name, granted=False))
+            # Add new local roles.
+            if row['local_roles'] != DELETION_MARKER:
+                local_roles = eval(row['local_roles'])
+                for rolemap in local_roles:
+                    user = rolemap['user_name']
+                    local_role = rolemap['local_role']
+                    role_manager.assignRoleToPrincipal(local_role, user)
+                    notify(LocalRoleSetEvent(obj, local_role, user, granted=True))
+                    items_changed += (
+                        '%s=%s, ' % ('local_roles', '%s|%s' % (user,local_role)))
             row.pop('local_roles')
 
@@ -122,4 +133,6 @@
             FacultyProcessor, self).checkConversion(row, mode=mode)
         if row.has_key('local_roles'):
+            if row['local_roles'] in (None, DELETION_MARKER, IGNORE_MARKER):
+                return errs, inv_errs, conv_dict
             try:
                 local_roles = eval(row['local_roles'])
Index: main/waeup.kofa/trunk/src/waeup/kofa/university/tests/sample_faculty_data_update.csv
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/university/tests/sample_faculty_data_update.csv	(revision 9001)
+++ main/waeup.kofa/trunk/src/waeup/kofa/university/tests/sample_faculty_data_update.csv	(revision 9001)
@@ -0,0 +1,5 @@
+code,local_roles
+FAC1,XXX
+FAC2,"[{'user_name':'bob','local_role':'waeup.local.DepartmentManager'}]"
+FAC3,<IGNORE>
+FAC4,
Index: main/waeup.kofa/trunk/src/waeup/kofa/university/tests/test_batching.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/university/tests/test_batching.py	(revision 9000)
+++ main/waeup.kofa/trunk/src/waeup/kofa/university/tests/test_batching.py	(revision 9001)
@@ -24,5 +24,6 @@
 from zope.component.hooks import setSite, clearSite
 from zope.component import createObject
-from zope.securitypolicy.interfaces import IPrincipalRoleMap
+from zope.securitypolicy.interfaces import (
+    IPrincipalRoleMap, IPrincipalRoleManager)
 from zope.interface.verify import verifyClass, verifyObject
 from waeup.kofa.interfaces import IBatchProcessor
@@ -42,4 +43,11 @@
 
 FACULTY_HEADER_FIELDS = FACULTY_SAMPLE_DATA.split(
+    '\n')[0].split(',')
+
+FACULTY_SAMPLE_DATA_UPDATE = open(
+    os.path.join(os.path.dirname(__file__), 'sample_faculty_data_update.csv'),
+    'rb').read()
+
+FACULTY_HEADER_FIELDS_UPDATE = FACULTY_SAMPLE_DATA_UPDATE.split(
     '\n')[0].split(',')
 
@@ -108,4 +116,6 @@
         self.csv_file_faculty = os.path.join(self.workdir, 'sample_faculty_data.csv')
         open(self.csv_file_faculty, 'wb').write(FACULTY_SAMPLE_DATA)
+        self.csv_file_faculty_update = os.path.join(self.workdir, 'sample_faculty_data_update.csv')
+        open(self.csv_file_faculty_update, 'wb').write(FACULTY_SAMPLE_DATA_UPDATE)
         return
 
@@ -214,4 +224,56 @@
         self.assertEqual(user_name, 'bob')
         self.assertEqual(local_role, 'waeup.local.DepartmentManager')
+        shutil.rmtree(os.path.dirname(fin_file))
+        return
+
+    def test_import_update(self):
+        self.app['faculties']['FAC2'] = Faculty(code='FAC2')
+        self.app['faculties']['FAC3'] = Faculty(code='FAC3')
+        self.app['faculties']['FAC4'] = Faculty(code='FAC4')
+
+        role_manager1 = IPrincipalRoleManager(self.app['faculties']['FAC1'])
+        role_manager1.assignRoleToPrincipal('alfonsrole', 'alfons')
+        role_map1 = IPrincipalRoleMap(self.app['faculties']['FAC1'])
+        self.assertEqual(len(role_map1.getPrincipalsAndRoles()), 1)
+
+        role_manager2 = IPrincipalRoleManager(self.app['faculties']['FAC2'])
+        role_manager2.assignRoleToPrincipal('alfonsrole', 'alfons')
+        role_map2 = IPrincipalRoleMap(self.app['faculties']['FAC2'])
+        self.assertEqual(len(role_map2.getPrincipalsAndRoles()), 1)
+
+        role_manager3 = IPrincipalRoleManager(self.app['faculties']['FAC3'])
+        role_manager3.assignRoleToPrincipal('alfonsrole', 'alfons')
+        role_map3 = IPrincipalRoleMap(self.app['faculties']['FAC3'])
+        self.assertEqual(len(role_map3.getPrincipalsAndRoles()), 1)
+
+        role_manager4 = IPrincipalRoleManager(self.app['faculties']['FAC4'])
+        role_manager4.assignRoleToPrincipal('alfonsrole', 'alfons')
+        role_map4 = IPrincipalRoleMap(self.app['faculties']['FAC4'])
+        self.assertEqual(len(role_map4.getPrincipalsAndRoles()), 1)
+
+        local_role, user_name, setting = role_map2.getPrincipalsAndRoles()[0]
+        self.assertEqual(user_name, 'alfons')
+        self.assertEqual(local_role, 'alfonsrole')
+
+        num, num_warns, fin_file, fail_file = self.proc.doImport(
+            self.csv_file_faculty_update, FACULTY_HEADER_FIELDS_UPDATE, 'update')
+        self.assertEqual(num_warns,0)
+        # Local roles have been removed in FAC1 due to deletion marker.
+        self.assertEqual(len(role_map1.getPrincipalsAndRoles()), 0)
+        # Old local roles have been removed and new roles have been added in FAC2.
+        self.assertEqual(len(role_map2.getPrincipalsAndRoles()), 1)
+        local_role, user_name, setting = role_map2.getPrincipalsAndRoles()[0]
+        self.assertEqual(user_name, 'bob')
+        self.assertEqual(local_role, 'waeup.local.DepartmentManager')
+        # Local roles are not touched in FAC3 due to ignore marker.
+        self.assertEqual(len(role_map3.getPrincipalsAndRoles()), 1)
+        local_role, user_name, setting = role_map3.getPrincipalsAndRoles()[0]
+        self.assertEqual(user_name, 'alfons')
+        self.assertEqual(local_role, 'alfonsrole')
+        # Local roles are not touched in FAC4 due to empty cell.
+        self.assertEqual(len(role_map4.getPrincipalsAndRoles()), 1)
+        local_role, user_name, setting = role_map4.getPrincipalsAndRoles()[0]
+        self.assertEqual(user_name, 'alfons')
+        self.assertEqual(local_role, 'alfonsrole')
         shutil.rmtree(os.path.dirname(fin_file))
         return
