diff --git a/product/ERP5SyncML/XMLSyncUtils.py b/product/ERP5SyncML/XMLSyncUtils.py
index e3f047c8f2c827f9a44193beecfed19541feea0e..b1ead0291fc1b13de846617108eb3c5656eca887 100644
--- a/product/ERP5SyncML/XMLSyncUtils.py
+++ b/product/ERP5SyncML/XMLSyncUtils.py
@@ -679,9 +679,9 @@ class XMLSyncUtilsMixin(SyncCode):
     """
     return node.xpath('@*')
 
-  def getSyncMLData(self, domain=None,remote_xml=None,cmd_id=0,
-                          subscriber=None,destination_path=None,
-                          xml_confirmation=None,conduit=None):
+  def getSyncMLData(self, domain=None, remote_xml=None, cmd_id=0,
+                    subscriber=None, xml_confirmation=None, conduit=None,
+                    max=1000, **kw):
     """
     This generate the syncml data message. This returns a string
     with all modification made locally (ie replace, add ,delete...)
@@ -691,7 +691,9 @@ class XMLSyncUtilsMixin(SyncCode):
     """
     local_gid_list = []
     syncml_data = ''
-
+    result = {'finished':0}
+    if isinstance(remote_xml, str) or isinstance(remote_xml, unicode):
+      remote_xml = Parse(remote_xml)
     if subscriber.getRemainingObjectPathList() is None:
       object_list = domain.getObjectList()
       object_path_list = map(lambda x: x.getPhysicalPath(),object_list)
@@ -717,25 +719,18 @@ class XMLSyncUtilsMixin(SyncCode):
               cmd_id += 1
 
     local_gid_list = []
-    #for object in domain.getObjectList():
+    loop = 0
     for object_path in subscriber.getRemainingObjectPathList():
-      #object = subscriber.getDestination()._getOb(object_id)
-      #object = subscriber.getDestination()._getOb(object_id)
-      #try:
       object = self.unrestrictedTraverse(object_path)
-      #except KeyError:
-      #object = None
       status = self.SENT
-      #gid_generator = getattr(object,domain.getGidGenerator(),None)
       object_gid = domain.getGidFromObject(object)
       if object_gid in ('', None):
         continue;
       local_gid_list += [object_gid]
-      #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 loop < max and not \
+          object.id.startswith('.'):
+        # If not we have to cut
         #LOG('getSyncMLData',0,'xml_mapping: %s' % str(domain.xml_mapping))
         #LOG('getSyncMLData',0,'code: %s' % str(self.getAlertCode(remote_xml)))
         #LOG('getSyncMLData',0,'gid_list: %s' % str(local_gid_list))
@@ -801,10 +796,12 @@ class XMLSyncUtilsMixin(SyncCode):
           if not signature.checkMD5(xml_object):
             set_synchronized = 0
             # This object has changed on this side, we have to generate some xmldiff
-            xml_string = self.getXupdateObject(object_xml =                           domain.getXMLFromObject(object),
-                                              old_xml=signature.getXML())
+            xml_string = self.getXupdateObject(
+                                      domain.getXMLFromObject(object),
+                                      signature.getXML())
             if xml_string.count('\n') > self.MAX_LINES:
-              if xml_string.find('--') >= 0: # This make comment fails, so we need to replace
+              # This make comment fails, so we need to replace
+              if xml_string.find('--') >= 0:
                 xml_string = xml_string.replace('--','@-@@-@')
               i = 0
               more_data=1
@@ -824,9 +821,10 @@ class XMLSyncUtilsMixin(SyncCode):
             gid = signature.getRid()#in fisrt, we try with rid if there is one
             if gid == None:
               gid = signature.getGid()
-            syncml_data += self.replaceXMLObject(cmd_id=cmd_id, object=object, 
-                gid=gid, xml_string=xml_string, 
-                more_data=more_data, media_type=subscriber.getMediaType())
+            syncml_data += self.replaceXMLObject(cmd_id=cmd_id, object=object,
+                                                 gid=gid, xml_string=xml_string,
+                                                 more_data=more_data,
+                                                 media_type=subscriber.getMediaType())
             cmd_id += 1
             signature.setTempXML(xml_object)
           # Now we can apply the xupdate from the subscriber
@@ -834,8 +832,8 @@ 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), 
+            conduit.updateNode(xml=subscriber_xupdate, object=object,
+                previous_xml=old_xml, force=(domain.getDomainType() == self.SUB),
                 simulate=0)
             xml_object = domain.getXMLFromObject(object)
             signature.setTempXML(xml_object)
@@ -892,16 +890,23 @@ class XMLSyncUtilsMixin(SyncCode):
                 more_data=more_data, media_type=subscriber.getMediaType())
       else:
         break
-    return (syncml_data,xml_confirmation,cmd_id)
+      loop += 1
+    result['finished'] = 1
+    result['syncml_data'] = syncml_data
+    result['xml_confirmation'] = xml_confirmation
+    result['cmd_id'] = cmd_id
+    return result
 
-  def applyActionList(self, domain=None, subscriber=None,destination_path=None,
-                      cmd_id=0,remote_xml=None,conduit=None,simulate=0):
+  def applyActionList(self, domain=None, subscriber=None, cmd_id=0,
+                      remote_xml=None,conduit=None,simulate=0):
     """
     This just look to a list of action to do, then id applies
     each action one by one, thanks to a conduit
     """
     xml_confirmation = ''
     has_next_action = 0
+    destination = self.unrestrictedTraverse(domain.getDestinationPath())
+    #LOG('applyActionList args',0,'domain : %s\n subscriber : %s\n cmd_id : %s' % (domain, subscriber, cmd_id))
     for action in self.getSyncActionList(remote_xml):
       conflict_list = []
       status_code = self.SUCCESS
@@ -915,7 +920,7 @@ class XMLSyncUtilsMixin(SyncCode):
           gid=rid
       else:
         gid=rid
-      object_id = domain.generateNewIdWithGenerator(object=destination_path,gid=gid)
+      object_id = domain.generateNewIdWithGenerator(object=destination,gid=gid)
       signature = subscriber.getSignatureFromGid(gid)
       if signature != None and rid != gid:
         #in this case, the object was created on another subscriber than erp5
@@ -923,6 +928,7 @@ class XMLSyncUtilsMixin(SyncCode):
         signature.setRid(rid)
       #LOG('gid == rid ?', 0, 'gid=%s, rid=%s' % (gid, rid))
       object = subscriber.getObjectFromGid(gid)
+      #LOG('applyActionList subscriber.getObjectFromGid %s' % gid,0,object)
       if signature == None:
         #LOG('applyActionList, signature is None',0,signature)
         if gid == rid:
@@ -956,10 +962,10 @@ class XMLSyncUtilsMixin(SyncCode):
         if action.nodeName == 'Add':
           # Then store the xml of this new subobject
           if object is None:
-            object_id = domain.generateNewIdWithGenerator(object=destination_path,gid=gid)
+            object_id = domain.generateNewIdWithGenerator(object=destination,gid=gid)
             #if object_id is not None:
             add_data = conduit.addNode(xml=data_subnode, 
-                object=destination_path, object_id=object_id)
+                object=destination, object_id=object_id)
             if add_data['conflict_list'] not in ('', None, []):
               conflict_list += add_data['conflict_list']
             # Retrieve directly the object from addNode
@@ -971,9 +977,9 @@ class XMLSyncUtilsMixin(SyncCode):
           else:
             #Object was retrieve but need to be updated without recreated
             #usefull when an object is only deleted by workflow.
-            object_id = domain.generateNewIdWithGenerator(object=destination_path,gid=gid)
+            object_id = domain.generateNewIdWithGenerator(object=destination,gid=gid)
             add_data = conduit.addNode(xml=data_subnode,
-                                       object=destination_path,
+                                       object=destination,
                                        object_id=object_id,
                                        sub_object=object)
             if add_data['conflict_list'] not in ('', None, []):
@@ -995,7 +1001,7 @@ class XMLSyncUtilsMixin(SyncCode):
                 remote_xml=action)
             cmd_id +=1
         elif action.nodeName == 'Replace':
-          #LOG('SyncModif',0,'object: %s will be updated...' % str(object))
+          #↓LOG('SyncModif',0,'object: %s will be updated...' % str(object))
           if object is not None:
             #LOG('SyncModif',0,'object: %s will be updated...' % object.id)
             signature = subscriber.getSignatureFromGid(gid)
@@ -1005,10 +1011,7 @@ class XMLSyncUtilsMixin(SyncCode):
             conflict_list += conduit.updateNode(xml=data_subnode, object=object,
                               previous_xml=signature.getXML(),force=force,
                               simulate=simulate)
-            #mapping = getattr(object,domain.getXMLMapping(),None)
             xml_object = domain.getXMLFromObject(object)
-            #if mapping is not None:
-            #  xml_object = mapping()
             signature.setTempXML(xml_object)
             if conflict_list != []:
               status_code = self.CONFLICT
@@ -1045,7 +1048,7 @@ class XMLSyncUtilsMixin(SyncCode):
             data_subnode = self.getDataSubNode(action)
           if subscriber.getObjectFromGid(object_id) not in (None, ''):
           #if the object exist:
-            conduit.deleteNode(xml=data_subnode, object=destination_path, 
+            conduit.deleteNode(xml=data_subnode, object=destination, 
                 object_id=subscriber.getObjectFromGid(object_id).getId())
             subscriber.delSignature(gid)
           xml_confirmation += self.SyncMLConfirmation(
@@ -1135,6 +1138,25 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
     """
     pass
 
+  def getConduitByName(self, conduit_name):
+    """
+    Get Conduit Object by given name.
+    The Conduit can be located in Any Products according to naming Convention
+    Products.<Product Name>.Conduit.<Conduit Module> ,if conduit_name equal module's name.
+    By default Conduit must be defined in Products.ERP5SyncML.Conduit.<Conduit Module>
+    """
+    from Products.ERP5SyncML import Conduit
+    if conduit_name.startswith('Products'):
+      path = conduit_name
+      conduit_name = conduit_name.split('.')[-1]
+      conduit_module = __import__(path, globals(), locals(), [''])
+      conduit = getattr(conduit_module, conduit_name)()
+    else:
+      conduit_module = __import__('.'.join([Conduit.__name__, conduit_name]),
+                                  globals(), locals(), [''])
+      conduit = getattr(conduit_module, conduit_name)()
+    return conduit
+
   def SyncModif(self, domain, remote_xml):
     """
     Modification Message, this is used after the first
@@ -1144,12 +1166,9 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
       Send the server modification, this happens after the Synchronization
       initialization
     """
-    from Products.ERP5SyncML import Conduit
     has_response = 0 #check if syncmodif replies to this messages
     cmd_id = 1 # specifies a SyncML message-unique command identifier
     #LOG('SyncModif',0,'Starting... domain: %s' % str(domain))
-    # Get the destination folder
-    destination_path = self.unrestrictedTraverse(domain.getDestinationPath())
 
     first_node = remote_xml.childNodes[0]
     # Get informations from the header
@@ -1193,24 +1212,14 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
 
     alert_code = self.getAlertCode(remote_xml)
     # Import the conduit and get it
-    conduit_name = subscriber.getConduit()
-    if conduit_name.startswith('Products'):
-      path = conduit_name
-      conduit_name = conduit_name.split('.')[-1]
-      conduit_module = __import__(path, globals(), locals(), [''])
-      conduit = getattr(conduit_module, conduit_name)()
-    else:
-      conduit_module = __import__('.'.join([Conduit.__name__, conduit_name]),
-                                  globals(), locals(), [''])
-      conduit = getattr(conduit_module, conduit_name)()
+    conduit = self.getConduitByName(subscriber.getConduit())
     # Then apply the list of actions
-    (xml_confirmation,has_next_action,cmd_id) = self.applyActionList(
-                                         cmd_id=cmd_id,
-                                         domain=domain,
-                                         destination_path=destination_path,
-                                         subscriber=subscriber,
-                                         remote_xml=remote_xml,
-                                         conduit=conduit, simulate=simulate)
+    (xml_confirmation, has_next_action, cmd_id) = self.applyActionList(
+                                      cmd_id=cmd_id,
+                                      domain=domain,
+                                      subscriber=subscriber,
+                                      remote_xml=remote_xml,
+                                      conduit=conduit, simulate=simulate)
     #LOG('SyncModif, has_next_action:',0,has_next_action)
 
     xml_list = []
@@ -1279,14 +1288,13 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
 
         xml('   <Item>\n')
         xml('    <Data>\n')
-        xml("     <Anchor xmlns='syncml:metinf'>\n")
+        xml('     <Anchor xmlns="syncml:metinf">\n')
         xml('      <Next>%s</Next>\n' % subscriber.getNextAnchor())
         xml('     </Anchor>\n')
         xml('    </Data>\n')
         xml('   </Item>\n')
 
         xml('  </Status>\n')
-        
 
     destination_url = ''
     # alert message if we want more data
@@ -1294,16 +1302,68 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
       xml(self.SyncMLAlert(cmd_id, self.WAITING_DATA,
                               subscriber.getTargetURI(),
                               subscriber.getSourceURI(),
-                              subscriber.getLastAnchor(), 
+                              subscriber.getLastAnchor(),
                               subscriber.getNextAnchor()))
     # Now we should send confirmations
     cmd_id_before_getsyncmldata = cmd_id
-    (syncml_data,xml_confirmation,cmd_id) = self.getSyncMLData(domain=domain,
+    cmd_id = cmd_id+1
+    if getattr(domain, 'getActivityEnabled', None) and domain.getActivityEnabled():
+      #use activities to get SyncML data.
+      if not (isinstance(remote_xml, str) or isinstance(remote_xml, unicode)):
+        string_io = StringIO()
+        PrettyPrint(remote_xml,stream=string_io)
+        remote_xml = string_io.getvalue()
+      self.activate().SyncModifActivity(
+                      domain_relative_url = domain.getRelativeUrl(),
+                      remote_xml = remote_xml,
+                      subscriber_relative_url = subscriber.getRelativeUrl(),
+                      cmd_id = cmd_id,
+                      xml_confirmation = xml_confirmation,
+                      syncml_data = '',
+                      cmd_id_before_getsyncmldata = cmd_id_before_getsyncmldata,
+                      xml_list = xml_list,
+                      has_status_list = has_status_list,
+                      has_response = has_response )
+      return {'has_response':1}
+    else:
+      result = self.getSyncMLData(domain=domain,
                              remote_xml=remote_xml,
                              subscriber=subscriber,
-                             destination_path=destination_path,
-                             cmd_id=cmd_id+1,xml_confirmation=xml_confirmation,
+                             cmd_id=cmd_id,xml_confirmation=xml_confirmation,
                              conduit=conduit)
+      syncml_data = result['syncml_data']
+      xml_confirmation = result['xml_confirmation']
+      cmd_id = result['cmd_id']
+      return self.sendSyncModif(syncml_data, cmd_id_before_getsyncmldata,
+                                subscriber, domain, xml_confirmation,
+                                remote_xml, xml_list, has_status_list, has_response)
+
+  def SyncModifActivity(self, **kw):
+    domain = self.unrestrictedTraverse(kw['domain_relative_url'])
+    subscriber = self.unrestrictedTraverse(kw['subscriber_relative_url'])
+    conduit = subscriber.getConduit()
+    result = self.getSyncMLData(domain = domain, subscriber = subscriber,
+                           conduit = conduit, max = 100, **kw)
+    syncml_data = result['syncml_data']
+    finished = result['finished']
+    if not finished:
+      self.activate().SyncModifActivity(**kw)
+    else:
+      xml_confirmation = result['xml_confirmation']
+      cmd_id = result['cmd_id']
+      cmd_id_before_getsyncmldata = kw['cmd_id_before_getsyncmldata']
+      remote_xml = Parse(kw['remote_xml'])
+      xml_list = kw['xml_list']
+      has_status_list = kw['has_status_list']
+      has_response = kw['has_response']
+      return self.sendSyncModif(syncml_data, cmd_id_before_getsyncmldata,
+                              subscriber, domain, xml_confirmation,
+                              remote_xml, xml_list, has_status_list, has_response)
+
+  def sendSyncModif(self, syncml_data, cmd_id_before_getsyncmldata, subscriber,
+                    domain, xml_confirmation, remote_xml, xml_list,
+                    has_status_list, has_response):
+    xml = xml_list.append
     if syncml_data != '':
       xml('  <Sync>\n')
       xml('   <CmdID>%s</CmdID>\n' % cmd_id_before_getsyncmldata)