Index: /main/waeup.kofa/trunk/src/waeup/kofa/applicants/tests/sample_applicant_data.csv
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/applicants/tests/sample_applicant_data.csv	(revision 8201)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/applicants/tests/sample_applicant_data.csv	(revision 8202)
@@ -1,4 +1,4 @@
-container_code,reg_number,firstname,lastname,date_of_birth,email,course1,sex
-dp2011,1001,Aaren,Pieri,1990-01-02,xx@yy.zz,CERT1,m
-dp2011,1002,Aaren,Finau,1990-01-03,xx@yy.zz,CERT1,m
-dp2011,1003,Aaren,Berson,1990-01-04,xx@yy.zz,CERT1,m
+container_code,reg_number,firstname,lastname,date_of_birth,email,course1,sex,middlename
+dp2011,1001,Aaren,Pieri,1990-01-02,xx@yy.zz,CERT1,m,Peter
+dp2011,1002,Aaren,Finau,1990-01-03,xx@yy.zz,CERT1,m,Claus
+dp2011,1003,Aaren,Berson,1990-01-04,xx@yy.zz,CERT1,m,Alfons
Index: /main/waeup.kofa/trunk/src/waeup/kofa/applicants/tests/sample_applicant_data_update.csv
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/applicants/tests/sample_applicant_data_update.csv	(revision 8201)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/applicants/tests/sample_applicant_data_update.csv	(revision 8202)
@@ -1,4 +1,4 @@
-container_code,reg_number,firstname
-dp2011,1001,Aaren
-dp2011,1002,Alfons
-dp2011,1003,Abraham
+container_code,reg_number,firstname,middlename
+dp2011,1001,Aaren,
+dp2011,1002,Alfons,
+dp2011,1003,Abraham,
Index: /main/waeup.kofa/trunk/src/waeup/kofa/applicants/tests/sample_applicant_data_update2.csv
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/applicants/tests/sample_applicant_data_update2.csv	(revision 8202)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/applicants/tests/sample_applicant_data_update2.csv	(revision 8202)
@@ -0,0 +1,4 @@
+container_code,reg_number,firstname,middlename
+dp2011,1001,Aaren,XXX
+dp2011,1002,Alfons,XXX
+dp2011,1003,Abraham,XXX
Index: /main/waeup.kofa/trunk/src/waeup/kofa/applicants/tests/sample_faulty_applicant_data.csv
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/applicants/tests/sample_faulty_applicant_data.csv	(revision 8201)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/applicants/tests/sample_faulty_applicant_data.csv	(revision 8202)
@@ -1,2 +1,2 @@
-container_code,reg_number,firstname,lastname,date_of_birth,email,course1,sex
-dp2011,1001,Aaren,Pieri,01/02/1990,xx@yy.zz,CERT1,m
+container_code,reg_number,firstname,lastname,date_of_birth,email,course1,sex,middlename
+dp2011,1001,Aaren,Pieri,01/02/1990,xx@yy.zz,CERT1,m,Claus
Index: /main/waeup.kofa/trunk/src/waeup/kofa/applicants/tests/test_batching.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/applicants/tests/test_batching.py	(revision 8201)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/applicants/tests/test_batching.py	(revision 8202)
@@ -48,5 +48,5 @@
     '\n')[0].split(',')
 
-# The same for students
+# The same for applicants
 APPLICANT_SAMPLE_DATA = open(
     os.path.join(os.path.dirname(__file__), 'sample_applicant_data.csv'),
@@ -56,5 +56,4 @@
                  'sample_faulty_applicant_data.csv'), 'rb').read()
 
-
 APPLICANT_HEADER_FIELDS = APPLICANT_SAMPLE_DATA.split(
     '\n')[0].split(',')
@@ -63,4 +62,8 @@
     os.path.join(os.path.dirname(__file__),
                  'sample_applicant_data_update.csv'), 'rb').read()
+
+APPLICANT_SAMPLE_DATA_UPDATE2 = open(
+    os.path.join(os.path.dirname(__file__),
+                 'sample_applicant_data_update2.csv'), 'rb').read()
 
 APPLICANT_HEADER_FIELDS_UPDATE = APPLICANT_SAMPLE_DATA_UPDATE.split(
@@ -231,7 +234,10 @@
         self.csv_file_update = os.path.join(
             self.workdir, 'sample_applicant_data_update.csv')
+        self.csv_file_update2 = os.path.join(
+            self.workdir, 'sample_applicant_data_update2.csv')
         open(self.csv_file, 'wb').write(APPLICANT_SAMPLE_DATA)
         open(self.csv_file_faulty, 'wb').write(FAULTY_APPLICANT_SAMPLE_DATA)
         open(self.csv_file_update, 'wb').write(APPLICANT_SAMPLE_DATA_UPDATE)
+        open(self.csv_file_update2, 'wb').write(APPLICANT_SAMPLE_DATA_UPDATE2)
 
     def test_interface(self):
@@ -306,4 +312,18 @@
             self.csv_file_update, APPLICANT_HEADER_FIELDS_UPDATE, 'update')
         self.assertEqual(num_warns,0)
+        # The middlename import value was None.
+        # Confirm that middlename has not been deleted.
+        container = self.app['applicants']['dp2011']
+        for key in container.keys():
+            if container[key].lastname == 'Pieri':
+                applicant = container[key]
+                break
+        self.assertEqual(applicant.middlename, 'Peter')
+        shutil.rmtree(os.path.dirname(fin_file))
+        # Now we import another file which clears all middlename attributes.
+        num, num_warns, fin_file, fail_file = self.processor.doImport(
+            self.csv_file_update2, APPLICANT_HEADER_FIELDS_UPDATE, 'update')
+        self.assertEqual(num_warns,0)
+        assert applicant.middlename is None
         shutil.rmtree(os.path.dirname(fin_file))
 
Index: /main/waeup.kofa/trunk/src/waeup/kofa/interfaces.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/interfaces.py	(revision 8201)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/interfaces.py	(revision 8202)
@@ -37,4 +37,6 @@
 _ = MessageFactory = zope.i18nmessageid.MessageFactory('waeup.kofa')
 
+DELETIONMARKER = 'XXX'
+
 CREATED = 'created'
 ADMITTED = 'admitted'
Index: /main/waeup.kofa/trunk/src/waeup/kofa/students/batching.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/students/batching.py	(revision 8201)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/students/batching.py	(revision 8202)
@@ -34,5 +34,5 @@
 from waeup.kofa.interfaces import (
     IBatchProcessor, FatalCSVError, IObjectConverter, IUserAccount,
-    IObjectHistory, VALIDATED)
+    IObjectHistory, VALIDATED, DELETIONMARKER)
 from waeup.kofa.interfaces import MessageFactory as _
 from waeup.kofa.students.interfaces import (
@@ -168,5 +168,9 @@
                 history.addMessage(msg)
             elif hasattr(obj, key):
-                setattr(obj, key, value)
+                # Set attribute to None if value is marked for deletion
+                if value == DELETIONMARKER:
+                    setattr(obj, key, None)
+                elif value is not None:
+                    setattr(obj, key, value)
             items_changed += '%s=%s, ' % (key,value)
         parent = self.getParent(row, site)
@@ -296,7 +300,11 @@
             # Skip fields not declared in interface.
             if hasattr(obj, key):
-                setattr(obj, key, value)
-                if key == 'certificate':
-                    value = value.code
+                # Set attribute to None if value is marked for deletion
+                if value == DELETIONMARKER:
+                    setattr(obj, key, None)
+                elif value is not None:
+                    setattr(obj, key, value)
+                    if key == 'certificate':
+                        value = value.code
             items_changed += '%s=%s, ' % (key,value)
         parent = self.getParent(row, site)
@@ -687,5 +695,9 @@
             if hasattr(obj, key) and not key in [
                 'current_session','current_level']:
-                setattr(obj, key, value)
+                # Set attribute to None if value is marked for deletion
+                if value == DELETIONMARKER:
+                    setattr(obj, key, None)
+                elif value is not None:
+                    setattr(obj, key, value)
             items_changed += '%s=%s, ' % (key,value)
         parent = self.getParent(row, site)
Index: /main/waeup.kofa/trunk/src/waeup/kofa/utils/batching.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/utils/batching.py	(revision 8201)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/utils/batching.py	(revision 8202)
@@ -32,5 +32,5 @@
 from waeup.kofa.interfaces import (
     IBatchProcessor, FatalCSVError, IObjectConverter,
-    ICSVExporter)
+    ICSVExporter, DELETIONMARKER)
 
 class BatchProcessor(grok.GlobalUtility):
@@ -204,5 +204,9 @@
             # Skip fields not declared in interface.
             if hasattr(obj, key):
-                setattr(obj, key, value)
+                # Set attribute to None if value is marked for deletion
+                if value == DELETIONMARKER:
+                    setattr(obj, key, None)
+                elif value is not None:
+                    setattr(obj, key, value)
         return
 
Index: /main/waeup.kofa/trunk/src/waeup/kofa/utils/tests/test_batching.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/utils/tests/test_batching.py	(revision 8201)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/utils/tests/test_batching.py	(revision 8202)
@@ -104,8 +104,7 @@
 
     def updateEntry(self, obj, row, site):
-        # This is not strictly necessary, as the default
-        # updateEntry method does exactly the same
         for key, value in row.items():
-            setattr(obj, key, value)
+            if value is not None:
+                setattr(obj, key, value)
 
 class BatchProcessorTests(FunctionalTestCase):
