diff --git a/product/ERP5SyncML/Conduit/ERP5Conduit.py b/product/ERP5SyncML/Conduit/ERP5Conduit.py
index 3f52fcabdc23ca7d9e6df3a3d352be214e167c78..4d3bd619087b0bf19b5a9d848502169dc5a64874 100644
--- a/product/ERP5SyncML/Conduit/ERP5Conduit.py
+++ b/product/ERP5SyncML/Conduit/ERP5Conduit.py
@@ -33,8 +33,7 @@ from Products.CMFCore.utils import getToolByName
 from Products.ERP5SyncML.XupdateUtils import XupdateUtils
 from Products.ERP5Type.Utils import convertToUpperCase
 from Products.ERP5Type.Accessor.TypeDefinition import list_types
-from xml.dom.ext.reader.Sax2 import FromXml
-from xml.dom.minidom import parse, parseString
+from Ft.Xml import Parse
 from DateTime.DateTime import DateTime
 from email.MIMEBase import MIMEBase
 from email import Encoders
@@ -44,10 +43,12 @@ from Products.ERP5Type import Permissions
 from Globals import PersistentMapping
 import pickle
 import string
-from xml.dom.ext import PrettyPrint
 from cStringIO import StringIO
 from xml.sax.saxutils import escape, unescape
 import re, copy
+import cStringIO
+from Ft.Xml.Domlette import Print, PrettyPrint
+
 
 
 from zLOG import LOG
@@ -132,7 +133,8 @@ class ERP5Conduit(XMLSyncUtilsMixin):
       return {'conflict_list':conflict_list, 'object':sub_object}
     LOG('addNode',0,'xml_reconstitued: %s' % str(xml))
     # In the case where this new node is a object to add
-    if xml.nodeName in self.XUPDATE_INSERT_OR_ADD and self.getSubObjectDepth(xml)==0:
+    if xml.nodeName in self.XUPDATE_INSERT_OR_ADD and \
+        self.getSubObjectDepth(xml)==0:
       if self.isHistoryAdd(xml)!=-1: # bad hack XXX to be removed
         for element in self.getXupdateElementList(xml):
           xml = self.getElementFromXupdate(element)
@@ -160,7 +162,8 @@ class ERP5Conduit(XMLSyncUtilsMixin):
             portal_type = self.getObjectType(xml)
           elif xml.nodeName in self.XUPDATE_INSERT_OR_ADD: # Deprecated ???
             portal_type = self.getXupdateObjectType(xml) # Deprecated ???
-          sub_object = self.constructContent(object, object_id, docid, portal_type)
+          sub_object = self.constructContent(object, object_id, docid, 
+              portal_type)
         self.newObject(
                   object=sub_object,
                   xml=xml,
@@ -274,9 +277,9 @@ class ERP5Conduit(XMLSyncUtilsMixin):
     LOG('updateNode, force: ',0,force)
     # we have an xupdate xml
     if xml.nodeName == 'xupdate:modifications':
-      conflict_list += self.applyXupdate(object=object,xupdate=xml,conduit=self,
-                                 previous_xml=previous_xml, force=force, simulate=simulate,
-                                 **kw)
+      conflict_list += self.applyXupdate(object=object, xupdate=xml, 
+          conduit=self,previous_xml=previous_xml, force=force, 
+          simulate=simulate, **kw)
     # we may have only the part of an xupdate
     else:
       args = {}
@@ -342,7 +345,8 @@ class ERP5Conduit(XMLSyncUtilsMixin):
           #   - current_data : the data actually on this box
           isConflict = 0
           if (previous_xml is not None) and (not force): # if no previous_xml, no conflict
-            old_data = self.getObjectProperty(keyword,previous_xml,data_type=data_type)
+            old_data = self.getObjectProperty(keyword, previous_xml, 
+                data_type=data_type)
             #current_data = object.getProperty(keyword)
             current_data = self.getProperty(object, keyword)
             LOG('updateNode',0,'Conflict data: %s' % str(data))
@@ -383,13 +387,13 @@ class ERP5Conduit(XMLSyncUtilsMixin):
         if keyword == 'object':
           # This is the case where we have to call addNode
           LOG('updateNode',0,'we will add sub-object')
-          conflict_list += self.addNode(xml=xml,object=object,force=force,
-                                        simulate=simulate, **kw)['conflict_list']
+          conflict_list += self.addNode(xml=xml, object=object, force=force, 
+              simulate=simulate, **kw)['conflict_list']
         elif keyword == self.history_tag and not simulate:
           # This is the case where we have to call addNode
           LOG('updateNode',0,'we will add history')
           conflict_list += self.addNode(xml=subnode,object=object,force=force,
-                                        simulate=simulate,**kw)['conflict_list']
+              simulate=simulate,**kw)['conflict_list']
         elif keyword in (self.local_role_tag,self.local_permission_tag) and not simulate:
           # This is the case where we have to update Roles or update permission
           LOG('updateNode',0,'we will add a local role')
@@ -397,8 +401,8 @@ class ERP5Conduit(XMLSyncUtilsMixin):
           #roles = self.convertXmlValue(data,data_type='tokens')
           #object.manage_setLocalRoles(user,roles)
           xml = self.getElementFromXupdate(xml)
-          conflict_list += self.addNode(xml=xml,object=object,force=force,
-                                        simulate=simulate,**kw)['conflict_list']
+          conflict_list += self.addNode(xml=xml, object=object, force=force, 
+              simulate=simulate,**kw)['conflict_list']
       elif self.isSubObjectModification(xml):
         # We should find the object corresponding to
         # this update, so we have to look in the previous_xml
@@ -421,8 +425,21 @@ class ERP5Conduit(XMLSyncUtilsMixin):
               sub_xml = self.getSubObjectXupdate(xml)
               LOG('updateNode',0,'sub_xml: %s' % str(sub_xml))
               # Then do the udpate
-              conflict_list += self.updateNode(xml=sub_xml,object=sub_object, force=force,
-                              previous_xml=sub_previous_xml,simulate=simulate, **kw)
+              conflict_list += self.updateNode(xml=sub_xml, object=sub_object, force=force, 
+                              previous_xml=sub_previous_xml, simulate=simulate, **kw)
+        elif previous_xml is None and xml is not None and sub_object_id is not None:
+          sub_object = None
+          try:
+            sub_object = object[sub_object_id]
+          except KeyError:
+            pass
+          if sub_object is not None:
+            sub_xml = self.getSubObjectXupdate(xml)
+            conflict_list += self.updateNode(xml=sub_xml,
+                                             object=sub_object,
+                                             force=force,
+                                             simulate=simulate,
+                                             **kw)
         elif previous_xml is None and xml is not None and sub_object_id is not None:
           sub_object = None
           try:
@@ -438,7 +455,8 @@ class ERP5Conduit(XMLSyncUtilsMixin):
                                              **kw)
     return conflict_list
 
-  security.declareProtected(Permissions.AccessContentsInformation,'getFormatedArgs')
+  security.declareProtected(Permissions.AccessContentsInformation, 
+      'getFormatedArgs')
   def getFormatedArgs(self, args=None):
     """
     This lookd inside the args dictionnary and then
@@ -484,19 +502,21 @@ class ERP5Conduit(XMLSyncUtilsMixin):
             return 0
     return 1
 
-  security.declareProtected(Permissions.AccessContentsInformation,'getSubObjectXupdate')
+  security.declareProtected(Permissions.AccessContentsInformation, 
+      'getSubObjectXupdate')
   def getSubObjectXupdate(self, xml):
     """
     This will change the xml in order to change the update
     from the object to the subobject
     """
-    xml = copy.deepcopy(xml)
-    for subnode in self.getAttributeNodeList(xml):
+    xml_copy = xml.cloneNode(True) #make a deepcopy of the node xml
+    for subnode in self.getAttributeNodeList(xml_copy):
       if subnode.nodeName=='select':
         subnode.nodeValue = self.getSubObjectSelect(subnode.nodeValue)
-    return xml
+    return xml_copy
 
-  security.declareProtected(Permissions.AccessContentsInformation,'isHistoryAdd')
+  security.declareProtected(Permissions.AccessContentsInformation, 
+      'isHistoryAdd')
   def isHistoryAdd(self, xml):
     bad_list = (self.history_exp,)
     for subnode in self.getAttributeNodeList(xml):
@@ -510,7 +530,8 @@ class ERP5Conduit(XMLSyncUtilsMixin):
               return -1
     return 0
 
-  security.declareProtected(Permissions.AccessContentsInformation,'isSubObjectModification')
+  security.declareProtected(Permissions.AccessContentsInformation, 
+      'isSubObjectModification')
   def isSubObjectModification(self, xml):
     """
     Check if it is a modification from an subobject
@@ -524,7 +545,8 @@ class ERP5Conduit(XMLSyncUtilsMixin):
             return 1
     return 0
 
-  security.declareProtected(Permissions.AccessContentsInformation,'getSubObjectDepth')
+  security.declareProtected(Permissions.AccessContentsInformation, 
+      'getSubObjectDepth')
   def getSubObjectDepth(self, xml):
     """
     Give the Depth of a subobject modification
@@ -555,7 +577,8 @@ class ERP5Conduit(XMLSyncUtilsMixin):
             return (1 - i)
     return 0
 
-  security.declareProtected(Permissions.AccessContentsInformation,'getSubObjectSelect')
+  security.declareProtected(Permissions.AccessContentsInformation, 
+      'getSubObjectSelect')
   def getSubObjectSelect(self, select):
     """
     Return a string wich is the selection for the subobject
@@ -571,7 +594,8 @@ class ERP5Conduit(XMLSyncUtilsMixin):
       select = new_value
     return select
 
-  security.declareProtected(Permissions.AccessContentsInformation,'getSubObjectId')
+  security.declareProtected(Permissions.AccessContentsInformation, 
+      'getSubObjectId')
   def getSubObjectId(self, xml):
     """
     Return the id of the subobject in an xupdate modification
@@ -587,7 +611,8 @@ class ERP5Conduit(XMLSyncUtilsMixin):
           return object_id
     return object_id
 
-  security.declareProtected(Permissions.AccessContentsInformation,'getHistoryIdFromSelect')
+  security.declareProtected(Permissions.AccessContentsInformation, 
+      'getHistoryIdFromSelect')
   def getHistoryIdFromSelect(self, xml):
     """
     Return the id of the subobject in an xupdate modification
@@ -604,7 +629,8 @@ class ERP5Conduit(XMLSyncUtilsMixin):
           return object_id
     return object_id
 
-  security.declareProtected(Permissions.AccessContentsInformation,'getSubObjectXml')
+  security.declareProtected(Permissions.AccessContentsInformation,
+      'getSubObjectXml')
   def getSubObjectXml(self, object_id, xml):
     """
     Return the xml of the subobject which as the id object_id
@@ -624,7 +650,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
     """
     for attribute in self.getAttributeNodeList(xml):
       if attribute.nodeName == param:
-        data = attribute.childNodes[0].data
+        data = attribute.value
         return self.convertXmlValue(data,data_type='string')
     return None
 
@@ -635,7 +661,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
     """
     for subnode in self.getElementNodeList(xml):
       if subnode.nodeName == 'docid':
-        data = subnode.childNodes[0].data
+        data = subnode.childNodes[0].value
         return self.convertXmlValue(data)
     return None
 
@@ -669,7 +695,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
       LOG('Conduit.convertToXml xml',0,repr(xml))
       if type(xml) is type(u'a'):
         xml = xml.encode('utf-8')
-      xml = parseString(xml)
+      xml = Parse(xml)
       LOG('Conduit.convertToXml not failed',0,'ok')
       xml = xml.childNodes[0] # Because we just created a new xml
     # If we have the xml from the node erp5, we just take the subnode
@@ -811,7 +837,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
       #PrettyPrint(xml,xml_string)
       #xml_string = xml_string.getvalue()
       #xml_string = unicode(xml_string,encoding='utf-8')
-      xml_string = xml.toxml(encoding='utf-8')
+      xml_string = self.nodeToString(xml)
       xml_string = unicode(xml_string,encoding='utf-8')
       #if type(xml_string) is type (u'a'):
       #  xml_string = xml_string.encode('utf-8')
@@ -840,12 +866,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
       if select_id is not None:
         result += ' id=%s' % select_id
       result +=  '>'
-      # Then dumps the xml and remove what we does'nt want
-      #xml_string = StringIO()
-      #PrettyPrint(xml,xml_string)
-      #xml_string = xml_string.getvalue()
-      #xml_string = unicode(xml_string,encoding='utf-8')
-      xml_string = xml.toxml(encoding='utf-8')
+      xml_string = self.nodeToString(xml)
       xml_string = unicode(xml_string,encoding='utf-8')
       maxi = xml_string.find('>')+1
       result += xml_string[maxi:xml_string.find('</%s>' % xml.nodeName)]
@@ -929,7 +950,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
     """
     conflict_list = []
     if type(xupdate) in (type('a'),type(u'a')):
-      xupdate = parseString(xupdate)
+      xupdate = Parse(xupdate)
     #When xupdate mix different object, (like object and his subobject) we need to treat them separatly
     if self.isMixedXupdate(xupdate):
       #return to updateNode with only one line
@@ -967,7 +988,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
     nb_sub = len(subnode_list)
     comp = 0
     for subnode in subnode_list:
-      value = subnode.getAttribute('select')
+      value = self.getAttribute(subnode, 'select')
       if re.search(self.object_exp, value):
         comp += 1
     if nb_sub == comp:
@@ -1043,7 +1064,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
     if wf_id is None: # History added by xupdate
       wf_id = self.getHistoryIdFromSelect(xml)
       LOG('addNode, workflow_history id:',0,wf_id)
-      LOG('addNode, workflow_history xml:',0,xml.toxml())
+      #LOG('addNode, workflow_history xml:',0,xml.toxml())#toxml isn't in 4Suite
       LOG('addNode, workflow_history xml.getElmentNodeList:',0,self.getElementNodeList(xml))
       xml = self.getElementNodeList(xml)[0]
     LOG('addNode, workflow_history id:',0,wf_id)
@@ -1152,3 +1173,14 @@ class ERP5Conduit(XMLSyncUtilsMixin):
 #        conflict.setRemoteValue(status)
 #        conflict_list += [conflict]
 #    return conflict_list
+
+  def nodeToString(self, node):
+    """
+    return an xml string corresponding to the node
+    """
+    buf = cStringIO.StringIO()
+    Print(node, stream=buf, encoding='utf-8')
+    xml_string = buf.getvalue()
+    buf.close() 
+    return xml_string
+
diff --git a/product/ERP5SyncML/Publication.py b/product/ERP5SyncML/Publication.py
index 4ba43575c994c5adbb4eec9140f93eed6dd9e180..57657883762914372cd089bb619aad0f9ff214c8 100644
--- a/product/ERP5SyncML/Publication.py
+++ b/product/ERP5SyncML/Publication.py
@@ -153,8 +153,9 @@ class Publication(Subscription):
 
   # Constructor
   def __init__(self, id, title, publication_url, destination_path, 
-      query, xml_mapping, conduit, gpg_key, auth_required=False, 
-      authentication_format='', authentication_type=''):
+      query, xml_mapping, conduit, gpg_key, id_generator, gid_generator,
+      flow_type, auth_required=False, authentication_format='', 
+      authentication_type=''):
     """
       constructor
     """
@@ -166,8 +167,9 @@ class Publication(Subscription):
     #self.list_subscribers = PersistentMapping()
     self.domain_type = self.PUB
     self.gpg_key = gpg_key
-    self.setGidGenerator(None)
-    self.setIdGenerator(None)
+    self.setGidGenerator(gid_generator)
+    self.setFlowType(flow_type)
+    self.setSynchronizationIdGenerator(id_generator)
     self.setConduit(conduit)
     Folder.__init__(self, id)
     self.title = title
diff --git a/product/ERP5SyncML/PublicationSynchronization.py b/product/ERP5SyncML/PublicationSynchronization.py
index 444d4200319c97171060144f71f2c2dfc65fa43b..60cb1e274de3ff941f614c82f74a37330fc79f7a 100644
--- a/product/ERP5SyncML/PublicationSynchronization.py
+++ b/product/ERP5SyncML/PublicationSynchronization.py
@@ -29,8 +29,7 @@
 import smtplib # to send emails
 from Publication import Publication,Subscriber
 from Subscription import Signature
-from xml.dom.ext.reader.Sax2 import FromXmlStream, FromXml
-from xml.dom.minidom import parse, parseString
+from Ft.Xml import Parse
 from XMLSyncUtils import XMLSyncUtils
 from Conduit.ERP5Conduit import ERP5Conduit
 from Products.CMFCore.utils import getToolByName
@@ -142,6 +141,13 @@ class PublicationSynchronization(XMLSyncUtils):
           xml(' <SyncBody>\n')
           xml(self.SyncMLStatus(cmd_id, subscriber.getSubscriptionUrl(), 
             publication.getPublicationUrl(), auth_code))
+          cmd_id += 1
+          if auth_code == self.AUTH_ACCEPTED:
+            # alert message
+            xml(self.SyncMLAlert(cmd_id, sync_type, 
+              subscriber.getSubscriptionUrl(), publication.getPublicationUrl(),
+              subscriber.getLastAnchor(), subscriber.getNextAnchor()))
+            cmd_id += 1
           xml(' </SyncBody>\n')
           xml('</SyncML>\n')
           xml_a = ''.join(xml_list)
@@ -221,7 +227,7 @@ class PublicationSynchronization(XMLSyncUtils):
 
     if xml_client is not None:
       if isinstance(xml_client, str) or isinstance(xml_client, unicode):
-        xml_client = parseString(xml_client)
+        xml_client = Parse(xml_client)
       first_node = xml_client.childNodes[0]
 
       if first_node.nodeName != "SyncML":
diff --git a/product/ERP5SyncML/Subscription.py b/product/ERP5SyncML/Subscription.py
index 5cae6b5435b08065c3cdcdfb39e017550f23ad99..fb2a94da8f12fe51f32de7708d45c8df81aa8363 100644
--- a/product/ERP5SyncML/Subscription.py
+++ b/product/ERP5SyncML/Subscription.py
@@ -642,8 +642,9 @@ class Subscription(Folder, SyncCode):
                               )
 
   # Constructor
-  def __init__(self, id, title, publication_url, subscription_url, destination_path, query, xml_mapping, conduit, gpg_key, login, password, 
-      authentication_format='', authentication_type=''):
+  def __init__(self, id, title, publication_url, subscription_url, 
+      destination_path, query, xml_mapping, conduit, gpg_key, id_generator, 
+      gid_generator, flow_type, login, password):
     """
       We need to create a dictionnary of
       signatures of documents which belong to the synchronisation
@@ -660,14 +661,13 @@ class Subscription(Folder, SyncCode):
     #self.signatures = PersistentMapping()
     self.last_anchor = '00000000T000000Z'
     self.next_anchor = '00000000T000000Z'
-    self.login=login
+    self.flow_type = flow_type
+    self.login = login
     self.password=password
-    self.authentication_format=authentication_format
-    self.authentication_type=authentication_type
     self.domain_type = self.SUB
     self.gpg_key = gpg_key
-    self.setGidGenerator(None)
-    self.setIdGenerator(None)
+    self.setGidGenerator(gid_generator)
+    self.setSynchronizationIdGenerator(id_generator)
     self.setConduit(conduit)
     Folder.__init__(self, id)
     self.title = title
@@ -715,7 +715,7 @@ class Subscription(Folder, SyncCode):
 
   def setXMLMapping(self, value):
     """
-    this the name of the method used in order to get the xml
+    this the name of the method used in order to set the xml
     """
     if value == '':
       value = None
@@ -884,6 +884,20 @@ class Subscription(Folder, SyncCode):
     """
     return self.gid_generator
 
+  def getFlowType(self):
+    """
+    This method return the type of the data within the xml message :
+      - text for VCard's
+      - xml for others
+    """
+    return getattr(self, 'flow_type', 'xml')
+
+  def setFlowType(self, flow_type):
+    """
+    set the flow type (xml or text)
+    """
+    self.flow_type=flow_type
+
   def getLogin(self):
     """
     This method return the login of this subscription
@@ -954,7 +968,7 @@ class Subscription(Folder, SyncCode):
       # It might be a script python
       generator = getattr(object,gid_gen)
       o_gid = generator() # XXX - used to be o_gid = generator(object=object) which is redundant
-      # LOG('getGidFromObject',0,'o_gid: %s' % repr(o_gid))
+    LOG('getGidFromObject',0,'o_gid: %s' % repr(o_gid))
     return o_gid
 
   def getObjectFromGid(self, gid):
@@ -1018,10 +1032,7 @@ class Subscription(Folder, SyncCode):
     """
     This tries to generate a new Id
     """
-    # LOG('generateNewId, object: ',0,object.getPhysicalPath())
-    id_generator = self.getIdGenerator()
-    # LOG('generateNewId, id_generator: ',0,id_generator)
-    # LOG('generateNewId, portal_object: ',0,object.getPortalObject())
+    id_generator = self.getSynchronizationIdGenerator()
     if id_generator is not None:
       o_base = aq_base(object)
       new_id = None
@@ -1038,20 +1049,20 @@ class Subscription(Folder, SyncCode):
       return new_id
     return None
 
-  def setIdGenerator(self, method):
+  def setSynchronizationIdGenerator(self, method):
     """
     This set the method name wich allows to generate
     a new id
     """
     if method in ('','None'):
       method = None
-    self.id_generator = method
+    self.synchronization_id_generator = method
 
-  def getIdGenerator(self):
+  def getSynchronizationIdGenerator(self):
     """
     This get the method name wich allows to generate a new id
     """
-    return self.id_generator
+    return getattr(self, 'synchronization_id_generator', None)
 
   def getSubscriptionUrl(self):
     """
@@ -1185,7 +1196,7 @@ class Subscription(Folder, SyncCode):
     """
     if signature.getGid() in self.objectIds():
       self._delObject(signature.getGid())
-    self._setObject( signature.getGid(), aq_base(signature) )
+    self._setObject(signature.getGid(), aq_base(signature) )
 
   def delSignature(self, gid):
     """
@@ -1321,7 +1332,7 @@ class Subscription(Folder, SyncCode):
     #elif format is .... put here the other formats
     else:#if there is no format corresponding with format, raise an error
       LOG('encode : unknown or not implemented format :', 0, format)
-      raise ValueError, "Sorry, the format %s is unknow or not implemented" % format
+      raise ValueError, "Sorry, the server ask for the format %s but it's unknow or not implemented" % format
 
   def decode(self, format, string_to_decode):
     """
diff --git a/product/ERP5SyncML/SubscriptionSynchronization.py b/product/ERP5SyncML/SubscriptionSynchronization.py
index ae05fc9c99a502c665254f6a6db8d136f086678a..dbeec952a471b33c066b0e335ef57f358d4dcd98 100644
--- a/product/ERP5SyncML/SubscriptionSynchronization.py
+++ b/product/ERP5SyncML/SubscriptionSynchronization.py
@@ -28,9 +28,7 @@
 
 import smtplib # to send emails
 from Subscription import Subscription,Signature
-from xml.dom.ext.reader.Sax2 import FromXmlStream, FromXml
-from xml.dom.minidom import parse, parseString
-from xml.dom.ext import PrettyPrint
+from Ft.Xml import Parse
 from XMLSyncUtils import XMLSyncUtils
 import commands
 from Conduit.ERP5Conduit import ERP5Conduit
@@ -99,13 +97,21 @@ class SubscriptionSynchronization(XMLSyncUtils):
     else:
       xml_client = msg
       if isinstance(xml_client, str) or isinstance(xml_client, unicode):
-        xml_client = parseString(xml_client)
+        xml_client = Parse(xml_client)
         next_status = self.getNextSyncBodyStatus(xml_client, None)
         #LOG('readResponse, next status :',0,next_status)
         if next_status is not None:
           status_code = self.getStatusCode(next_status)
           #LOG('readResponse status code :',0,status_code)
           if status_code == self.AUTH_REQUIRED:
+            if self.checkChal(xml_client):
+              authentication_format, authentication_type = self.getChal(xml_client)
+              subscription.setAuthenticationFormat(authentication_format)
+              subscription.setAuthenticationType(authentication_type)
+            else:
+              raise ValueError, "Sorry, the server chalenge for an \
+                  authentication, but the authentication format is not find"
+
             #LOG('readResponse', 0, 'Authentication required')
             response = self.SubSyncCred(id, xml_client)
           elif status_code == self.UNAUTHORIZED:
diff --git a/product/ERP5SyncML/SynchronizationTool.py b/product/ERP5SyncML/SynchronizationTool.py
index 6bb230a57d5e5bdb8534d2412c67fb9f7627022e..1cf90548054f67b6aa49cfc79a171cc7d96a87e8 100644
--- a/product/ERP5SyncML/SynchronizationTool.py
+++ b/product/ERP5SyncML/SynchronizationTool.py
@@ -40,8 +40,7 @@ from Products.ERP5SyncML import Conduit
 from Publication import Publication,Subscriber
 from Products.BTreeFolder2.BTreeFolder2 import BTreeFolder2
 from Subscription import Subscription,Signature
-from xml.dom.ext.reader.Sax2 import FromXmlStream, FromXml
-from xml.dom.minidom import parse, parseString
+from Ft.Xml import Parse
 from Products.ERP5Type import Permissions
 from PublicationSynchronization import PublicationSynchronization
 from SubscriptionSynchronization import SubscriptionSynchronization
@@ -50,7 +49,6 @@ from AccessControl.SecurityManagement import newSecurityManager
 from AccessControl.SecurityManagement import noSecurityManager
 from AccessControl.User import UnrestrictedUser
 from Acquisition import aq_base
-from xml.parsers.expat import ExpatError # parseString error
 import urllib
 import urllib2
 import socket
@@ -162,9 +160,11 @@ class SynchronizationTool( SubscriptionSynchronization,
   security.declareProtected(Permissions.ModifyPortalContent, 
       'manage_addPublication')
   def manage_addPublication(self, title, publication_url, destination_path,
-            query, xml_mapping, conduit, gpg_key, auth_required=0,
-            authentication_format='', authentication_type='', RESPONSE=None):
-    """
+            query, xml_mapping, conduit, gpg_key, 
+            synchronization_id_generator=None, gid_generator=None, 
+            flow_type='xml', auth_required=0, authentication_format='', 
+            authentication_type='', RESPONSE=None):
+    """ 
       create a new publication
     """
     #if not('publications' in self.objectIds()):
@@ -173,8 +173,9 @@ class SynchronizationTool( SubscriptionSynchronization,
     folder = self.getObjectContainer()
     new_id = self.getPublicationIdFromTitle(title)
     pub = Publication(new_id, title, publication_url, destination_path,
-                      query, xml_mapping, conduit, gpg_key, auth_required,
-                      authentication_format, authentication_type)
+                      query, xml_mapping, conduit, gpg_key, 
+                      synchronization_id_generator, gid_generator, flow_type,
+                      auth_required, authentication_format, authentication_type)
     folder._setObject( new_id, pub )
     #if len(self.list_publications) == 0:
     #  self.list_publications = PersistentMapping()
@@ -186,8 +187,9 @@ class SynchronizationTool( SubscriptionSynchronization,
       'manage_addSubscription')
   def manage_addSubscription(self, title, publication_url, subscription_url,
                        destination_path, query, xml_mapping, conduit, gpg_key, 
-                       login=None, password=None, authentication_format='',
-                       authentication_type='',RESPONSE=None):
+                       synchronization_id_generator=None, gid_generator=None, 
+                       flow_type='xml', login=None, password=None, 
+                       RESPONSE=None):
     """
       XXX should be renamed as addSubscription
       create a new subscription
@@ -199,8 +201,8 @@ class SynchronizationTool( SubscriptionSynchronization,
     new_id = self.getSubscriptionIdFromTitle(title)
     sub = Subscription(new_id, title, publication_url, subscription_url,
                        destination_path, query, xml_mapping, conduit, gpg_key,
-                       login, password, authentication_format, 
-                       authentication_type)
+                       synchronization_id_generator, gid_generator, flow_type, 
+                       login, password)
     folder._setObject( new_id, sub )
     #if len(self.list_subscriptions) == 0:
     #  self.list_subscriptions = PersistentMapping()
@@ -211,9 +213,11 @@ class SynchronizationTool( SubscriptionSynchronization,
   security.declareProtected(Permissions.ModifyPortalContent, 
       'manage_editPublication')
   def manage_editPublication(self, title, publication_url, destination_path,
-                       query, xml_mapping, conduit, gpg_key, id_generator,
-                       gid_generator, auth_required=0, authentication_format='',
-                       authentication_type='', RESPONSE=None):
+                       query, xml_mapping, conduit, gpg_key, 
+                       synchronization_id_generator, gid_generator, 
+                       flow_type='xml', auth_required=0, 
+                       authentication_format='', authentication_type='', 
+                       RESPONSE=None):
     """
       modify a publication
     """
@@ -225,8 +229,9 @@ class SynchronizationTool( SubscriptionSynchronization,
     pub.setConduit(conduit)
     pub.setXMLMapping(xml_mapping)
     pub.setGPGKey(gpg_key)
-    pub.setIdGenerator(id_generator)
+    pub.setSynchronizationIdGenerator(synchronization_id_generator)
     pub.setGidGenerator(gid_generator)
+    pub.setFlowType(flow_type)
     pub.setAuthentication(auth_required)
     pub.setAuthenticationFormat(authentication_format)
     pub.setAuthenticationType(authentication_type)
@@ -237,9 +242,9 @@ class SynchronizationTool( SubscriptionSynchronization,
   security.declareProtected(Permissions.ModifyPortalContent, 
       'manage_editSubscription')
   def manage_editSubscription(self, title, publication_url, subscription_url,
-      destination_path, query, xml_mapping, conduit, gpg_key, id_generator,
-      gid_generator,login='', password='', authentication_format='', 
-      authentication_type='', RESPONSE=None):
+      destination_path, query, xml_mapping, conduit, gpg_key, 
+      synchronization_id_generator, gid_generator, flow_type='xml', login='', 
+      password='', RESPONSE=None):
     """
       modify a subscription
     """
@@ -252,12 +257,11 @@ class SynchronizationTool( SubscriptionSynchronization,
     sub.setXMLMapping(xml_mapping)
     sub.setGPGKey(gpg_key)
     sub.setSubscriptionUrl(subscription_url)
-    sub.setIdGenerator(id_generator)
+    sub.setSynchronizationIdGenerator(synchronization_id_generator)
     sub.setGidGenerator(gid_generator)
+    sub.setFlowType(flow_type)
     sub.setLogin(login)
     sub.setPassword(password)
-    sub.setAuthenticationFormat(authentication_format)
-    sub.setAuthenticationType(authentication_type)
     if RESPONSE is not None:
       RESPONSE.redirect('manageSubscriptions')
 
@@ -613,6 +617,7 @@ class SynchronizationTool( SubscriptionSynchronization,
   
   security.declareProtected(Permissions.AccessContentsInformation, 
       'getSubscriberDocumentPath')
+
   def getSubscriberDocumentPath(self, conflict):
     """
     apply the publisher value for all conflict of the given document
@@ -974,7 +979,7 @@ class SynchronizationTool( SubscriptionSynchronization,
         commands.getstatusoutput('rm -f /tmp/%s.gz.gpg' % filename)
       # Get the target and then find the corresponding publication or
       # Subscription
-      xml = parseString(text)
+      xml = Parse(text)
       #XXX this function is not very optimized and should be improved
       url = self.getTarget(xml)
       for publication in self.getPublicationList():
diff --git a/product/ERP5SyncML/XMLSyncUtils.py b/product/ERP5SyncML/XMLSyncUtils.py
index bad3c0ff677b3170084aa173c8fa6db725b48645..7a0b3ce52004ec65471b68658b6a20281531499a 100644
--- a/product/ERP5SyncML/XMLSyncUtils.py
+++ b/product/ERP5SyncML/XMLSyncUtils.py
@@ -29,8 +29,7 @@
 import smtplib
 from Products.ERP5SyncML.SyncCode import SyncCode
 from Products.ERP5SyncML.Subscription import Signature
-from xml.dom.ext.reader.Sax2 import FromXml
-from xml.dom.minidom import parse, parseString
+from Ft.Xml import Parse
 from DateTime import DateTime
 from cStringIO import StringIO
 from xml.dom.ext import PrettyPrint
@@ -200,7 +199,9 @@ class XMLSyncUtilsMixin(SyncCode):
     xml = xml_list.append
     xml('   <Add>\n')
     xml('    <CmdID>%s</CmdID>\n' % cmd_id)
-    xml('    <Meta><Type>%s</Type></Meta>\n' % object.portal_type)
+    xml('    <Meta>\n')
+    xml('     <Type>%s</Type>\n' % object.portal_type)
+    xml('    </Meta>\n')
     xml('    <Item>\n')
     xml('     <Source>\n')
     xml('      <LocURI>%s</LocURI>\n' % gid)
@@ -227,8 +228,8 @@ class XMLSyncUtilsMixin(SyncCode):
     xml('     <Source>\n')
     xml('      <LocURI>%s</LocURI>\n' % object_gid)
     xml('     </Source>\n')
-    xml('     <Data>\n')
-    xml('     </Data>\n')
+    #xml('     <Data>\n')  #this 2 lines seems to be useless
+    #xml('     </Data>\n')
     xml('    </Item>\n')
     xml('   </Delete>\n')
     xml_a = ''.join(xml_list)
@@ -243,7 +244,9 @@ class XMLSyncUtilsMixin(SyncCode):
     xml = xml_list.append
     xml('   <Replace>\n')
     xml('    <CmdID>%s</CmdID>\n' % cmd_id)
-    xml('    <Meta><Type>%s</Type></Meta>\n' % object.portal_type)
+    xml('    <Meta>\n')
+    xml('     <Type>%s</Type>\n' % object.portal_type)
+    xml('    </Meta>\n')
     xml('    <Item>\n')
     xml('     <Source>\n')
     xml('      <LocURI>%s</LocURI>\n' % str(gid))
@@ -290,10 +293,13 @@ class XMLSyncUtilsMixin(SyncCode):
     if xml_mapping is not None:
       if hasattr(object,xml_mapping):
         xml_method = getattr(object,xml_mapping)
-      elif hasattr(object,'manage_FTPget'):
-        xml_method = getattr(object,'manage_FTPget')
+      #elif hasattr(object,'manage_FTPget'):
+      #  xml_method = getattr(object,'manage_FTPget')
       if xml_method is not None:
         xml = xml_method()
+      else:
+        raise ValueError, "Sorry the script or method was not found"
+    LOG('getXMLObject', 0, 'xml_mapping:%s, xml:%s, object:%s xml_method:%s' % (xml_mapping, xml, object, xml_method))
     return xml
 
   def getSessionId(self, xml):
@@ -301,28 +307,17 @@ class XMLSyncUtilsMixin(SyncCode):
     We will retrieve the session id of the message
     """
     session_id = 0
-    for subnode in self.getElementNodeList(xml):
-      if subnode.nodeName == 'SyncML':
-        for subnode1 in self.getElementNodeList(subnode):
-          if subnode1.nodeName == 'SyncHdr':
-            for subnode2 in self.getElementNodeList(subnode1):
-              if subnode2.nodeName == 'SessionID':
-                session_id = int(subnode2.childNodes[0].data)
+    session_id = xml.xpath('string(/SyncML/SyncHdr/SessionID)')
+    session_id = int(session_id)
     return session_id
     
-    
   def getMessageId(self, xml):
     """
     We will retrieve the message id of the message
     """
     message_id = 0
-    for subnode in self.getElementNodeList(xml):
-      if subnode.nodeName == 'SyncML':
-        for subnode1 in self.getElementNodeList(subnode):
-          if subnode1.nodeName == 'SyncHdr':
-            for subnode2 in self.getElementNodeList(subnode1):
-              if subnode2.nodeName == 'MsgID':
-                message_id = int(subnode2.childNodes[0].data)
+    message_id = xml.xpath('string(/SyncML/SyncHdr/MsgID)')
+    message_id = int(message_id)
     return message_id
 
   def getTarget(self, xml):
@@ -330,18 +325,10 @@ class XMLSyncUtilsMixin(SyncCode):
     return the target in the SyncHdr section
     """
     url = ''
-    for subnode in self.getElementNodeList(xml):
-      if subnode.nodeName == 'SyncML':
-        for subnode1 in self.getElementNodeList(subnode):
-          if subnode1.nodeName == 'SyncHdr':
-            for subnode2 in self.getElementNodeList(subnode1):
-              if subnode2.nodeName == 'Target':
-                for subnode3 in self.getElementNodeList(subnode2):
-                  if subnode3.nodeName == 'LocURI':
-                    url = subnode3.childNodes[0].data
+    url = xml.xpath('string(/SyncML/SyncHdr/Target/LocURI)')
+    url = url.encode('utf-8')
     return url
 
-
   def getAlertLastAnchor(self, xml_stream):
     """
       Return the value of the last anchor, in the
@@ -351,23 +338,8 @@ class XMLSyncUtilsMixin(SyncCode):
 
     # Get informations from the body
     client_body = first_node.childNodes[3]
-    for subnode in client_body.childNodes:
-      if subnode.nodeType == subnode.ELEMENT_NODE and \
-          subnode.nodeName == "Alert":
-        for subnode2 in subnode.childNodes:
-          if subnode2.nodeType == subnode2.ELEMENT_NODE and \
-              subnode2.nodeName == "Item":
-            for subnode3 in subnode2.childNodes:
-              if subnode3.nodeType == subnode3.ELEMENT_NODE and \
-                  subnode3.nodeName == "Meta":
-                for subnode4 in subnode3.childNodes:
-                  if subnode4.nodeType == subnode4.ELEMENT_NODE and \
-                      subnode4.nodeName == "Anchor":
-                    for subnode5 in subnode4.childNodes:
-                      # Get the last time we had a synchronization
-                     if subnode5.nodeType == subnode5.ELEMENT_NODE and \
-                         subnode5.nodeName == "Last":
-                        last_anchor = subnode5.childNodes[0].data
+    last_anchor = client_body.xpath('string(/Alert/Item/Meta/Anchor/Last)')
+    last_anchor = last_anchor.encode('utf-8')
     return last_anchor
 
   def getAlertNextAnchor(self, xml_stream):
@@ -381,61 +353,33 @@ class XMLSyncUtilsMixin(SyncCode):
 
     # Get informations from the body
     client_body = first_node.childNodes[3]
-    if client_body.nodeName != "SyncBody":
-      print "This is not a SyncML Body"
-    for subnode in client_body.childNodes:
-      if subnode.nodeType == subnode.ELEMENT_NODE and \
-          subnode.nodeName == "Alert":
-        for subnode2 in subnode.childNodes:
-          if subnode2.nodeType == subnode2.ELEMENT_NODE and \
-              subnode2.nodeName == "Item":
-            for subnode3 in subnode2.childNodes:
-              if subnode3.nodeType == subnode3.ELEMENT_NODE and \
-                  subnode3.nodeName == "Meta":
-                for subnode4 in subnode3.childNodes:
-                 if subnode4.nodeType == subnode4.ELEMENT_NODE and \
-                     subnode4.nodeName == "Anchor":
-                    for subnode5 in subnode4.childNodes:
-                      # Get the last time we had a synchronization
-                      if subnode5.nodeType == subnode5.ELEMENT_NODE and \
-                          subnode5.nodeName == "Next":
-                        next_anchor = subnode5.childNodes[0].data
-                        return next_anchor
+    next_anchor = client_body.xpath('string(/Alert/Item/Meta/Anchor/Next)')
+    next_anchor = next_anchor.encode('utf-8')
+    return next_anchor
 
   def getStatusTarget(self, xml):
     """
       Return the value of the alert code inside the xml_stream
     """
-    # Get informations from the body
-    if xml.nodeName=='Status':
-      for subnode in xml.childNodes:
-        if subnode.nodeType == subnode.ELEMENT_NODE and \
-            subnode.nodeName == 'TargetRef':
-          return subnode.childNodes[0].data
-    return None
+    return xml.xpath('string(TargetRef)')
 
   def getStatusCode(self, xml):
     """
       Return the value of the alert code inside the xml_stream
     """
-    # Get informations from the body
-    if xml.nodeName=='Status':
-      for subnode in xml.childNodes:
-        if subnode.nodeType == subnode.ELEMENT_NODE and \
-            subnode.nodeName == 'Data':
-          return int(subnode.childNodes[0].data)
+    status_code = xml.xpath('string(Data)')
+    if status_code not in ('', None, []):
+      return int(status_code)
     return None
 
   def getStatusCommand(self, xml):
     """
       Return the value of the command inside the xml_stream
     """
-    # Get informations from the body
     if xml.nodeName=='Status':
-      for subnode in xml.childNodes:
-        if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == 'Cmd':
-          return subnode.childNodes[0].data
-    return None
+      return xml.xpath('string(//Status/Cmd)')
+    else:
+      return None
 
   def getCred(self, xml):
     """
@@ -444,111 +388,84 @@ class XMLSyncUtilsMixin(SyncCode):
     format=''
     type=''
     data=''
-    
 
     first_node = xml.childNodes[0]
-    if first_node.nodeName != "SyncML":
-      print "This is not a SyncML message"
-    # Get informations from the header
-    xml_header = first_node.childNodes[1]
-    if xml_header.nodeName != "SyncHdr":
-      LOG('PubSyncModif',0,'This is not a SyncML Header')
-      raise ValueError, "Sorry, This is not a SyncML Header"
+    format = first_node.xpath('string(/SyncML/SyncHdr/Cred/Meta/Format)')
+    type = first_node.xpath('string(/SyncML/SyncHdr/Cred/Meta/Type)')
+    data = first_node.xpath('string(/SyncML/SyncHdr/Cred/Data)')
 
-    for subnode in xml_header.childNodes:
-      if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName=='Cred':
-        for subnode2 in subnode.childNodes:
-          if subnode2.nodeType == subnode2.ELEMENT_NODE and \
-              subnode2.nodeName == 'Meta':
-            for subnode3 in subnode2.childNodes:
-              if subnode3.nodeType == subnode3.ELEMENT_NODE and \
-                  subnode3.nodeName == 'Format':
-                    if len(subnode3.childNodes) > 0:
-                      format=subnode3.childNodes[0].data
-              if subnode3.nodeType == subnode3.ELEMENT_NODE and \
-                  subnode3.nodeName == 'Type':
-                    if len(subnode3.childNodes) > 0:
-                      type=subnode3.childNodes[0].data
-          if subnode2.nodeType == subnode2.ELEMENT_NODE and \
-              subnode2.nodeName == 'Data':
-                if len(subnode2.childNodes) > 0:
-                  data=subnode2.childNodes[0].data
+    format = format.encode('utf-8')
+    type = type.encode('utf-8')
+    data = data.encode('utf-8')
     return (format, type, data)
 
-  def getAlertCode(self, xml_stream):
+  def checkCred(self, xml_stream):
     """
-      Return the value of the alert code inside the full syncml message
+      Check if there's a Cred section in the xml_stream
     """
-    # Get informations from the body
-    first_node = xml_stream.childNodes[0]
-    client_body = first_node.childNodes[3]
-    if client_body.nodeName != "SyncBody":
-      LOG('XMLSyncUtils.getAlertCode',0,"This is not a SyncML Body")
-      raise ValueError, "Sorry, This is not a SyncML Body"
-    alert = 0
-    for subnode in client_body.childNodes:
-      if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName=='Alert':
-        for subnode1 in subnode.childNodes:
-          if subnode1.nodeType == subnode1.ELEMENT_NODE and subnode1.nodeName == 'Data':
-            return int(subnode1.childNodes[0].data)
-    return None
+    if xml_stream.xpath('string(SyncML/SyncHdr/Cred)') not in ('', None, []):
+      return True
+    return False
 
-  def checkCred(self, xml_stream):
+  def getChal(self, xml):
     """
-      Check if there's a Cred section in the xml_stream
+      return the chalenge information : format and type
+    """    
+    format=''
+    type=''
+
+    first_node = xml.childNodes[0]
+    format = first_node.xpath('string(/SyncML/SyncBody/Status/Chal/Meta/Format)')
+    type = first_node.xpath('string(/SyncML/SyncBody/Status/Chal/Meta/Type)')
+
+    format = format.encode('utf-8')
+    type = type.encode('utf-8')
+    return (format, type)
+
+  def checkChal(self, xml_stream):
     """
-    first_node = xml_stream.childNodes[0]
-    # Get informations from the header
-    xml_header = first_node.childNodes[1]
-    if xml_header.nodeName != "SyncHdr":
-      LOG('PubSyncModif',0,'This is not a SyncML Header')
-      raise ValueError, "Sorry, This is not a SyncML Header"
-    cred = 0
-    for subnode in xml_header.childNodes:
-      if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == "Cred":
-        cred=1
-    return cred
+      Check if there's a Chal section in the xml_stream
+    """
+    if xml_stream.xpath('string(SyncML/SyncBody/Status/Chal)') \
+        not in ('', None, []):
+      return True
+    return False
+
+  def getAlertCode(self, xml_stream):
+    """
+      Return the value of the alert code inside the full syncml message
+    """
+    alert_code = xml_stream.xpath('string(SyncML/SyncBody/Alert/Data)')
+    if alert_code not in (None, ''):
+      return int(alert_code)
+    else:
+      return None
 
   def checkAlert(self, xml_stream):
     """
       Check if there's an Alert section in the xml_stream
     """
-    first_node = xml_stream.childNodes[0]
-    client_body = first_node.childNodes[3]
-    if client_body.nodeName != "SyncBody":
-      print "This is not a SyncML Body"
-    alert = 0
-    for subnode in client_body.childNodes:
-      if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == "Alert":
-        alert = 1
+    alert = False
+    if xml_stream.xpath('string(SyncML/SyncBody/Alert)') not in ('', None, []):
+      alert = True
     return alert
 
   def checkSync(self, xml_stream):
     """
       Check if there's an Sync section in the xml_xtream
     """
-    first_node = xml_stream.childNodes[0]
-    client_body = first_node.childNodes[3]
-    if client_body.nodeName != "SyncBody":
-      LOG('checkSync',0,"This is not a SyncML Body")
-      raise ValueError, "Sorry, This is not a SyncML Body"
-    for subnode in client_body.childNodes:
-      if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == "Sync":
-        return 1
-    return 0
+    sync = False
+    if xml_stream.xpath('string(SyncML/SyncBody/Sync)') not in ('', None, []):
+      sync = True
+    return sync
 
   def CheckStatus(self, xml_stream):
     """
       Check if there's a Status section in the xml_xtream
     """
-    first_node = xml_stream.childNodes[0]
-    client_body = first_node.childNodes[3]
-    if client_body.nodeName != "SyncBody":
-      print "This is not a SyncML Body"
-    status = None
-    for subnode in client_body.childNodes:
-      if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == "Status":
-        status = "1"
+    status = False
+    if xml_stream.xpath('string(SyncML/SyncBody/Status)') not in ('', None, []):
+      status = True
     return status
 
   def getNextSyncAction(self, xml_stream, last_action):
@@ -563,18 +480,22 @@ class XMLSyncUtilsMixin(SyncCode):
       print "This is not a SyncML Body"
     next_action = None
     for subnode in client_body.childNodes:
-      if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == "Sync":
+      if subnode.nodeType == subnode.ELEMENT_NODE and \
+          subnode.nodeName == "Sync":
         # if we didn't use this method before
         if last_action == None and len(subnode.childNodes) > 1:
           next_action = subnode.childNodes[1]
         else:
           found = None
           for subnode2 in subnode.childNodes:
-            if subnode2.nodeType == subnode.ELEMENT_NODE and subnode2 != last_action and found is None:
+            if subnode2.nodeType == subnode.ELEMENT_NODE and \
+                subnode2 != last_action and found is None:
               pass
-            elif subnode2.nodeType == subnode.ELEMENT_NODE and subnode2 == last_action and found is None:
+            elif subnode2.nodeType == subnode.ELEMENT_NODE and \
+                subnode2 == last_action and found is None:
               found = 1
-            elif subnode2.nodeType == subnode.ELEMENT_NODE and found is not None:
+            elif subnode2.nodeType == subnode.ELEMENT_NODE and \
+                found is not None:
               next_action = subnode2
               break
     return next_action
@@ -593,7 +514,8 @@ class XMLSyncUtilsMixin(SyncCode):
     next_status = None
     found = None
     for subnode in client_body.childNodes:
-      if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == "Status":
+      if subnode.nodeType == subnode.ELEMENT_NODE and \
+          subnode.nodeName == "Status":
         # if we didn't use this method before
         if last_status == None:
           next_status = subnode
@@ -604,27 +526,32 @@ class XMLSyncUtilsMixin(SyncCode):
           return subnode
     return next_status
 
+  def getDataText(self, action):
+    """
+    return the section data in text form, it's usefull for the VCardConduit
+    """
+    return action.xpath('string(Item/Data)')
+
   def getDataSubNode(self, action):
     """
       Return the node starting with <object....> of the action
     """
-    for subnode in action.childNodes:
-      if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == 'Item':
-        for subnode2 in subnode.childNodes:
-          if subnode2.nodeType == subnode2.ELEMENT_NODE and subnode2.nodeName == 'Data':
-            for subnode3 in subnode2.childNodes:
-              #if subnode3.nodeType == subnode3.ELEMENT_NODE and subnode3.nodeName == 'object':
-              if subnode3.nodeType == subnode3.ELEMENT_NODE:
-                return subnode3
+    if action.xpath('Item/Data') not in ([], None):
+      data_node = action.xpath('Item/Data')[0]
+      if data_node.hasChildNodes() and data_node.childNodes.__len__()>1:
+        return data_node.childNodes[1]
+    return None
 
   def getPartialData(self, action):
     """
       Return the node starting with <object....> of the action
     """
     for subnode in action.childNodes:
-      if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == 'Item':
+      if subnode.nodeType == subnode.ELEMENT_NODE and \
+          subnode.nodeName == 'Item':
         for subnode2 in subnode.childNodes:
-          if subnode2.nodeType == subnode2.ELEMENT_NODE and subnode2.nodeName == 'Data':
+          if subnode2.nodeType == subnode2.ELEMENT_NODE and \
+              subnode2.nodeName == 'Data':
             for subnode3 in subnode2.childNodes:
               #if subnode3.nodeType == subnode3.ELEMENT_NODE and subnode3.nodeName == 'object':
               if subnode3.nodeType == subnode3.COMMENT_NODE:
@@ -639,60 +566,40 @@ class XMLSyncUtilsMixin(SyncCode):
 
     return None
 
-
-  def getAttributeNodeList(self, node):
-    """
-      Return attributesNodes that are ElementNode XXX may be not needed at all
-    """
-    subnode_list = []
-    for subnode in node.attributes:
-      if subnode.nodeType == subnode.ATTRIBUTE_NODE:
-        subnode_list += [subnode]
-    return subnode_list
-
   def getActionId(self, action):
     """
       Return the rid of the object described by the action
     """
     for subnode in action.childNodes:
-      if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == 'Item':
+      if subnode.nodeType == subnode.ELEMENT_NODE and \
+          subnode.nodeName == 'Item':
         for subnode2 in subnode.childNodes:
-          if subnode2.nodeType == subnode2.ELEMENT_NODE and subnode2.nodeName == 'Source':
+          if subnode2.nodeType == subnode2.ELEMENT_NODE and \
+              subnode2.nodeName == 'Source':
             for subnode3 in subnode2.childNodes:
-              if subnode3.nodeType == subnode3.ELEMENT_NODE and subnode3.nodeName == 'LocURI':
+              if subnode3.nodeType == subnode3.ELEMENT_NODE and \
+                  subnode3.nodeName == 'LocURI':
                 return str(subnode3.childNodes[0].data)
 
   def checkActionMoreData(self, action):
     """
       Return the rid of the object described by the action
     """
-    for subnode in action.childNodes:
-      if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == 'Item':
-        for subnode2 in subnode.childNodes:
-          if subnode2.nodeType == subnode2.ELEMENT_NODE and subnode2.nodeName == 'MoreData':
-            return 1
-    return 0
+    if action.xpath('Item/MoreData') not in ([],None) :
+      return True
+    return False
 
   def getActionType(self, action):
     """
       Return the type of the object described by the action
     """
-    for subnode in action.childNodes:
-      if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == 'Meta':
-        for subnode2 in subnode.childNodes:
-          if subnode2.nodeType == subnode2.ELEMENT_NODE and subnode2.nodeName == 'Type':
-            return str(subnode2.childNodes[0].data)
+    return action.xpath('string(Meta/Type)')
 
   def getElementNodeList(self, node):
     """
       Return childNodes that are ElementNode
     """
-    #return node.getElementsByTagName('*')
-    subnode_list = []
-    for subnode in node.childNodes or []:
-      if subnode.nodeType == subnode.ELEMENT_NODE:
-        subnode_list += [subnode]
-    return subnode_list
+    return node.xpath('*')
 
   def getTextNodeList(self, node):
     """
@@ -703,16 +610,12 @@ class XMLSyncUtilsMixin(SyncCode):
       if subnode.nodeType == subnode.TEXT_NODE:
         subnode_list += [subnode]
     return subnode_list
-
+  
   def getAttributeNodeList(self, node):
     """
       Return childNodes that are ElementNode
     """
-    attribute_list = []
-    for subnode in node.attributes.values() or []:
-      if subnode.nodeType == subnode.ATTRIBUTE_NODE:
-        attribute_list += [subnode]
-    return attribute_list
+    return node.xpath('@*')
 
   def getSyncMLData(self, domain=None,remote_xml=None,cmd_id=0,
                           subscriber=None,destination_path=None,
@@ -730,7 +633,6 @@ class XMLSyncUtilsMixin(SyncCode):
     if subscriber.getRemainingObjectPathList() is None:
       object_list = domain.getObjectList()
       object_path_list = map(lambda x: x.getPhysicalPath(),object_list)
-      LOG('getSyncMLData, object_path_list',0,object_path_list)
       subscriber.setRemainingObjectPathList(object_path_list)
 
       #object_gid = domain.getGidFromObject(object)
@@ -744,10 +646,10 @@ class XMLSyncUtilsMixin(SyncCode):
           if signature.getStatus()!=self.PARTIAL: # If partial, then we have a signature
                                                   # but no local object
             xml_object = signature.getXML()
-            if xml_object is not None: # This prevent to delete an object that we
-                                      # were not able to create
-              syncml_data += self.deleteXMLObject(xml_object=signature.getXML() or '',
-                                                  object_gid=object_gid,cmd_id=cmd_id)
+            if xml_object is not None: # This prevent to delete an object that
+                                      # we were not able to create
+              syncml_data += self.deleteXMLObject(xml_object=signature.getXML()\
+                  or '', object_gid=object_gid,cmd_id=cmd_id)
 
     local_gid_list = []
     #for object in domain.getObjectList():
@@ -765,14 +667,16 @@ class XMLSyncUtilsMixin(SyncCode):
       #if gid_generator is not None:
       #  object_gid = gid_generator()
       force = 0
-      if syncml_data.count('\n') < self.MAX_LINES and not object.id.startswith('.'): # If not we have to cut
+      if syncml_data.count('\n') < self.MAX_LINES and not \
+          object.id.startswith('.'): # If not we have to cut
         #LOG('getSyncMLData',0,'xml_mapping: %s' % str(domain.xml_mapping))
+        #LOG('getSyncMLData', 0, 'FlowType: %s' % str(subscriber.getFlowType()))
         #LOG('getSyncMLData',0,'code: %s' % str(self.getAlertCode(remote_xml)))
         #LOG('getSyncMLData',0,'gid_list: %s' % str(local_gid_list))
         #LOG('getSyncMLData',0,'hasSignature: %s' % str(subscriber.hasSignature(object_gid)))
         #LOG('getSyncMLData',0,'alert_code == slowsync: %s' % str(self.getAlertCode(remote_xml)==self.SLOW_SYNC))
         signature = subscriber.getSignature(object_gid)
-        #LOG('getSyncMLData',0,'current object: %s' % str(object.getId()))
+
         # Here we first check if the object was modified or not by looking at dates
         if signature is not None:
           signature.checkSynchronizationNeeded(object)
@@ -781,11 +685,12 @@ class XMLSyncUtilsMixin(SyncCode):
         # For the case it was never synchronized, we have to send everything
         if signature is not None and signature.getXMLMapping()==None:
           pass
-        elif signature==None or (signature.getXML()==None and signature.getStatus()!=self.PARTIAL) or \
-            self.getAlertCode(remote_xml)==self.SLOW_SYNC:
+        elif signature == None or (signature.getXML() == None and \
+            signature.getStatus() != self.PARTIAL) or \
+            self.getAlertCode(remote_xml) == self.SLOW_SYNC:
           #LOG('PubSyncModif',0,'Current object.getPath: %s' % object.getPath())
-          LOG('getSyncMLData',0,'no signature for gid: %s' % object_gid)
-          xml_object = self.getXMLObject(object=object,xml_mapping=domain.xml_mapping)
+          xml_object = self.getXMLObject(object=object, 
+              xml_mapping=domain.xml_mapping)
           xml_string = xml_object
           signature = Signature(gid=object_gid,id=object.getId(),object=object)
           signature.setTempXML(xml_object)
@@ -806,14 +711,15 @@ class XMLSyncUtilsMixin(SyncCode):
             status =self.PARTIAL
             signature.setAction('Add')
             xml_string = '<!--' + short_string + '-->'
-          syncml_data += self.addXMLObject(cmd_id=cmd_id, object=object,gid=object_gid,
-                                  xml_string=xml_string, more_data=more_data)
+          syncml_data += self.addXMLObject(cmd_id=cmd_id, object=object, 
+              gid=object_gid, xml_string=xml_string, more_data=more_data)
           cmd_id += 1
           signature.setStatus(status)
           subscriber.addSignature(signature)
         elif signature.getStatus()==self.NOT_SYNCHRONIZED \
             or signature.getStatus()==self.PUB_CONFLICT_MERGE: # We don't have synchronized this object yet
-          xml_object = self.getXMLObject(object=object,xml_mapping=domain.xml_mapping)
+          xml_object = self.getXMLObject(object=object, 
+              xml_mapping=domain.xml_mapping)
           #LOG('getSyncMLData',0,'checkMD5: %s' % str(signature.checkMD5(xml_object)))
           #LOG('getSyncMLData',0,'getStatus: %s' % str(signature.getStatus()))
           if signature.getStatus()==self.PUB_CONFLICT_MERGE:
@@ -842,8 +748,11 @@ class XMLSyncUtilsMixin(SyncCode):
               signature.setAction('Replace')
               xml_string = '<!--' + short_string + '-->'
             signature.setStatus(status)
-            syncml_data += self.replaceXMLObject(cmd_id=cmd_id,object=object,gid=object_gid,
-                                                xml_string=xml_string, more_data=more_data)
+            if(subscriber.getFlowType() == 'text'):
+              xml_string = self.getXMLObject(object=object, 
+                  xml_mapping=domain.xml_mapping)
+            syncml_data += self.replaceXMLObject(cmd_id=cmd_id, object=object, 
+                gid=object_gid, xml_string=xml_string, more_data=more_data)
             cmd_id += 1
             signature.setTempXML(xml_object)
           # Now we can apply the xupdate from the subscriber
@@ -851,17 +760,17 @@ class XMLSyncUtilsMixin(SyncCode):
           #LOG('getSyncMLData subscriber_xupdate',0,subscriber_xupdate)
           if subscriber_xupdate is not None:
             old_xml = signature.getXML()
-            conduit.updateNode(xml=subscriber_xupdate, object=object,
-                              previous_xml=old_xml,force=(domain.getDomainType==self.SUB),
-                              simulate=0)
-            xml_object = self.getXMLObject(object=object,xml_mapping=domain.xml_mapping)
+            conduit.updateNode(xml=subscriber_xupdate, object=object, 
+                previous_xml=old_xml, force=(domain.getDomainType==self.SUB), 
+                simulate=0)
+            xml_object = self.getXMLObject(object=object, 
+                xml_mapping=domain.xml_mapping)
             signature.setTempXML(xml_object)
           if set_synchronized: # We have to do that after this previous update
             # We should not have this case when we are in CONFLICT_MERGE
             signature.setStatus(self.SYNCHRONIZED)
         elif signature.getStatus()==self.PUB_CONFLICT_CLIENT_WIN:
           # We have decided to apply the update
-          LOG('getSyncMLData',0,'signature.getTempXML(): %s' % str(signature.getTempXML()))
           # XXX previous_xml will be getXML instead of getTempXML because
           # some modification was already made and the update
           # may not apply correctly
@@ -889,12 +798,16 @@ class XMLSyncUtilsMixin(SyncCode):
             xml_string = xml_string.replace('--','@-@@-@')
           xml_string = '<!--' + xml_string + '-->'
           signature.setStatus(status)
+          if(subscriber.getFlowType() == 'text'):
+            xml_string = self.getXMLObject(object=object, 
+                xml_mapping=domain.xml_mapping)
+          LOG('xml_string =', 0, xml_string)
           if signature.getAction()=='Replace':
-            syncml_data += self.replaceXMLObject(cmd_id=cmd_id,object=object,gid=object_gid,
-                                                xml_string=xml_string, more_data=more_data)
+            syncml_data += self.replaceXMLObject(cmd_id=cmd_id, object=object,
+                gid=object_gid, xml_string=xml_string, more_data=more_data)
           elif signature.getAction()=='Add':
-            syncml_data += self.addXMLObject(cmd_id=cmd_id, object=object,gid=object_gid,
-                                    xml_string=xml_string, more_data=more_data)
+            syncml_data += self.addXMLObject(cmd_id=cmd_id, object=object, 
+                gid=object_gid, xml_string=xml_string, more_data=more_data)
     return (syncml_data,xml_confirmation,cmd_id)
 
   def applyActionList(self, domain=None, subscriber=None,destination_path=None,
@@ -918,7 +831,8 @@ class XMLSyncUtilsMixin(SyncCode):
       object = domain.getObjectFromGid(object_gid)
       if signature == None:
         LOG('applyActionList, signature is None',0,signature)
-        signature = Signature(gid=object_gid,status=self.NOT_SYNCHRONIZED,object=object).__of__(subscriber)
+        signature = Signature(gid=object_gid, status=self.NOT_SYNCHRONIZED, 
+            object=object).__of__(subscriber)
         subscriber.addSignature(signature)
       force = signature.getForce()
       LOG('applyActionList',0,'object: %s' % repr(object))
@@ -932,22 +846,28 @@ class XMLSyncUtilsMixin(SyncCode):
             data_subnode = partial_data
           LOG('SyncModif',0,'data_subnode: %s' % data_subnode)
           #data_subnode = FromXml(data_subnode)
-          data_subnode = parseString(data_subnode)
-          data_subnode = data_subnode.childNodes[0] # Because we just created a new xml
+          if subscriber.getFlowType() == 'xml':
+            data_subnode = Parse(data_subnode)
+            data_subnode = data_subnode.childNodes[0] # Because we just created a new xml
           # document, with childNodes[0] a DocumentType and childNodes[1] the Element Node
         else:
-          data_subnode = self.getDataSubNode(next_action)
+          if subscriber.getFlowType() == 'text':
+            data_subnode = self.getDataText(next_action)
+          else:
+            data_subnode = self.getDataSubNode(next_action)
         if next_action.nodeName == 'Add':
           # Then store the xml of this new subobject
           if object is None:
             object_id = domain.generateNewIdWithGenerator(object=destination_path,gid=object_gid)
             #if object_id is not None:
-            add_data = conduit.addNode(xml=data_subnode, object=destination_path,
-                                             object_id=object_id)
-            conflict_list += add_data['conflict_list']
+            add_data = conduit.addNode(xml=data_subnode, 
+                object=destination_path, object_id=object_id)
+            if add_data['conflict_list'] not in ('', None, []):
+              conflict_list += add_data['conflict_list']
             # Retrieve directly the object from addNode
             object = add_data['object']
             LOG('XMLSyncUtils, in ADD add_data',0,add_data)
+            signature.setPath(object.getPhysicalPath())
             LOG('applyActionList',0,'object after add: %s' % repr(object))
           else:
             #Object was retrieve but need to be updated without recreated
@@ -957,7 +877,8 @@ class XMLSyncUtilsMixin(SyncCode):
                                        object=destination_path,
                                        object_id=object_id,
                                        sub_object=object)
-            conflict_list += add_data['conflict_list']
+            if add_data['conflict_list'] not in ('', None, []):
+              conflict_list += add_data['conflict_list']
           if object is not None:
             LOG('SyncModif',0,'addNode, found the object')
             #mapping = getattr(object,domain.getXMLMapping(),None)
@@ -990,7 +911,8 @@ class XMLSyncUtilsMixin(SyncCode):
             if conflict_list != []:
               status_code = self.CONFLICT
               signature.setStatus(self.CONFLICT)
-              signature.setConflictList(signature.getConflictList()+conflict_list)
+              signature.setConflictList(signature.getConflictList() \
+                  + conflict_list)
               string_io = StringIO()
               PrettyPrint(data_subnode,stream=string_io)
               data_subnode_string = string_io.getvalue()
@@ -1012,11 +934,15 @@ class XMLSyncUtilsMixin(SyncCode):
 
         elif next_action.nodeName == 'Delete':
           object_id = signature.getId()
-          conduit.deleteNode(xml=self.getDataSubNode(next_action), object=destination_path,
-                             object_id=object_id)
+          if subscriber.getFlowType == 'text': 
+            data_subnode = self.getDataText(next_action)
+          else:
+            data_subnode = self.getDataSubNode(next_action)
+          conduit.deleteNode(xml=data_subnode, object=destination_path, 
+              object_id=object_id)
           subscriber.delSignature(object_gid)
-          xml_confirmation += self.SyncMLConfirmation(cmd_id,
-                                      object_gid,status_code,'Delete')
+          xml_confirmation += self.SyncMLConfirmation(cmd_id, 
+              object_gid,status_code,'Delete')
       else: # We want to retrieve more data
         signature.setStatus(self.PARTIAL)
         #LOG('SyncModif',0,'setPartialXML: %s' % str(previous_partial))
@@ -1026,8 +952,8 @@ class XMLSyncUtilsMixin(SyncCode):
         signature.setPartialXML(previous_partial)
         #LOG('SyncModif',0,'previous_partial: %s' % str(previous_partial))
         LOG('SyncModif',0,'waiting more data for :%s' % signature.getId())
-        xml_confirmation += self.SyncMLConfirmation(cmd_id,object_gid,
-                                                self.WAITING_DATA,next_action.nodeName)
+        xml_confirmation += self.SyncMLConfirmation(cmd_id, object_gid, 
+            self.WAITING_DATA, next_action.nodeName)
       if conflict_list != [] and signature is not None:
         # We had a conflict
         signature.setStatus(self.CONFLICT)
@@ -1121,11 +1047,13 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
     if domain.domain_type == self.PUB:
       simulate = 1
       for subnode in xml_header.childNodes:
-        if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == "Source":
-	  for subnode2 in subnode.childNodes:
-	    if subnode2.nodeType == subnode2.ELEMENT_NODE and subnode2.nodeName == 'LocURI':
-	      subscription_url = str(subnode2.childNodes[0].data)
-      subscriber = domain.getSubscriber(subscription_url)
+        if subnode.nodeType == subnode.ELEMENT_NODE and \
+                              subnode.nodeName == "Source":
+          for subnode2 in subnode.childNodes:
+            if subnode2.nodeType == subnode2.ELEMENT_NODE and \
+                                  subnode2.nodeName == 'LocURI':
+              subscription_url = str(subnode2.childNodes[0].data)
+              subscriber = domain.getSubscriber(subscription_url)
 
     # We have to check if this message was not already, this can be dangerous
     # to update two times the same object
@@ -1134,6 +1062,7 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
     if not correct_message: # We need to send again the message
       LOG('SyncModif, no correct message:',0,"sending again...")
       last_xml = subscriber.getLastSentMessage()
+      LOG("last_xml :", 0, last_xml)
       if last_xml != '':
         has_response = 1
         if domain.domain_type == self.PUB: # We always reply
@@ -1142,7 +1071,8 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
               xml=last_xml,domain=domain)
         elif domain.domain_type == self.SUB:
           self.sendResponse(from_url=domain.subscription_url, 
-              to_url=domain.publication_url, sync_id=domain.getTitle(), xml=last_xml,domain=domain)
+              to_url=domain.publication_url, sync_id=domain.getTitle(), 
+              xml=last_xml, domain=domain)
       return {'has_response':has_response,'xml':last_xml}
     subscriber.setLastSentMessage('')
 
@@ -1164,7 +1094,8 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
                                   globals(), locals(), [''])
       conduit = getattr(conduit_module, conduit_name)()
     # Then apply the list of actions
-    (xml_confirmation,has_next_action,cmd_id) = self.applyActionList(cmd_id=cmd_id,
+    (xml_confirmation,has_next_action,cmd_id) = self.applyActionList(
+                                         cmd_id=cmd_id,
                                          domain=domain,
                                          destination_path=destination_path,
                                          subscriber=subscriber,
@@ -1178,8 +1109,9 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
     
     # syncml header
     if domain.domain_type == self.PUB:
-      xml(self.SyncMLHeader(subscriber.getSessionId(), subscriber.incrementMessageId(),
-          subscriber.getSubscriptionUrl(), domain.getPublicationUrl()))
+      xml(self.SyncMLHeader(subscriber.getSessionId(), 
+        subscriber.incrementMessageId(), subscriber.getSubscriptionUrl(), 
+        domain.getPublicationUrl()))
     elif domain.domain_type == self.SUB:
       xml(self.SyncMLHeader(domain.getSessionId(), domain.incrementMessageId(),
         domain.getPublicationUrl(), domain.getSubscriptionUrl()))
@@ -1192,11 +1124,11 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
     if has_next_action == 0 and not \
       (domain.domain_type==self.SUB and alert_code==self.SLOW_SYNC):
       (syncml_data,xml_confirmation,cmd_id) = self.getSyncMLData(domain=domain,
-                                       remote_xml=remote_xml,
-                                       subscriber=subscriber,
-                                       destination_path=destination_path,
-                                       cmd_id=cmd_id,xml_confirmation=xml_confirmation,
-                                       conduit=conduit)
+                               remote_xml=remote_xml,
+                               subscriber=subscriber,
+                               destination_path=destination_path,
+                               cmd_id=cmd_id,xml_confirmation=xml_confirmation,
+                               conduit=conduit)
 
     # syncml body
     xml(' <SyncBody>\n')
diff --git a/product/ERP5SyncML/dtml/managePublications.dtml b/product/ERP5SyncML/dtml/managePublications.dtml
index afd939bebfde039f44163327958bfaf5572046f3..091dee809310f57aaa018b3eda60d5165f97cc08 100644
--- a/product/ERP5SyncML/dtml/managePublications.dtml
+++ b/product/ERP5SyncML/dtml/managePublications.dtml
@@ -114,7 +114,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
         </label></div>
         </td>
         <td align="left" valign="top">
-        <input type="text" name="id_generator" value="<dtml-var getIdGenerator>" size="40" />
+        <input type="text" name="synchronization_id_generator" value="<dtml-var getSynchronizationIdGenerator>" size="40" />
         </td>
       </tr>
       <tr>
@@ -127,6 +127,24 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
         <input type="text" name="gid_generator" value="<dtml-var getGidGenerator>" size="40" />
         </td>
       </tr>
+      <tr>
+        <td align="left" valign="top">
+        <div class="form-label">
+        Flow Type
+        </label></div>
+        </td>
+        <td align="left" valign="top">
+        <SELECT name="flow_type" size="1">
+          <dtml-if expr="getFlowType() != 'text'">
+            <OPTION value="xml" selected>XML</option>
+            <OPTION value="text">text</option>
+          <dtml-else>
+            <OPTION value="xml">XML</option>
+            <OPTION value="text" selected>text</option>
+          </dtml-if>
+        </SELECT>
+        </td>
+      </tr>
       <tr>
         <td align="left" valign="top">
         <div class="form-label">
diff --git a/product/ERP5SyncML/dtml/manageSubscriptions.dtml b/product/ERP5SyncML/dtml/manageSubscriptions.dtml
index fb7bd87a3f4570ab66b3af7e1a64feb99324962b..f82c3c98d3e2036509e5373183cef6a622b736b3 100644
--- a/product/ERP5SyncML/dtml/manageSubscriptions.dtml
+++ b/product/ERP5SyncML/dtml/manageSubscriptions.dtml
@@ -124,7 +124,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
         </label></div>
         </td>
         <td align="left" valign="top">
-        <input type="text" name="id_generator" value="<dtml-var getIdGenerator>" size="40" />
+        <input type="text" name="synchronization_id_generator" value="<dtml-var getSynchronizationIdGenerator>" size="40" />
         </td>
       </tr>
       <tr>
@@ -140,41 +140,39 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
       <tr>
         <td align="left" valign="top">
         <div class="form-label">
-        Login
-        </label></div>
-        </td>
-        <td align="left" valign="top">
-        <input type="text" name="login" value="<dtml-var getLogin>" size="40" />
-        </td>
-      </tr>
-      <tr>
-        <td align="left" valign="top">
-        <div class="form-label">
-        Password
+        Flow Type
         </label></div>
         </td>
         <td align="left" valign="top">
-        <input type="password" name="password" value="<dtml-var getPassword>" size="40" />
+        <SELECT name="flow_type" size="1">
+          <dtml-if expr="getFlowType() != 'text'">
+            <OPTION value="xml" selected>XML</option>
+            <OPTION value="text">text</option>          
+          <dtml-else>
+            <OPTION value="xml">XML</option>
+            <OPTION value="text" selected>text</option>          
+          </dtml-if>
+        </SELECT>
         </td>
       </tr>
       <tr>
         <td align="left" valign="top">
         <div class="form-label">
-        Format authentication
+        Login
         </label></div>
         </td>
         <td align="left" valign="top">
-        <input type="text" name="authentication_format" value="<dtml-var getAuthenticationFormat>" size="40" />
+        <input type="text" name="login" value="<dtml-var getLogin>" size="40" />
         </td>
       </tr>
       <tr>
         <td align="left" valign="top">
         <div class="form-label">
-        Type authentication
+        Password
         </label></div>
         </td>
         <td align="left" valign="top">
-        <input type="text" name="authentication_type" value="<dtml-var getAuthenticationType>" size="40" />
+        <input type="password" name="password" value="<dtml-var getPassword>" size="40" />
         </td>
       </tr>
     </table>
diff --git a/product/ERP5SyncML/dtml/manage_addPublication.dtml b/product/ERP5SyncML/dtml/manage_addPublication.dtml
index 8b59f8ee75b287a7add2e014e187d21fc5c2a160..ce095663a206b718bddfebd51917e9cfa43393f1 100644
--- a/product/ERP5SyncML/dtml/manage_addPublication.dtml
+++ b/product/ERP5SyncML/dtml/manage_addPublication.dtml
@@ -110,7 +110,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     </label></div>
     </td>
     <td align="left" valign="top">
-    <input type="text" name="id_generator" size="40" />
+    <input type="text" name="synchronization_id_generator" size="40" />
     </td>
   </tr>
   <tr>
@@ -123,6 +123,19 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     <input type="text" name="gid_generator" size="40" />
     </td>
   </tr>
+  <tr>
+    <td align="left" valign="top">
+    <div class="form-label">
+    Flow Type
+    </label></div>
+    </td>
+    <td align="left" valign="top">
+    <SELECT name="flow_type" size="1">
+        <OPTION value="xml" selected>XML</option>
+        <OPTION value="text">text</option>
+    </SELECT>
+    </td>
+  </tr>
   <tr>
     <td align="left" valign="top">
     <div class="form-label">
diff --git a/product/ERP5SyncML/dtml/manage_addSubscription.dtml b/product/ERP5SyncML/dtml/manage_addSubscription.dtml
index 50a5a2df644b7de8bc77e2d71a73487e5ea10ef5..9d93125120045f925363f2ea72f523ad88e81781 100644
--- a/product/ERP5SyncML/dtml/manage_addSubscription.dtml
+++ b/product/ERP5SyncML/dtml/manage_addSubscription.dtml
@@ -120,7 +120,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     </label></div>
     </td>
     <td align="left" valign="top">
-    <input type="text" name="id_generator" size="40" />
+    <input type="text" name="synchronization_id_generator" size="40" />
     </td>
   </tr>
   <tr>
@@ -136,39 +136,33 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
   <tr>
     <td align="left" valign="top">
     <div class="form-label">
-    Login
+    Flow Type
     </label></div>
     </td>
     <td align="left" valign="top">
-    <input type="text" name="login" size="40" />        </td>
-  </tr> 
-  <tr>
-    <td align="left" valign="top">
-    <div class="form-label">
-    Password
-    </label></div>
-    </td>
-    <td align="left" valign="top">
-    <input type="password" name="password" size="40" />
+    <SELECT name="flow_type" size="1">
+        <OPTION value="xml" selected>XML</option>
+        <OPTION value="text">text</option>
+    </SELECT>
     </td>
   </tr>
   <tr>
     <td align="left" valign="top">
     <div class="form-label">
-    Format authentication
+    Login
     </label></div>
     </td>
     <td align="left" valign="top">
-    <input type="text" name="authentication_format" size="40" />
-    </td>
-  </tr>
+    <input type="text" name="login" size="40" />        </td>
+  </tr> 
+  <tr>
     <td align="left" valign="top">
     <div class="form-label">
-    Type authentication
+    Password
     </label></div>
     </td>
     <td align="left" valign="top">
-    <input type="text" name="authentication_type" size="40" />
+    <input type="password" name="password" size="40" />
     </td>
   </tr>
   <tr>
diff --git a/product/ERP5SyncML/tests/testERP5SyncML.py b/product/ERP5SyncML/tests/testERP5SyncML.py
index bc5a8ca912d88296f9eb2fae947349301212ec51..77e5eb4c267ed0b6f2825c0278f236dad00558f8 100644
--- a/product/ERP5SyncML/tests/testERP5SyncML.py
+++ b/product/ERP5SyncML/tests/testERP5SyncML.py
@@ -46,10 +46,11 @@ try:
     from base64 import b64encode, b64decode
 except ImportError:
     from base64 import encodestring as b64encode, decodestring as b64decode
-class TestERP5SyncML(ERP5TypeTestCase):
+
+
+class TestERP5SyncMLMixin:
 
   # Different variables used for this test
-  run_all_test = 1
   workflow_id = 'edit_workflow'
   first_name1 = 'Sebastien'
   last_name1 = 'Robin'
@@ -91,10 +92,6 @@ class TestERP5SyncML(ERP5TypeTestCase):
   #subscription_url1 = 'client1@localhost'
   #subscription_url2 = 'client2@localhost'
 
-  def getTitle(self):
-    """
-    """
-    return "ERP5 SyncML"
 
   def afterSetUp(self):
     """Setup."""
@@ -117,7 +114,7 @@ class TestERP5SyncML(ERP5TypeTestCase):
       /person_client1 : empty
       /person_client2 : empty
     """
-    return ('erp5_base',)
+    return ('erp5_base','fabien_bt')
 
   def getSynchronizationTool(self):
     return getattr(self.getPortal(), 'portal_synchronizations', None)
@@ -134,6 +131,194 @@ class TestERP5SyncML(ERP5TypeTestCase):
   def getPortalId(self):
     return self.getPortal().getId()
 
+  def login(self, quiet=0):
+    uf = self.getPortal().acl_users
+    uf._doAddUser('fab', 'myPassword', ['Manager'], [])
+    uf._doAddUser('ERP5TypeTestCase', '', ['Manager'], [])
+    uf._doAddUser('syncml', '', ['Manager'], [])
+    user = uf.getUserById('fab').__of__(uf)
+    newSecurityManager(None, user)
+
+  def populatePersonServer(self, quiet=0, run=0):
+    if not run: return
+    if not quiet:
+      ZopeTestCase._print('\nTest Populate Person Server ')
+      LOG('Testing... ',0,'populatePersonServer')
+    self.login()
+    portal = self.getPortal()
+    if not hasattr(portal,'person_server'):
+      portal.portal_types.constructContent(type_name = 'Person Module',
+                                           container = portal,
+                                           id = 'person_server')
+    if not hasattr(portal,'person_client1'):
+      portal.portal_types.constructContent(type_name = 'Person Module',
+                                           container = portal,
+                                           id = 'person_client1')
+    if not hasattr(portal,'person_client2'):
+      portal.portal_types.constructContent(type_name = 'Person Module',
+                                           container = portal,
+                                           id = 'person_client2')
+    person_id = ''
+    person_server = self.getPersonServer()
+    person1 = person_server.newContent(id=self.id1,portal_type='Person')
+    kw = {'first_name':self.first_name1,'last_name':self.last_name1,
+          'description':self.description1}
+    person1.edit(**kw)
+    person2 = person_server.newContent(id=self.id2,portal_type='Person')
+    kw = {'first_name':self.first_name2,'last_name':self.last_name2,
+          'description':self.description2}
+    person2.edit(**kw)
+    nb_person = len(person_server.objectValues())
+    self.failUnless(nb_person==2)
+    return nb_person
+
+  def synchronize(self, id, run=1):
+    """
+    This just define how we synchronize, we have
+    to define it here because it is specific to the unit testing
+    """
+    portal_sync = self.getSynchronizationTool()
+    subscription = portal_sync.getSubscription(id)
+    publication = None
+    for publication in portal_sync.getPublicationList():
+      if publication.getPublicationUrl()==subscription.getSubscriptionUrl():
+        publication = publication
+    self.failUnless(publication is not None)
+    # reset files, because we do sync by files
+    file = open('/tmp/sync_client1','w')
+    file.write('')
+    file.close()
+    file = open('/tmp/sync_client2','w')
+    file.write('')
+    file.close()
+    file = open('/tmp/sync','w')
+    file.write('')
+    file.close()
+    nb_message = 1
+    result = portal_sync.SubSync(subscription.getTitle())
+    while result['has_response']==1:
+      portal_sync.PubSync(publication.getTitle())
+      result = portal_sync.SubSync(subscription.getTitle())
+      nb_message += 1 + result['has_response']
+    return nb_message
+
+  def synchronizeWithBrokenMessage(self, id, run=1):
+    """
+    This just define how we synchronize, we have
+    to define it here because it is specific to the unit testing
+    """
+    portal_sync = self.getSynchronizationTool()
+    #portal_sync.email = None # XXX To be removed
+    subscription = portal_sync.getSubscription(id)
+    publication = None
+    for publication in portal_sync.getPublicationList():
+      if publication.getPublicationUrl()==subscription.getSubscriptionUrl():
+        publication = publication
+    self.failUnless(publication is not None)
+    # reset files, because we do sync by files
+    file = open('/tmp/sync_client1','w')
+    file.write('')
+    file.close()
+    file = open('/tmp/sync_client2','w')
+    file.write('')
+    file.close()
+    file = open('/tmp/sync','w')
+    file.write('')
+    file.close()
+    nb_message = 1
+    result = portal_sync.SubSync(subscription.getTitle())
+    while result['has_response']==1:
+      # We do thing three times, so that we will test
+      # if we manage well duplicate messages
+      portal_sync.PubSync(publication.getTitle())
+      portal_sync.PubSync(publication.getTitle())
+      portal_sync.PubSync(publication.getTitle())
+      result = portal_sync.SubSync(subscription.getTitle())
+      result = portal_sync.SubSync(subscription.getTitle())
+      result = portal_sync.SubSync(subscription.getTitle())
+      nb_message += 1 + result['has_response']
+    return nb_message
+
+  def checkSynchronizationStateIsSynchronized(self, quiet=0, run=1):
+    portal_sync = self.getSynchronizationTool()
+    person_server = self.getPersonServer()
+    for person in person_server.objectValues():
+      state_list = portal_sync.getSynchronizationState(person)
+      for state in state_list:
+        self.failUnless(state[1]==state[0].SYNCHRONIZED)
+    person_client1 = self.getPersonClient1()
+    for person in person_client1.objectValues():
+      state_list = portal_sync.getSynchronizationState(person)
+      for state in state_list:
+        self.failUnless(state[1]==state[0].SYNCHRONIZED)
+    person_client2 = self.getPersonClient2()
+    for person in person_client2.objectValues():
+      state_list = portal_sync.getSynchronizationState(person)
+      for state in state_list:
+        self.failUnless(state[1]==state[0].SYNCHRONIZED)
+    # Check for each signature that the tempXML is None
+    for sub in portal_sync.getSubscriptionList():
+      for m in sub.getSignatureList():
+        self.assertEquals(m.getTempXML(),None)
+        self.assertEquals(m.getPartialXML(),None)
+    for pub in portal_sync.getPublicationList():
+      for sub in pub.getSubscriberList():
+        for m in sub.getSignatureList():
+          self.assertEquals(m.getPartialXML(),None)
+
+  def verifyFirstNameAndLastNameAreSynchronized(self, first_name, 
+      last_name, person_server, person_client):
+    """
+      verify if the first and last name are synchronized
+    """
+    self.failUnless(person_server.getFirstName()==first_name)
+    self.failUnless(person_server.getLastName()==last_name)
+    self.failUnless(person_client.getFirstName()==first_name)
+    self.failUnless(person_client.getLastName()==last_name)
+  
+  def verifyFirstNameAndLastNameAreNotSynchronized(self, first_name, 
+      last_name, person_server, person_client):
+    """
+      verify that the first and last name are NOT synchronized
+    """
+    self.failUnless(person_server.getFirstName()!=first_name)
+    self.failUnless(person_server.getLastName()!=last_name)
+    self.failUnless(person_client.getFirstName()==first_name)
+    self.failUnless(person_client.getLastName()==last_name)
+
+  def checkFirstSynchronization(self, id=None, nb_person=0):
+
+    portal_sync = self.getSynchronizationTool()
+    subscription1 = portal_sync.getSubscription(self.sub_id1)
+    subscription2 = portal_sync.getSubscription(self.sub_id2)
+    self.failUnless(len(subscription1.getObjectList())==nb_person)
+    person_server = self.getPersonServer() # We also check we don't
+                                           # modify initial ob
+    person1_s = person_server._getOb(self.id1)
+    self.failUnless(person1_s.getId()==self.id1)
+    self.failUnless(person1_s.getFirstName()==self.first_name1)
+    self.failUnless(person1_s.getLastName()==self.last_name1)
+    person_client1 = self.getPersonClient1()
+    person1_c = person_client1._getOb(id)
+    self.failUnless(person1_c.getId()==id)
+    self.failUnless(person1_c.getFirstName()==self.first_name1)
+    self.failUnless(person1_c.getLastName()==self.last_name1)
+    self.failUnless(len(subscription2.getObjectList())==nb_person)
+    person_client2 = self.getPersonClient2()
+    person2_c = person_client2._getOb(id) 
+    self.failUnless(person2_c.getId()==id)
+    self.failUnless(person2_c.getFirstName()==self.first_name1)
+    self.failUnless(person2_c.getLastName()==self.last_name1)
+
+
+class TestERP5SyncML(TestERP5SyncMLMixin, ERP5TypeTestCase):
+  
+  run_all_test = True
+  def getTitle(self):
+    """
+    """
+    return "ERP5 SyncML"
+
   def test_01_HasEverything(self, quiet=0, run=run_all_test):
     # Test if portal_synchronizations was created
     if not run: return
@@ -152,9 +337,9 @@ class TestERP5SyncML(ERP5TypeTestCase):
       LOG('Testing... ',0,'test_02_AddPublication')
     portal_id = self.getPortalName()
     portal_sync = self.getSynchronizationTool()
-    portal_sync.manage_addPublication(self.pub_id,self.publication_url,
-                                      '/%s/person_server' % portal_id,'objectValues',
-                                      self.xml_mapping,'ERP5Conduit','')
+    portal_sync.manage_addPublication(self.pub_id,self.publication_url, 
+        '/%s/person_server' % portal_id,'objectValues', self.xml_mapping, 
+        'ERP5Conduit','')
     pub = portal_sync.getPublication(self.pub_id)
     self.failUnless(pub is not None)
 
@@ -165,9 +350,9 @@ class TestERP5SyncML(ERP5TypeTestCase):
       LOG('Testing... ',0,'test_03_AddSubscription1')
     portal_id = self.getPortalId()
     portal_sync = self.getSynchronizationTool()
-    portal_sync.manage_addSubscription(self.sub_id1,self.publication_url,
-                          self.subscription_url1,'/%s/person_client1' % portal_id,'objectValues',
-                          self.xml_mapping,'ERP5Conduit','')
+    portal_sync.manage_addSubscription(self.sub_id1, self.publication_url, 
+        self.subscription_url1,'/%s/person_client1' % portal_id,'objectValues', 
+        self.xml_mapping,'ERP5Conduit','')
     sub = portal_sync.getSubscription(self.sub_id1)
     self.failUnless(sub is not None)
 
@@ -178,59 +363,18 @@ class TestERP5SyncML(ERP5TypeTestCase):
       LOG('Testing... ',0,'test_04_AddSubscription2')
     portal_id = self.getPortalId()
     portal_sync = self.getSynchronizationTool()
-    portal_sync.manage_addSubscription(self.sub_id2,self.publication_url,
-                          self.subscription_url2,'/%s/person_client2' % portal_id,'objectValues',
-                          self.xml_mapping,'ERP5Conduit','')
+    portal_sync.manage_addSubscription(self.sub_id2,self.publication_url, 
+        self.subscription_url2,'/%s/person_client2' % portal_id,'objectValues', 
+        self.xml_mapping,'ERP5Conduit','')
     sub = portal_sync.getSubscription(self.sub_id2)
     self.failUnless(sub is not None)
 
-  def login(self, quiet=0):
-    uf = self.getPortal().acl_users
-    uf._doAddUser('fab', 'myPassword', ['Manager'], [])
-    uf._doAddUser('ERP5TypeTestCase', '', ['Manager'], [])
-    uf._doAddUser('syncml', '', ['Manager'], [])
-    user = uf.getUserById('fab').__of__(uf)
-    newSecurityManager(None, user)
-
-  def populatePersonServer(self, quiet=0, run=run_all_test):
-    if not run: return
-    if not quiet:
-      ZopeTestCase._print('\nTest Populate Person Server ')
-      LOG('Testing... ',0,'populatePersonServer')
-    self.login()
-    portal = self.getPortal()
-    if not hasattr(portal,'person_server'):
-      portal.portal_types.constructContent(type_name = 'Person Module',
-                                           container = portal,
-                                           id = 'person_server')
-    if not hasattr(portal,'person_client1'):
-      portal.portal_types.constructContent(type_name = 'Person Module',
-                                           container = portal,
-                                           id = 'person_client1')
-    if not hasattr(portal,'person_client2'):
-      portal.portal_types.constructContent(type_name = 'Person Module',
-                                           container = portal,
-                                           id = 'person_client2')
-    person_id = ''
-    person_server = self.getPersonServer()
-    person1 = person_server.newContent(id=self.id1,portal_type='Person')
-    kw = {'first_name':self.first_name1,'last_name':self.last_name1,
-          'description':self.description1}
-    person1.edit(**kw)
-    person2 = person_server.newContent(id=self.id2,portal_type='Person')
-    kw = {'first_name':self.first_name2,'last_name':self.last_name2,
-          'description':self.description2}
-    person2.edit(**kw)
-    nb_person = len(person_server.objectValues())
-    self.failUnless(nb_person==2)
-    return nb_person
-
-  def setupPublicationAndSubscription(self, quiet=0, run=1):
+  def setupPublicationAndSubscription(self, quiet=0, run=run_all_test):
     self.test_02_AddPublication(quiet=1,run=1)
     self.test_03_AddSubscription1(quiet=1,run=1)
     self.test_04_AddSubscription2(quiet=1,run=1)
       
-  def setupPublicationAndSubscriptionAndGid(self, quiet=0, run=1):
+  def setupPublicationAndSubscriptionAndGid(self, quiet=0, run=run_all_test):
     self.setupPublicationAndSubscription(quiet=1,run=1)
     def getGid(object):
       return object.getTitle()
@@ -241,9 +385,9 @@ class TestERP5SyncML(ERP5TypeTestCase):
     pub.setGidGenerator(getGid)
     sub1.setGidGenerator(getGid)
     sub2.setGidGenerator(getGid)
-    pub.setIdGenerator('_generateNextId')
-    sub1.setIdGenerator('_generateNextId')
-    sub2.setIdGenerator('_generateNextId')
+    pub.setSynchronizationIdGenerator('_generateNextId')
+    sub1.setSynchronizationIdGenerator('_generateNextId')
+    sub2.setSynchronizationIdGenerator('_generateNextId')
 
   def test_05_GetSynchronizationList(self, quiet=0, run=run_all_test):
     # This test the getSynchronizationList, ie,
@@ -315,73 +459,6 @@ class TestERP5SyncML(ERP5TypeTestCase):
     c_local_role = person_client1.get_local_roles()
     self.assertEqual(s_local_role,c_local_role)
 
-  def synchronize(self, id, run=1):
-    """
-    This just define how we synchronize, we have
-    to define it here because it is specific to the unit testing
-    """
-    portal_sync = self.getSynchronizationTool()
-    subscription = portal_sync.getSubscription(id)
-    publication = None
-    for publication in portal_sync.getPublicationList():
-      if publication.getPublicationUrl()==subscription.getSubscriptionUrl():
-        publication = publication
-    self.failUnless(publication is not None)
-    # reset files, because we do sync by files
-    file = open('/tmp/sync_client1','w')
-    file.write('')
-    file.close()
-    file = open('/tmp/sync_client2','w')
-    file.write('')
-    file.close()
-    file = open('/tmp/sync','w')
-    file.write('')
-    file.close()
-    nb_message = 1
-    result = portal_sync.SubSync(subscription.getTitle())
-    while result['has_response']==1:
-      portal_sync.PubSync(publication.getTitle())
-      result = portal_sync.SubSync(subscription.getTitle())
-      nb_message += 1 + result['has_response']
-    return nb_message
-
-  def synchronizeWithBrokenMessage(self, id, run=1):
-    """
-    This just define how we synchronize, we have
-    to define it here because it is specific to the unit testing
-    """
-    portal_sync = self.getSynchronizationTool()
-    #portal_sync.email = None # XXX To be removed
-    subscription = portal_sync.getSubscription(id)
-    publication = None
-    for publication in portal_sync.getPublicationList():
-      if publication.getPublicationUrl()==subscription.getSubscriptionUrl():
-        publication = publication
-    self.failUnless(publication is not None)
-    # reset files, because we do sync by files
-    file = open('/tmp/sync_client1','w')
-    file.write('')
-    file.close()
-    file = open('/tmp/sync_client2','w')
-    file.write('')
-    file.close()
-    file = open('/tmp/sync','w')
-    file.write('')
-    file.close()
-    nb_message = 1
-    result = portal_sync.SubSync(subscription.getTitle())
-    while result['has_response']==1:
-      # We do thing three times, so that we will test
-      # if we manage well duplicate messages
-      portal_sync.PubSync(publication.getTitle())
-      portal_sync.PubSync(publication.getTitle())
-      portal_sync.PubSync(publication.getTitle())
-      result = portal_sync.SubSync(subscription.getTitle())
-      result = portal_sync.SubSync(subscription.getTitle())
-      result = portal_sync.SubSync(subscription.getTitle())
-      nb_message += 1 + result['has_response']
-    return nb_message
-
   def test_08_FirstSynchronization(self, quiet=0, run=run_all_test):
     # We will try to populate the folder person_client1
     # with the data form person_server
@@ -408,26 +485,7 @@ class TestERP5SyncML(ERP5TypeTestCase):
     for sub in portal_sync.getSubscriptionList():
       self.assertEquals(sub.getSynchronizationType(),SyncCode.TWO_WAY)
     self.failUnless(nb_message2==self.nb_message_first_synchronization)
-    subscription1 = portal_sync.getSubscription(self.sub_id1)
-    subscription2 = portal_sync.getSubscription(self.sub_id2)
-    self.failUnless(len(subscription1.getObjectList())==nb_person)
-    person_server = self.getPersonServer() # We also check we don't
-                                           # modify initial ob
-    person1_s = person_server._getOb(self.id1)
-    self.failUnless(person1_s.getId()==self.id1)
-    self.failUnless(person1_s.getFirstName()==self.first_name1)
-    self.failUnless(person1_s.getLastName()==self.last_name1)
-    person_client1 = self.getPersonClient1()
-    person1_c = person_client1._getOb(self.id1)
-    self.failUnless(person1_c.getId()==self.id1)
-    self.failUnless(person1_c.getFirstName()==self.first_name1)
-    self.failUnless(person1_c.getLastName()==self.last_name1)
-    self.failUnless(len(subscription2.getObjectList())==nb_person)
-    person_client2 = self.getPersonClient2()
-    person2_c = person_client2._getOb(self.id1)
-    self.failUnless(person2_c.getId()==self.id1)
-    self.failUnless(person2_c.getFirstName()==self.first_name1)
-    self.failUnless(person2_c.getLastName()==self.last_name1)
+    self.checkFirstSynchronization(id=self.id1, nb_person=nb_person)
 
   def test_09_FirstSynchronizationWithLongLines(self, quiet=0, run=run_all_test):
     # We will try to populate the folder person_client1
@@ -497,33 +555,6 @@ class TestERP5SyncML(ERP5TypeTestCase):
                                         # for each subscriber
     self.checkSynchronizationStateIsSynchronized()
 
-  def checkSynchronizationStateIsSynchronized(self, quiet=0, run=1):
-    portal_sync = self.getSynchronizationTool()
-    person_server = self.getPersonServer()
-    for person in person_server.objectValues():
-      state_list = portal_sync.getSynchronizationState(person)
-      for state in state_list:
-        self.failUnless(state[1]==state[0].SYNCHRONIZED)
-    person_client1 = self.getPersonClient1()
-    for person in person_client1.objectValues():
-      state_list = portal_sync.getSynchronizationState(person)
-      for state in state_list:
-        self.failUnless(state[1]==state[0].SYNCHRONIZED)
-    person_client2 = self.getPersonClient2()
-    for person in person_client2.objectValues():
-      state_list = portal_sync.getSynchronizationState(person)
-      for state in state_list:
-        self.failUnless(state[1]==state[0].SYNCHRONIZED)
-    # Check for each signature that the tempXML is None
-    for sub in portal_sync.getSubscriptionList():
-      for m in sub.getSignatureList():
-        self.assertEquals(m.getTempXML(),None)
-        self.assertEquals(m.getPartialXML(),None)
-    for pub in portal_sync.getPublicationList():
-      for sub in pub.getSubscriberList():
-        for m in sub.getSignatureList():
-          self.assertEquals(m.getPartialXML(),None)
-
   def checkSynchronizationStateIsConflict(self, quiet=0, run=1):
     portal_sync = self.getSynchronizationTool()
     person_server = self.getPersonServer()
@@ -987,7 +1018,7 @@ class TestERP5SyncML(ERP5TypeTestCase):
     self.failUnless(person_s.getDescription()==self.description3)
     self.failUnless(person_c1.getDescription()==self.description3)
 
-  def test_25_MultiNodeConflict(self, quiet=0, run=1):
+  def test_25_MultiNodeConflict(self, quiet=0, run=run_all_test):
     """
     We will create conflicts with 3 differents nodes, and we will
     solve it by taking one full version of documents.
@@ -1410,27 +1441,7 @@ wuIFtde33Dp3NkZl9fc2Rmw6fDp8OnX2RmX19fJibDqV1dXcKwwrDCsMKwwrDCsA=='
     sub.setAuthenticationFormat(auth_format)
     sub.setAuthenticationType(auth_type)
 
-  def verifyFirstNameAndLastNameAreSynchronized(self, first_name, 
-      last_name, person_server, person_client):
-    """
-      verify if the first and last name are synchronized
-    """
-    self.failUnless(person_server.getFirstName()==first_name)
-    self.failUnless(person_server.getLastName()==last_name)
-    self.failUnless(person_client.getFirstName()==first_name)
-    self.failUnless(person_client.getLastName()==last_name)
-  
-  def verifyFirstNameAndLastNameAreNotSynchronized(self, first_name, 
-      last_name, person_server, person_client):
-    """
-      verify that the first and last name are NOT synchronized
-    """
-    self.failUnless(person_server.getFirstName()!=first_name)
-    self.failUnless(person_server.getLastName()!=last_name)
-    self.failUnless(person_client.getFirstName()==first_name)
-    self.failUnless(person_client.getLastName()==last_name)
-
-  def test_35_authentication(self, quiet=0, run=1):
+  def test_35_authentication(self, quiet=0, run=run_all_test):
     """
       we will test 
       - if we can't synchronize without good authentication for an 
@@ -1507,7 +1518,6 @@ wuIFtde33Dp3NkZl9fc2Rmw6fDp8OnX2RmX19fJibDqV1dXcKwwrDCsMKwwrDCsA=='
     self.synchronize(self.sub_id1)
     self.verifyFirstNameAndLastNameAreNotSynchronized(self.first_name1, 
       self.last_name1, person1_s, person1_c)
-
     
     #with the good password
     self.addAuthenticationToSubscription(self.sub_id1, 'fab', 'myPassword',