diff --git a/product/ERP5SyncML/Conduit/ERP5Conduit.py b/product/ERP5SyncML/Conduit/ERP5Conduit.py
index c61da7fa888e50e7be13242e732caacf0187c6c0..dbc4f2cdb795c34e7bdc7e729064727a1f207ab1 100755
--- a/product/ERP5SyncML/Conduit/ERP5Conduit.py
+++ b/product/ERP5SyncML/Conduit/ERP5Conduit.py
@@ -150,7 +150,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
             if portal_type == 'Workspace':
               proxy_type = 'folder'
             proxy = px_tool.createEmptyProxy(proxy_type,
-                                   object,portal_type,object_id,docid)
+                                   object,portal_type,object_id,docid=docid)
             proxy.isIndexable = 0 # So it will not be reindexed, this prevent errors
             # Calculate rpath
             utool = getToolByName(object, 'portal_url')
@@ -184,6 +184,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
             conflict_list += self.addNode(xml=sub_xml,object=sub_object,
                             previous_xml=sub_previous_xml, force=force)
     elif xml.nodeName == self.history_tag or self.isHistoryAdd(xml)>0:
+      #return conflict_list # XXX to be removed soon
       # We want to add a workflow action
       wf_tool = getToolByName(object,'portal_workflow')
       wf_id = self.getAttribute(xml,'id')
@@ -199,9 +200,11 @@ class ERP5Conduit(XMLSyncUtilsMixin):
         LOG('addNode, status:',0,status)
         wf_tool.setStatusOf(wf_id,object,status)
     elif xml.nodeName in self.local_role_list:
+      #return conflict_list # XXX to be removed soon
       # We want to add a local role
       #user = self.getParameter(xml,'user')
       roles = self.convertXmlValue(xml.childNodes[0].data,data_type='tokens')
+      roles = list(roles) # Needed for CPS, or we have a CPS error
       user = roles[0]
       roles = roles[1:]
       object.manage_setLocalRoles(user,roles)
@@ -217,7 +220,8 @@ class ERP5Conduit(XMLSyncUtilsMixin):
     LOG('ERP5Conduit',0,'deleteNode')
     LOG('ERP5Conduit',0,'deleteNode, object.id: %s' % object.getId())
     conflict_list = []
-    xml = self.convertToXml(xml)
+    if xml is not None:
+      xml = self.convertToXml(xml)
     if object_id is None:
       LOG('ERP5Conduit',0,'deleteNode, SubObjectDepth: %i' % self.getSubObjectDepth(xml))
       if xml.nodeName == self.xml_object_tag:
@@ -238,6 +242,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
       try:
         object._delObject(object_id)
       except (AttributeError, KeyError):
+        LOG('ERP5Conduit',0,'deleteNode, Unable to delete: %s' % str(object_id))
         pass
     return conflict_list
 
@@ -319,10 +324,16 @@ class ERP5Conduit(XMLSyncUtilsMixin):
               if 1:
                 # This is a conflict
                 isConflict = 1
-                conflict_list += [Conflict(object_path=object.getPhysicalPath(),
-                                           keyword=keyword,
-                                           local_value=current_data,
-                                           remote_value=data)]
+                string_io = StringIO()
+                PrettyPrint(xml,stream=string_io)
+                conflict = Conflict(object_path=object.getPhysicalPath())
+                conflict.setXupdate(string_io.getvalue())
+                conflict_list += [conflict]
+                #conflict_list += [Conflict(object_path=object.getPhysicalPath(),
+                #                           keyword=keyword,
+                #                           xupdate=string_io)]
+                                           #local_value=current_data, # not needed any more
+                                           #remote_value=data)] # not needed any more
           # We will now apply the argument with the method edit
           if args != {} and (isConflict==0 or force):
             LOG('updateNode',0,'object._edit, args: %s' % str(args))
diff --git a/product/ERP5SyncML/Subscription.py b/product/ERP5SyncML/Subscription.py
index 6634b9ad72c29295b24eb8b3c2abe7fcebfb1331..a271c038bdae72a9ef3b1c3f7a57a6eca3a2a35f 100755
--- a/product/ERP5SyncML/Subscription.py
+++ b/product/ERP5SyncML/Subscription.py
@@ -41,13 +41,14 @@ class Conflict(SyncCode):
     remote_value : the value sent by the remote box
 
   """
-  def __init__(self, object_path=None, keyword=None, local_value=None,\
+  def __init__(self, object_path=None, keyword=None, xupdate=None, local_value=None,\
                remote_value=None, domain=None, domain_id=None):
     self.object_path=object_path
     self.keyword = keyword
     self.setLocalValue(local_value)
     self.setRemoteValue(remote_value)
     self.domain = domain
+    self.resetXupdate()
     self.domain_id = domain_id
 
   def getObjectPath(self):
@@ -62,6 +63,37 @@ class Conflict(SyncCode):
     """
     return self.local_value
 
+  def getXupdateList(self):
+    """
+    get the xupdate wich gave an error
+    """
+    xupdate_list = []
+    if len(self.xupdate)>0:
+      for xupdate in self.xupdate:
+        xupdate_list+= [xupdate]
+    return xupdate_list
+
+  def resetXupdate(self):
+    """
+    Reset the xupdate list
+    """
+    self.xupdate = PersistentMapping()
+
+  def setXupdate(self, xupdate):
+    """
+    set the xupdate
+    """
+    if xupdate == None:
+      self.resetXupdate()
+    else:
+      self.xupdate = self.getXupdateList() + [xupdate]
+
+  def setXupdateList(self, xupdate):
+    """
+    set the xupdate
+    """
+    self.xupdate = xupdate
+
   def setLocalValue(self, value):
     """
     get the domain
@@ -318,10 +350,24 @@ class Signature(SyncCode):
     """
     Return the actual action for a partial synchronization
     """
+    LOG('setConflictList, list',0,conflict_list)
     if conflict_list is None:
       self.resetConflictList()
     else:
-      self.conflict_list = conflict_list
+      new_conflict_list = []
+      # If two conflicts are on the same objects, then
+      # we join them, so we have a conflict with many xupdate
+      for conflict in conflict_list:
+        found = None
+        for n_conflict in new_conflict_list:
+          if n_conflict.getObjectPath() == conflict.getObjectPath():
+            found = n_conflict
+        LOG('setConflictList, found',0,found)
+        if found == None:
+          new_conflict_list += [conflict]
+        else:
+          n_conflict.setXupdate(conflict.getXupdateList())
+      self.conflict_list = new_conflict_list
 
 class Subscription(SyncCode):
   """
diff --git a/product/ERP5SyncML/SynchronizationTool.py b/product/ERP5SyncML/SynchronizationTool.py
index 8e09c20bcef87e9298710ba3c3b633cfb9c2aecb..6544a76794ac047e438c7d3e57672883f1862315 100755
--- a/product/ERP5SyncML/SynchronizationTool.py
+++ b/product/ERP5SyncML/SynchronizationTool.py
@@ -245,7 +245,13 @@ class SynchronizationTool( UniqueObject, SimpleItem,
       return_list += [self.list_subscriptions[key]]
     return return_list
 
-  def getConflictList(self):
+  def getDomainList(self):
+    """
+      Returns the list of subscriptions and publications
+    """
+    return self.getSubscriptionList() + self.getPublicationList()
+
+  def getConflictList(self, path=None):
     """
     Retrieve the list of all conflicts
     Here the list is as follow :
@@ -256,23 +262,67 @@ class SynchronizationTool( UniqueObject, SimpleItem,
     for publication in self.getPublicationList():
       pub_conflict_list = publication.getConflictList()
       for conflict in pub_conflict_list:
-        conflict.setDomain('Publication')
+        #conflict.setDomain('Publication')
+        conflict.setDomain(publication)
         conflict.setDomainId(publication.getId())
         conflict_list += [conflict]
     for subscription in self.getSubscriptionList():
       sub_conflict_list = subscription.getConflictList()
       for conflict in sub_conflict_list:
-        conflict.setDomain('Subscription')
+        #conflict.setDomain('Subscription')
+        conflict.setDomain(subscription)
         conflict.setDomainId(subscription.getId())
         conflict_list += [conflict]
+    if path is not None: # Retrieve only conflicts for a given path
+      new_list = []
+      for conflict in conflict_list:
+        if conflict.getObjectPath() == path:
+          new_list += [conflict]
+      return new_list
     return conflict_list
 
-  def getSynchronizationState(self, context):
-    """
-        context       --    the context on which we are looking for state
+  def getSynchronizationState(self, path):
     """
+    context : the context on which we are looking for state
 
+    This functions have to retrieve the synchronization state,
+    it will first look in the conflict list, if nothing is found,
+    then we have to check on a publication/subscription.
 
+    This method returns a mapping between subscription and states
+    """
+    conflict_list = self.getConflictList()
+    state_list= []
+    LOG('getSynchronizationState',0,'path: %s' % str(path))
+    for conflict in conflict_list:
+      if conflict.getObjectPath() == path:
+        LOG('getSynchronizationState',0,'found a conflict: %s' % str(conflict))
+        state_list += [[conflict.getDomain(),self.CONFLICT]]
+    for domain in self.getDomainList():
+      destination = domain.getDestinationPath()
+      LOG('getSynchronizationState',0,'destination: %s' % str(destination))
+      j_path = '/'.join(path)
+      LOG('getSynchronizationState',0,'j_path: %s' % str(j_path))
+      if j_path.find(destination)==0:
+        o_id = j_path[len(destination)+1:].split('/')[0]
+        LOG('getSynchronizationState',0,'o_id: %s' % o_id)
+        subscriber_list = []
+        if domain.domain_type==self.PUB:
+          subscriber_list = domain.getSubscriberList()
+        else:
+          subscriber_list = [domain]
+        for subscriber in subscriber_list:
+          signature = subscriber.getSignature(o_id)
+          if signature is not None:
+            state = signature.getStatus()
+            found = None
+            # Make sure there is not already a conflict giving the state
+            for state_item in state_list:
+              if state_item[0]==subscriber:
+                found = 1
+            if found is None:
+              state_list += [[subscriber,state]]
+    return state_list
 
   def manageLocalValue(self, domain, domain_id, object_path, RESPONSE=None):
     """