mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

ugaston
11.56.2008 0e02964d4df506f9337c34f743e3d6c685633aa6
Replication Conflict Test Suite
1 files added
4 files modified
3438 ■■■■■ changed files
opends/tests/functional-tests/testcases/replication/conflict/conflict.xml 3026 ●●●●● patch | view | raw | blame | history
opends/tests/functional-tests/testcases/replication/replication.xml 2 ●●● patch | view | raw | blame | history
opends/tests/functional-tests/testcases/replication/replication_setup.xml 203 ●●●●● patch | view | raw | blame | history
opends/tests/shared/functions/dsconfig.xml 181 ●●●●● patch | view | raw | blame | history
opends/tests/shared/java/ldap/modifyAnAttribute.java 26 ●●●● patch | view | raw | blame | history
opends/tests/functional-tests/testcases/replication/conflict/conflict.xml
New file
@@ -0,0 +1,3026 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE stax SYSTEM "../../../../shared/stax.dtd">
<!--
 ! CDDL HEADER START
 !
 ! The contents of this file are subject to the terms of the
 ! Common Development and Distribution License, Version 1.0 only
 ! (the "License").  You may not use this file except in compliance
 ! with the License.
 !
 ! You can obtain a copy of the license at
 ! trunk/opends/resource/legal-notices/OpenDS.LICENSE
 ! or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 ! See the License for the specific language governing permissions
 ! and limitations under the License.
 !
 ! When distributing Covered Code, include this CDDL HEADER in each
 ! file and include the License file at
 ! trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 ! add the following below this CDDL HEADER, with the fields enclosed
 ! by brackets "[]" replaced with your own identifying information:
 !      Portions Copyright [yyyy] [name of copyright owner]
 !
 ! CDDL HEADER END
 !
 !      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 ! -->
<stax>
  <defaultcall function="replication_conflict"/>
  <function name="replication_conflict">
    <sequence>
      <block name="'conflict'">
        <sequence>
          <script>
            if not CurrentTestPath.has_key('group'):
              CurrentTestPath['group']='replication'
            CurrentTestPath['suite']=STAXCurrentBlock
          </script>
          <call function="'testSuite_Preamble'"/>
          <!--- Test Suite information
          #@TestSuiteName       Replication Conflict Tests
          #@TestSuitePurpose    Verify that replication handles the conflicts
                                all right
          #@TestSuiteID         Conflict Tests
          #@TestSuiteGroup      Conflict
          #@TestGroup           Replication
          #@TestScript          replication_failover.xml
          #@TestHTMLLink        http://opends.dev.java.net/
          -->
          <import machine="STAF_LOCAL_HOSTNAME"
            file="'%s/testcases/replication/replication_setup.xml'
                  % (TESTS_DIR)"/>
          <call function="'replication_setup'">
            { 'topologyFile'       : '%s/config/replication/basic_topology.txt'\
                                      % TESTS_DIR,
              'dataFile'           : 'Short_Example.ldif',
              'isolateLdapServers' : True,
              'enableDebugLogs'    : False
            }
          </call>
          <script>
            server1 = _topologyServerList[0]
            server2 = _topologyServerList[1]
            server1Host = server1.getHostname()
            server2Host = server2.getHostname()
            server1Path = '%s/%s' % (server1.getDir(), OPENDSNAME)
            server2Path = '%s/%s' % (server2.getDir(), OPENDSNAME)
            server2DataDir = '%s/%s' % (server2.getDir(),relativeDataDir)
            server1name = '%s:%s' % (server1Host, server1.getPort())
            server2name = '%s:%s' % (server2Host, server2.getPort())
            # Filter used for retrieving conflict counters from cn=monitor
            filter0 = '(base-dn=%s)' % synchroSuffix
            filter1 = '(cn=Replication Plugin*)'
            monitorFilter = '&amp;%s%s' % (filter0, filter1)
            monitorCounters = 'resolved-naming-conflicts \
                               unresolved-naming-conflicts \
                               resolved-modify-conflicts'
            addedEntries = STAXGlobal( [[], []] )
            class Entry:
              def __init__(self, rdn):
                self.userDn = '%s, ou=People, %s' \
                              % (rdn, synchroSuffix)
                self.listAttr = []
                self.listAttr.append('objectclass:top')
                self.listAttr.append('objectclass:organizationalperson')
                self.listAttr.append('objectclass:inetorgperson')
                self.listAttr.append('objectclass:person')
                self.listAttr.append('sn:User')
                self.listAttr.append('cn:Test User')
              def getDn(self):
                return self.userDn
              def getAttrList(self):
                return self.listAttr
              def addAttr(self, attrType, attrValue):
                self.listAttr.append('%s:%s' % (attrType, attrValue))
          </script>
          <!-- ============================================== -->
          <!-- ============================================== -->
          <!--- Test Case information
          #@TestMarker          Replication Conflict Tests
          #@TestName            Replication: Conflict: Basic check
          #@TestID              Basic check
          #@TestPurpose         Check replication assures synchronization after
                                a simultaneous conflictuous modify on 2
                                different servers (regardless of the prevailing
                                modify)
          #@TestPreamble
          #@TestSteps           Add entry to server1 with employeeNumber:0
          #@TestSteps           Parallel replace
                                  server1: employeeNumber -> 1
                                  server2: employeeNumber -> 2
          #@TestSteps           Check entry consistent on both servers
          #@TestPostamble
          #@TestResult          Success if trees are synchronised
          -->
          <testcase name="getTestCaseName
                          ('Basic check')">
            <sequence>
              <call function="'testCase_Preamble'"/>
              <message>
                'Replication: Conflict: Basic check 0. \
                Check replication assures synchronization after a simultaneous \
                conflictuous modify on 2 different servers (regardless of the \
                prevailing modify)'
              </message>
              <!-- Add entry to server1 -->
              <script>
                entry = Entry('uid=tuser-0')
                entry.addAttr('employeeNumber', '0')
              </script>
              <call function="'addAnEntry'">
                { 'location'       : server1Host,
                  'dsPath'         : server1Path,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'DNToAdd'        : entry.getDn(),
                  'listAttributes' : entry.getAttrList()
                }
              </call>
              <call function="'Sleep'">
                { 'sleepForMilliSeconds' : 2000 }
              </call>
              <paralleliterate var="server"
                               in="[server1, server2]"
                               indexvar="i">
                <!-- Modify entry on one of the servers -->
                <call function="'modifyAnAttribute'">
                  { 'location'          : server.getHostname(),
                    'dsPath'            : '%s/%s' \
                                          % (server.getDir(), OPENDSNAME),
                    'dsInstanceHost'    : server.getHostname(),
                    'dsInstancePort'    : server.getPort(),
                    'dsInstanceDn'      : server.getRootDn(),
                    'dsInstancePswd'    : server.getRootPwd(),
                    'DNToModify'        : entry.getDn(),
                    'attributeName'     : 'employeeNumber',
                    'newAttributeValue' : '%i' % (i + 1),
                    'changetype'        : 'replace'
                  }
                </call>
              </paralleliterate>
              <paralleliterate var="server" in="[server1, server2]">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : entry.getDn(),
                      'dsFilter'       : 'objectclass=*',
                      'dsAttributes'   : 'employeeNumber'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Verify the synchronization of the trees among the servers in
                the topology -->
              <call function="'verifyTrees'">
                [ clientHost, clientPath, server1, [server2], synchroSuffix ]
              </call>
              <!-- Delete added entry -->
              <call function="'ldapDeleteWithScript'">
                { 'location'       : clientHost,
                  'dsPath'         : clientPath,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'dsDn'           : [entry.getDn()]
                }
              </call>
              <call function="'testCase_Postamble'"/>
            </sequence>
          </testcase>
          <!--- Test Case information
          #@TestMarker          Replication Conflict Tests
          #@TestName            Replication: Conflict: double_replace_multi
          #@TestID              double_replace_multi
          #@TestPurpose         Double replace a multi-valued attribute
          #@TestPreamble
          #@TestSteps           Add entry to server1 with description:{1 2}
          #@TestSteps           Disconnect Replication Servers
          #@TestSteps           server1: replace description -> {3 4}
          #@TestSteps           server2: replace description -> {5 6}
          #@TestSteps           Re-connect Replication Servers
          #@TestSteps           Check description={5 6} on both servers
          #@TestPostamble
          #@TestResult          Success if trees are synchronised
          -->
          <testcase name="getTestCaseName
                          ('double_replace_multi')">
            <sequence>
              <call function="'testCase_Preamble'"/>
              <message>
                'Replication: Conflict: double_replace_multi. \
                Double replace a multi-valued attribute'
              </message>
              <!-- Add entry to server1 -->
              <script>
                entry = Entry('cn=A1')
                entry.addAttr('description', '1')
                entry.addAttr('description', '2')
                server1mods = ['description:3', 'description:4']
                server2mods = ['description:5', 'description:6']
                mods = [server1mods, server2mods]
              </script>
              <call function="'addAnEntry'">
                { 'location'       : server1Host,
                  'dsPath'         : server1Path,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'DNToAdd'        : entry.getDn(),
                  'listAttributes' : entry.getAttrList()
                }
              </call>
              <!-- Disconnect Replication Servers -->
              <call function="'disconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <iterate var="server"
                       in="[server1, server2]"
                       indexvar="i">
                <!-- Modify entry on one of the servers -->
                <call function="'modifyAnAttribute'">
                  { 'location'          : server.getHostname(),
                    'dsPath'            : '%s/%s' \
                                          % (server.getDir(), OPENDSNAME),
                    'dsInstanceHost'    : server.getHostname(),
                    'dsInstancePort'    : server.getPort(),
                    'dsInstanceDn'      : server.getRootDn(),
                    'dsInstancePswd'    : server.getRootPwd(),
                    'DNToModify'        : entry.getDn(),
                    'listAttributes'    : mods[i],
                    'changetype'        : 'replace'
                  }
                </call>
              </iterate>
              <!-- Check modifies have not been propagated -->
              <paralleliterate var="server" in="[server1, server2]">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : entry.getDn(),
                      'dsFilter'       : 'objectclass=*',
                      'dsAttributes'   : 'description'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Reconnect Replication Servers -->
              <call function="'reconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <!-- Check conflict is resolved -->
              <paralleliterate var="server" in="[server1, server2]">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : entry.getDn(),
                      'dsFilter'       : 'objectclass=*',
                      'dsAttributes'   : 'description'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Verify the synchronization of the trees among the servers in
                the topology -->
              <call function="'verifyTrees'">
                [ clientHost, clientPath, server1, [server2], synchroSuffix ]
              </call>
              <!-- Delete added entry -->
              <call function="'ldapDeleteWithScript'">
                { 'location'       : clientHost,
                  'dsPath'         : clientPath,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'dsDn'           : [entry.getDn()]
                }
              </call>
              <call function="'testCase_Postamble'"/>
            </sequence>
          </testcase>
          <!--- Test Case information
          #@TestMarker          Replication Conflict Tests
          #@TestName            Replication: Conflict: double_replace_single
          #@TestID              double_replace_single
          #@TestPurpose         Double replace a single-valued attribute
          #@TestPreamble
          #@TestSteps           Add entry to server1 with employeeNumber:0
          #@TestSteps           Disconnect Replication Servers
          #@TestSteps           server1: replace employeeNumber -> 1
          #@TestSteps           server2: replace employeeNumber -> 2
          #@TestSteps           Re-connect Replication Servers
          #@TestSteps           Check employeeNumber=2 on both servers
          #@TestPostamble
          #@TestResult          Success if trees are synchronised
          -->
          <testcase name="getTestCaseName
                          ('double_replace_single')">
            <sequence>
              <call function="'testCase_Preamble'"/>
              <message>
                'Replication: Conflict: double_replace_single. \
                Double replace a single-valued attribute'
              </message>
              <!-- Add entry to server1 -->
              <script>
                entry = Entry('cn=A4')
                entry.addAttr('employeeNumber', '0')
              </script>
              <call function="'addAnEntry'">
                { 'location'       : server1Host,
                  'dsPath'         : server1Path,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'DNToAdd'        : entry.getDn(),
                  'listAttributes' : entry.getAttrList()
                }
              </call>
              <!-- Disconnect Replication Servers -->
              <call function="'disconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <iterate var="server"
                       in="[server1, server2]"
                       indexvar="i">
                <!-- Modify entry on one of the servers -->
                <call function="'modifyAnAttribute'">
                  { 'location'          : server.getHostname(),
                    'dsPath'            : '%s/%s' \
                                          % (server.getDir(), OPENDSNAME),
                    'dsInstanceHost'    : server.getHostname(),
                    'dsInstancePort'    : server.getPort(),
                    'dsInstanceDn'      : server.getRootDn(),
                    'dsInstancePswd'    : server.getRootPwd(),
                    'DNToModify'        : entry.getDn(),
                    'attributeName'     : 'employeeNumber',
                    'newAttributeValue' : '%i' % (i + 1),
                    'changetype'        : 'replace'
                  }
                </call>
              </iterate>
              <!-- Check modifies have not been propagated -->
              <paralleliterate var="server" in="[server1, server2]">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : entry.getDn(),
                      'dsFilter'       : 'objectclass=*',
                      'dsAttributes'   : 'employeeNumber'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Reconnect Replication Servers -->
              <call function="'reconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <!-- Check conflict is resolved -->
              <paralleliterate var="server" in="[server1, server2]">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : entry.getDn(),
                      'dsFilter'       : 'objectclass=*',
                      'dsAttributes'   : 'employeeNumber'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Verify the synchronization of the trees among the servers in
                the topology -->
              <call function="'verifyTrees'">
                [ clientHost, clientPath, server1, [server2], synchroSuffix ]
              </call>
              <!-- Delete added entry -->
              <call function="'ldapDeleteWithScript'">
                { 'location'       : clientHost,
                  'dsPath'         : clientPath,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'dsDn'           : [entry.getDn()]
                }
              </call>
              <call function="'testCase_Postamble'"/>
            </sequence>
          </testcase>
          <!--- Test Case information
          #@TestMarker         Replication Conflict Tests
          #@TestName           Replication: Conflict: double_mod_del_add_multi_1
          #@TestID             double_mod_del_add_multi_1
          #@TestPurpose        Double replace (del+add) same value with any
                               value of a multi-valued attribute
          #@TestPreamble
          #@TestSteps          Add entry to server1 with
                               description:{1 2 3 4 5 6 7 8 9 10}
          #@TestSteps          Disconnect Replication Servers
          #@TestSteps          server1: del description=1 + add description=11
          #@TestSteps          server2: del description=1 + add description=12
          #@TestSteps          Re-connect Replication Servers
          #@TestSteps          Check description={2 3 4 5 6 7 8 9 10 11 12}
                               on both servers
          #@TestPostamble
          #@TestResult         Success if trees are synchronised
          -->
          <testcase name="getTestCaseName
                          ('double_mod_del_add_multi_1')">
            <sequence>
              <call function="'testCase_Preamble'"/>
              <message>
                'Replication: Conflict: double_mod_del_add_multi_1. \
                Double replace (del+add) same value with any value of a \
                multi-valued attribute'
              </message>
              <!-- Add entry to server1 -->
              <script>
                entry = Entry('cn=A2')
                for x in range(10):
                  entry.addAttr('description', '%i' % (x+1))
                server1del = ['description:1']
                server1add = ['description:11']
                server2del = ['description:1']
                server2add = ['description:12']
                server1mods = [server1del, server1add]
                server2mods = [server2del, server2add]
                mods = [server1mods, server2mods]
              </script>
              <call function="'addAnEntry'">
                { 'location'       : server1Host,
                  'dsPath'         : server1Path,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'DNToAdd'        : entry.getDn(),
                  'listAttributes' : entry.getAttrList()
                }
              </call>
              <!-- Disconnect Replication Servers -->
              <call function="'disconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <iterate var="server"
                       in="[server1, server2]"
                       indexvar="i">
                <sequence>
                  <!-- Modify entry on one of the servers -->
                  <call function="'modifyAnAttribute'">
                    { 'location'          : server.getHostname(),
                      'dsPath'            : '%s/%s' \
                                            % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost'    : server.getHostname(),
                      'dsInstancePort'    : server.getPort(),
                      'dsInstanceDn'      : server.getRootDn(),
                      'dsInstancePswd'    : server.getRootPwd(),
                      'DNToModify'        : entry.getDn(),
                      'listAttributes'    : mods[i][0],
                      'changetype'        : 'delete'
                    }
                  </call>
                  <call function="'modifyAnAttribute'">
                    { 'location'          : server.getHostname(),
                      'dsPath'            : '%s/%s' \
                                            % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost'    : server.getHostname(),
                      'dsInstancePort'    : server.getPort(),
                      'dsInstanceDn'      : server.getRootDn(),
                      'dsInstancePswd'    : server.getRootPwd(),
                      'DNToModify'        : entry.getDn(),
                      'listAttributes'    : mods[i][1],
                      'changetype'        : 'add'
                    }
                  </call>
                </sequence>
              </iterate>
              <!-- Check modifies have not been propagated -->
              <paralleliterate var="server" in="[server1, server2]">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : entry.getDn(),
                      'dsFilter'       : 'objectclass=*',
                      'dsAttributes'   : 'description'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Reconnect Replication Servers -->
              <call function="'reconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <!-- Check conflict is resolved -->
              <paralleliterate var="server" in="[server1, server2]">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : entry.getDn(),
                      'dsFilter'       : 'objectclass=*',
                      'dsAttributes'   : 'description'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Verify the synchronization of the trees among the servers in
                the topology -->
              <call function="'verifyTrees'">
                [ clientHost, clientPath, server1, [server2], synchroSuffix ]
              </call>
              <!-- Delete added entry -->
              <call function="'ldapDeleteWithScript'">
                { 'location'       : clientHost,
                  'dsPath'         : clientPath,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'dsDn'           : [entry.getDn()]
                }
              </call>
              <script>
                knownIssue(3392)
              </script>
              <call function="'testCase_Postamble'"/>
            </sequence>
          </testcase>
          <!--- Test Case information
          #@TestMarker         Replication Conflict Tests
          #@TestName           Replication: Conflict: double_mod_del_add_multi_2
          #@TestID             double_mod_del_add_multi_2
          #@TestPurpose        Double replace (del+add) any value with same
                               value of a multi-valued attribute
          #@TestPreamble
          #@TestSteps          Add entry to server1 with
                               description:{1 2 3 4 5 6 7 8 9 10}
          #@TestSteps          Disconnect Replication Servers
          #@TestSteps          server1: del description=1 + add description=11
          #@TestSteps          server2: del description=10 + add description=11
          #@TestSteps          Re-connect Replication Servers
          #@TestSteps          Check description={2 3 4 5 6 7 8 9 11}
                               on both servers
          #@TestPostamble
          #@TestResult         Success if trees are synchronised
          -->
          <testcase name="getTestCaseName
                          ('double_mod_del_add_multi_2')">
            <sequence>
              <call function="'testCase_Preamble'"/>
              <message>
                'Replication: Conflict: double_mod_del_add_multi_2. \
                Double replace (del+add) any value with same value of a \
                multi-valued attribute'
              </message>
              <!-- Add entry to server1 -->
              <script>
                entry = Entry('cn=A3')
                for x in range(10):
                  entry.addAttr('description', '%i' % (x+1))
                server1del = ['description:1']
                server1add = ['description:11']
                server2del = ['description:10']
                server2add = ['description:11']
                server1mods = [server1del, server1add]
                server2mods = [server2del, server2add]
                mods = [server1mods, server2mods]
              </script>
              <call function="'addAnEntry'">
                { 'location'       : server1Host,
                  'dsPath'         : server1Path,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'DNToAdd'        : entry.getDn(),
                  'listAttributes' : entry.getAttrList()
                }
              </call>
              <!-- Disconnect Replication Servers -->
              <call function="'disconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <iterate var="server"
                       in="[server1, server2]"
                       indexvar="i">
                <sequence>
                  <!-- Modify entry on one of the servers -->
                  <call function="'modifyAnAttribute'">
                    { 'location'          : server.getHostname(),
                      'dsPath'            : '%s/%s' \
                                            % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost'    : server.getHostname(),
                      'dsInstancePort'    : server.getPort(),
                      'dsInstanceDn'      : server.getRootDn(),
                      'dsInstancePswd'    : server.getRootPwd(),
                      'DNToModify'        : entry.getDn(),
                      'listAttributes'    : mods[i][0],
                      'changetype'        : 'delete'
                    }
                  </call>
                  <call function="'modifyAnAttribute'">
                    { 'location'          : server.getHostname(),
                      'dsPath'            : '%s/%s' \
                                            % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost'    : server.getHostname(),
                      'dsInstancePort'    : server.getPort(),
                      'dsInstanceDn'      : server.getRootDn(),
                      'dsInstancePswd'    : server.getRootPwd(),
                      'DNToModify'        : entry.getDn(),
                      'listAttributes'    : mods[i][1],
                      'changetype'        : 'add'
                    }
                  </call>
                </sequence>
              </iterate>
              <!-- Check modifies have not been propagated -->
              <paralleliterate var="server" in="[server1, server2]">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : entry.getDn(),
                      'dsFilter'       : 'objectclass=*',
                      'dsAttributes'   : 'description'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Reconnect Replication Servers -->
              <call function="'reconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <!-- Check conflict is resolved -->
              <paralleliterate var="server" in="[server1, server2]">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : entry.getDn(),
                      'dsFilter'       : 'objectclass=*',
                      'dsAttributes'   : 'description'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Verify the synchronization of the trees among the servers in
                the topology -->
              <call function="'verifyTrees'">
                [ clientHost, clientPath, server1, [server2], synchroSuffix ]
              </call>
              <!-- Delete added entry -->
              <call function="'ldapDeleteWithScript'">
                { 'location'       : clientHost,
                  'dsPath'         : clientPath,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'dsDn'           : [entry.getDn()]
                }
              </call>
              <call function="'testCase_Postamble'"/>
            </sequence>
          </testcase>
          <!--- Test Case information
          #@TestMarker         Replication Conflict Tests
          #@TestName           Replication: Conflict: double_mod_add_multi
          #@TestID             double_mod_add_multi
          #@TestPurpose        Double mod_add a multi-valued attribute
          #@TestPreamble
          #@TestSteps          Add entry to server1
          #@TestSteps          Disconnect Replication Servers
          #@TestSteps          server1: add description=1
          #@TestSteps          server2: add description={1 2}
          #@TestSteps          Re-connect Replication Servers
          #@TestSteps          Check description={1 2} on both servers
          #@TestPostamble
          #@TestResult         Success if trees are synchronised
          -->
          <testcase name="getTestCaseName
                          ('double_mod_add_multi')">
            <sequence>
              <call function="'testCase_Preamble'"/>
              <message>
                'Replication: Conflict: double_mod_add_multi. \
                Double mod_add a multi-valued attribute'
              </message>
              <!-- Add entry to server1 -->
              <script>
                entry = Entry('cn=B1')
                server1add = ['description:1']
                server2add = ['description:1', 'description:2']
                server1mods = [server1add]
                server2mods = [server2add]
                mods = [server1mods, server2mods]
              </script>
              <call function="'addAnEntry'">
                { 'location'       : server1Host,
                  'dsPath'         : server1Path,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'DNToAdd'        : entry.getDn(),
                  'listAttributes' : entry.getAttrList()
                }
              </call>
              <!-- Disconnect Replication Servers -->
              <call function="'disconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <iterate var="server"
                       in="[server1, server2]"
                       indexvar="i">
                <sequence>
                  <!-- Modify entry on one of the servers -->
                  <call function="'modifyAnAttribute'">
                    { 'location'          : server.getHostname(),
                      'dsPath'            : '%s/%s' \
                                            % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost'    : server.getHostname(),
                      'dsInstancePort'    : server.getPort(),
                      'dsInstanceDn'      : server.getRootDn(),
                      'dsInstancePswd'    : server.getRootPwd(),
                      'DNToModify'        : entry.getDn(),
                      'listAttributes'    : mods[i][0],
                      'changetype'        : 'add'
                    }
                  </call>
                </sequence>
              </iterate>
              <!-- Check modifies have not been propagated -->
              <paralleliterate var="server" in="[server1, server2]">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : entry.getDn(),
                      'dsFilter'       : 'objectclass=*',
                      'dsAttributes'   : 'description'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Reconnect Replication Servers -->
              <call function="'reconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <!-- Check conflict is resolved -->
              <paralleliterate var="server" in="[server1, server2]">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : entry.getDn(),
                      'dsFilter'       : 'objectclass=*',
                      'dsAttributes'   : 'description'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Verify the synchronization of the trees among the servers in
                the topology -->
              <call function="'verifyTrees'">
                [ clientHost, clientPath, server1, [server2], synchroSuffix ]
              </call>
              <!-- Delete added entry -->
              <call function="'ldapDeleteWithScript'">
                { 'location'       : clientHost,
                  'dsPath'         : clientPath,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'dsDn'           : [entry.getDn()]
                }
              </call>
              <script>
                knownIssue(3394)
              </script>
              <call function="'testCase_Postamble'"/>
            </sequence>
          </testcase>
          <!--- Test Case information
          #@TestMarker         Replication Conflict Tests
          #@TestName           Replication: Conflict: double_mod_add_single
          #@TestID             double_mod_add_single
          #@TestPurpose        Double mod_add a single-valued attribute
          #@TestPreamble
          #@TestSteps          Add entry to server1
          #@TestSteps          Disconnect Replication Servers
          #@TestSteps          server1: add employeeNumber=1
          #@TestSteps          server2: add employeeNumber=2
          #@TestSteps          Re-connect Replication Servers
          #@TestSteps          Check employeeNumber=1 on both servers
          #@TestPostamble
          #@TestResult         Success if trees are synchronised
          -->
          <testcase name="getTestCaseName
                          ('double_mod_add_single')">
            <sequence>
              <call function="'testCase_Preamble'"/>
              <message>
                'Replication: Conflict: double_mod_add_single. \
                Double mod_add a single-valued attribute'
              </message>
              <!-- Add entry to server1 -->
              <script>
                entry = Entry('cn=B2')
                server1add = ['employeeNumber:1']
                server2add = ['employeeNumber:2']
                server1mods = [server1add]
                server2mods = [server2add]
                mods = [server1mods, server2mods]
              </script>
              <call function="'addAnEntry'">
                { 'location'       : server1Host,
                  'dsPath'         : server1Path,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'DNToAdd'        : entry.getDn(),
                  'listAttributes' : entry.getAttrList()
                }
              </call>
              <!-- Disconnect Replication Servers -->
              <call function="'disconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <iterate var="server"
                       in="[server1, server2]"
                       indexvar="i">
                <sequence>
                  <!-- Modify entry on one of the servers -->
                  <call function="'modifyAnAttribute'">
                    { 'location'          : server.getHostname(),
                      'dsPath'            : '%s/%s' \
                                            % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost'    : server.getHostname(),
                      'dsInstancePort'    : server.getPort(),
                      'dsInstanceDn'      : server.getRootDn(),
                      'dsInstancePswd'    : server.getRootPwd(),
                      'DNToModify'        : entry.getDn(),
                      'listAttributes'    : mods[i][0],
                      'changetype'        : 'add'
                    }
                  </call>
                </sequence>
              </iterate>
              <!-- Check modifies have not been propagated -->
              <paralleliterate var="server" in="[server1, server2]">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : entry.getDn(),
                      'dsFilter'       : 'objectclass=*',
                      'dsAttributes'   : 'employeeNumber'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Reconnect Replication Servers -->
              <call function="'reconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <!-- Check conflict is resolved -->
              <paralleliterate var="server" in="[server1, server2]">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : entry.getDn(),
                      'dsFilter'       : 'objectclass=*',
                      'dsAttributes'   : 'employeeNumber'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Verify the synchronization of the trees among the servers in
                the topology -->
              <call function="'verifyTrees'">
                [ clientHost, clientPath, server1, [server2], synchroSuffix ]
              </call>
              <!-- Delete added entry -->
              <call function="'ldapDeleteWithScript'">
                { 'location'       : clientHost,
                  'dsPath'         : clientPath,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'dsDn'           : [entry.getDn()]
                }
              </call>
              <call function="'testCase_Postamble'"/>
            </sequence>
          </testcase>
          <!--- Test Case information
          #@TestMarker         Replication Conflict Tests
          #@TestName           Replication: Conflict: double_mod_del_multi
          #@TestID             double_mod_del_multi
          #@TestPurpose        Double mod_delete a multi-valued attribute
          #@TestPreamble
          #@TestSteps          Add entry to server1 with
                               description:{1 2 3 4 5 6 7 8 9 10}
          #@TestSteps          Disconnect Replication Servers
          #@TestSteps          server1: delete description={1 2 3 4 5}
          #@TestSteps          server2: delete description={4 5 6 7 8}
          #@TestSteps          Re-connect Replication Servers
          #@TestSteps          Check description={9 10} on both servers
          #@TestPostamble
          #@TestResult         Success if trees are synchronised
          -->
          <testcase name="getTestCaseName
                          ('double_mod_del_multi')">
            <sequence>
              <call function="'testCase_Preamble'"/>
              <message>
                'Replication: Conflict: double_mod_del_multi. \
                Double mod_delete a multi-valued attribute'
              </message>
              <!-- Add entry to server1 -->
              <script>
                entry = Entry('cn=C1')
                for x in range(10):
                  entry.addAttr('description', '%i' % (x+1))
                server1del = []
                for y in range(1,6):
                  server1del.append('description:%i' % y)
                server2del = []
                for z in range(4,9):
                  server2del.append('description:%i' % z)
                server1mods = [server1del]
                server2mods = [server2del]
                mods = [server1mods, server2mods]
              </script>
              <call function="'addAnEntry'">
                { 'location'       : server1Host,
                  'dsPath'         : server1Path,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'DNToAdd'        : entry.getDn(),
                  'listAttributes' : entry.getAttrList()
                }
              </call>
              <!-- Disconnect Replication Servers -->
              <call function="'disconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <iterate var="server"
                       in="[server1, server2]"
                       indexvar="i">
                <sequence>
                  <!-- Modify entry on one of the servers -->
                  <call function="'modifyAnAttribute'">
                    { 'location'          : server.getHostname(),
                      'dsPath'            : '%s/%s' \
                                            % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost'    : server.getHostname(),
                      'dsInstancePort'    : server.getPort(),
                      'dsInstanceDn'      : server.getRootDn(),
                      'dsInstancePswd'    : server.getRootPwd(),
                      'DNToModify'        : entry.getDn(),
                      'listAttributes'    : mods[i][0],
                      'changetype'        : 'delete'
                    }
                  </call>
                </sequence>
              </iterate>
              <!-- Check modifies have not been propagated -->
              <paralleliterate var="server" in="[server1, server2]">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : entry.getDn(),
                      'dsFilter'       : 'objectclass=*',
                      'dsAttributes'   : 'description'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Reconnect Replication Servers -->
              <call function="'reconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <!-- Check conflict is resolved -->
              <paralleliterate var="server" in="[server1, server2]">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : entry.getDn(),
                      'dsFilter'       : 'objectclass=*',
                      'dsAttributes'   : 'description'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Verify the synchronization of the trees among the servers in
                the topology -->
              <call function="'verifyTrees'">
                [ clientHost, clientPath, server1, [server2], synchroSuffix ]
              </call>
              <!-- Delete added entry -->
              <call function="'ldapDeleteWithScript'">
                { 'location'       : clientHost,
                  'dsPath'         : clientPath,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'dsDn'           : [entry.getDn()]
                }
              </call>
              <script>
                knownIssue(3397)
              </script>
              <call function="'testCase_Postamble'"/>
            </sequence>
          </testcase>
          <!--- Test Case information
          #@TestMarker         Replication Conflict Tests
          #@TestName           Replication: Conflict: double_mod_del_single
          #@TestID             double_mod_del_single
          #@TestPurpose        Double mod_delete a single-valued attribute
          #@TestPreamble
          #@TestSteps          Add entry to server1 with employeeNumber=1
          #@TestSteps          Disconnect Replication Servers
          #@TestSteps          server1: delete employeeNumber
          #@TestSteps          server2: delete employeeNumber=1
          #@TestSteps          Re-connect Replication Servers
          #@TestSteps          Check employeeNumber no longer exists on either
                               server
          #@TestPostamble
          #@TestResult         Success if trees are synchronised
          -->
          <testcase name="getTestCaseName
                          ('double_mod_del_single')">
            <sequence>
              <call function="'testCase_Preamble'"/>
              <message>
                'Replication: Conflict: double_mod_del_single. \
                Double mod_delete a single-valued attribute'
              </message>
              <!-- Add entry to server1 -->
              <script>
                entry = Entry('cn=C2')
                entry.addAttr('employeeNumber', '1')
                server1del = ['employeeNumber:']
                server2del = ['employeeNumber:1']
                server1mods = [server1del]
                server2mods = [server2del]
                mods = [server1mods, server2mods]
              </script>
              <call function="'addAnEntry'">
                { 'location'       : server1Host,
                  'dsPath'         : server1Path,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'DNToAdd'        : entry.getDn(),
                  'listAttributes' : entry.getAttrList()
                }
              </call>
              <!-- Disconnect Replication Servers -->
              <call function="'disconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <iterate var="server"
                       in="[server1, server2]"
                       indexvar="i">
                <sequence>
                  <!-- Modify entry on one of the servers -->
                  <call function="'modifyAnAttribute'">
                    { 'location'          : server.getHostname(),
                      'dsPath'            : '%s/%s' \
                                            % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost'    : server.getHostname(),
                      'dsInstancePort'    : server.getPort(),
                      'dsInstanceDn'      : server.getRootDn(),
                      'dsInstancePswd'    : server.getRootPwd(),
                      'DNToModify'        : entry.getDn(),
                      'listAttributes'    : mods[i][0],
                      'changetype'        : 'delete'
                    }
                  </call>
                </sequence>
              </iterate>
              <!-- Check modifies have not been propagated -->
              <paralleliterate var="server" in="[server1, server2]">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : entry.getDn(),
                      'dsFilter'       : 'objectclass=*',
                      'dsAttributes'   : 'employeeNumber'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Reconnect Replication Servers -->
              <call function="'reconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <!-- Check conflict is resolved -->
              <paralleliterate var="server" in="[server1, server2]">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : entry.getDn(),
                      'dsFilter'       : 'objectclass=*',
                      'dsAttributes'   : 'employeeNumber'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Verify the synchronization of the trees among the servers in
                the topology -->
              <call function="'verifyTrees'">
                [ clientHost, clientPath, server1, [server2], synchroSuffix ]
              </call>
              <!-- Delete added entry -->
              <call function="'ldapDeleteWithScript'">
                { 'location'       : clientHost,
                  'dsPath'         : clientPath,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'dsDn'           : [entry.getDn()]
                }
              </call>
              <!-- Issue visible in the error log, so not detectable so far.
              <script>
                knownIssue(3399)
              </script>
              -->
              <call function="'testCase_Postamble'"/>
            </sequence>
          </testcase>
          <!--- Test Case information
          #@TestMarker         Replication Conflict Tests
          #@TestName           Replication: Conflict:
                               mod_del_add_vs_mod_add_del_multi
          #@TestID             mod_del_add_vs_mod_add_del_multi
          #@TestPurpose        Modify: Delete+Add then Add+Delete on 2
                               multi-valued attributes
          #@TestPreamble
          #@TestSteps          Add entry to server1 with
                               description=1 , telephoneNumber=1
          #@TestSteps          Disconnect Replication Servers
          #@TestSteps          server1: add description=2 ,
                               delete telephoneNumber
          #@TestSteps          server2: delete description ,
                               add telephoneNumber=2
          #@TestSteps          Re-connect Replication Servers
          #@TestSteps          Check description no longer exists and
                               telephoneNumber=2 on both servers
          #@TestPostamble
          #@TestResult         Success if trees are synchronised
          -->
          <testcase name="getTestCaseName
                          ('mod_del_add_vs_mod_add_del_multi')">
            <sequence>
              <call function="'testCase_Preamble'"/>
              <message>
                'Replication: Conflict: mod_del_add_vs_mod_add_del_multi. \
                Modify: Delete+Add then Add+Delete on 2 multi-valued attributes'
              </message>
              <!-- Add entry to server1 -->
              <script>
                entry = Entry('cn=D1')
                entry.addAttr('description', '1')
                entry.addAttr('telephoneNumber', '1')
                server1add = ['description:2']
                server1del = ['telephoneNumber:']
                server2del = ['description:']
                server2add = ['telephoneNumber:2']
                server1mods = [server1add, server1del]
                server2mods = [server2del, server2add]
                mods = [server1mods, server2mods]
                server1changetypes = ['add', 'delete']
                server2changetypes = ['delete', 'add']
                changetypes = [server1changetypes, server2changetypes]
              </script>
              <call function="'addAnEntry'">
                { 'location'       : server1Host,
                  'dsPath'         : server1Path,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'DNToAdd'        : entry.getDn(),
                  'listAttributes' : entry.getAttrList()
                }
              </call>
              <!-- Disconnect Replication Servers -->
              <call function="'disconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <iterate var="server"
                       in="[server1, server2]"
                       indexvar="i">
                <sequence>
                  <!-- Modify entry on one of the servers -->
                  <call function="'modifyAnAttribute'">
                    { 'location'          : server.getHostname(),
                      'dsPath'            : '%s/%s' \
                                            % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost'    : server.getHostname(),
                      'dsInstancePort'    : server.getPort(),
                      'dsInstanceDn'      : server.getRootDn(),
                      'dsInstancePswd'    : server.getRootPwd(),
                      'DNToModify'        : entry.getDn(),
                      'listAttributes'    : mods[i][0],
                      'changetype'        : changetypes[i][0]
                    }
                  </call>
                  <call function="'modifyAnAttribute'">
                    { 'location'          : server.getHostname(),
                      'dsPath'            : '%s/%s' \
                                            % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost'    : server.getHostname(),
                      'dsInstancePort'    : server.getPort(),
                      'dsInstanceDn'      : server.getRootDn(),
                      'dsInstancePswd'    : server.getRootPwd(),
                      'DNToModify'        : entry.getDn(),
                      'listAttributes'    : mods[i][1],
                      'changetype'        : changetypes[i][1]
                    }
                  </call>
                </sequence>
              </iterate>
              <!-- Check modifies have not been propagated -->
              <paralleliterate var="server" in="[server1, server2]">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : entry.getDn(),
                      'dsFilter'       : 'objectclass=*',
                      'dsAttributes'   : 'description telephoneNumber'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Reconnect Replication Servers -->
              <call function="'reconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <!-- Check conflict is resolved -->
              <paralleliterate var="server" in="[server1, server2]">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : entry.getDn(),
                      'dsFilter'       : 'objectclass=*',
                      'dsAttributes'   : 'description telephoneNumber'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Verify the synchronization of the trees among the servers in
                the topology -->
              <call function="'verifyTrees'">
                [ clientHost, clientPath, server1, [server2], synchroSuffix ]
              </call>
              <!-- Delete added entry -->
              <call function="'ldapDeleteWithScript'">
                { 'location'       : clientHost,
                  'dsPath'         : clientPath,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'dsDn'           : [entry.getDn()]
                }
              </call>
              <call function="'testCase_Postamble'"/>
            </sequence>
          </testcase>
          <!--- Test Case information
          #@TestMarker         Replication Conflict Tests
          #@TestName           Replication: Conflict:
                               mod_add_vs_mod_replace_multi
          #@TestID             mod_add_vs_mod_replace_multi
          #@TestPurpose        mod_add vs mod_replace on a multi-valued
                               attribute
          #@TestPreamble
          #@TestSteps          Add entry to server1 with description=1
          #@TestSteps          Disconnect Replication Servers
          #@TestSteps          server1: add description={2 3}
          #@TestSteps          server2: replace description -> {4 5}
          #@TestSteps          Re-connect Replication Servers
          #@TestSteps          Check description={4 5} on both servers
          #@TestPostamble
          #@TestResult         Success if trees are synchronised
          -->
          <testcase name="getTestCaseName
                          ('mod_add_vs_mod_replace_multi')">
            <sequence>
              <call function="'testCase_Preamble'"/>
              <message>
                'Replication: Conflict: mod_add_vs_mod_replace_multi. \
                mod_add vs mod_replace on a multi-valued attribute'
              </message>
              <!-- Add entry to server1 -->
              <script>
                entry = Entry('cn=E1')
                entry.addAttr('description', '1')
                server1add = ['description:2', 'description:3']
                server2replace = ['description:4', 'description:5']
                server1mods = [server1add]
                server2mods = [server2replace]
                mods = [server1mods, server2mods]
                server1changetypes = ['add']
                server2changetypes = ['replace']
                changetypes = [server1changetypes, server2changetypes]
              </script>
              <call function="'addAnEntry'">
                { 'location'       : server1Host,
                  'dsPath'         : server1Path,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'DNToAdd'        : entry.getDn(),
                  'listAttributes' : entry.getAttrList()
                }
              </call>
              <!-- Disconnect Replication Servers -->
              <call function="'disconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <iterate var="server"
                       in="[server1, server2]"
                       indexvar="i">
                <sequence>
                  <!-- Modify entry on one of the servers -->
                  <call function="'modifyAnAttribute'">
                    { 'location'          : server.getHostname(),
                      'dsPath'            : '%s/%s' \
                                            % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost'    : server.getHostname(),
                      'dsInstancePort'    : server.getPort(),
                      'dsInstanceDn'      : server.getRootDn(),
                      'dsInstancePswd'    : server.getRootPwd(),
                      'DNToModify'        : entry.getDn(),
                      'listAttributes'    : mods[i][0],
                      'changetype'        : changetypes[i][0]
                    }
                  </call>
                </sequence>
              </iterate>
              <!-- Check modifies have not been propagated -->
              <paralleliterate var="server" in="[server1, server2]">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : entry.getDn(),
                      'dsFilter'       : 'objectclass=*',
                      'dsAttributes'   : 'description'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Reconnect Replication Servers -->
              <call function="'reconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <!-- Check conflict is resolved -->
              <paralleliterate var="server" in="[server1, server2]">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : entry.getDn(),
                      'dsFilter'       : 'objectclass=*',
                      'dsAttributes'   : 'description'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Verify the synchronization of the trees among the servers in
                the topology -->
              <call function="'verifyTrees'">
                [ clientHost, clientPath, server1, [server2], synchroSuffix ]
              </call>
              <!-- Delete added entry -->
              <call function="'ldapDeleteWithScript'">
                { 'location'       : clientHost,
                  'dsPath'         : clientPath,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'dsDn'           : [entry.getDn()]
                }
              </call>
              <call function="'testCase_Postamble'"/>
            </sequence>
          </testcase>
          <!--- Test Case information
          #@TestMarker         Replication Conflict Tests
          #@TestName           Replication: Conflict:
                               mod_replace_vs_mod_add_multi
          #@TestID             mod_replace_vs_mod_add_multi
          #@TestPurpose        mod_replace vs mod_add on a multi-valued
                               attribute
          #@TestPreamble
          #@TestSteps          Add entry to server1 with description=1
          #@TestSteps          Disconnect Replication Servers
          #@TestSteps          server1: replace description -> {2 3}
          #@TestSteps          server2: add description={4 5}
          #@TestSteps          Re-connect Replication Servers
          #@TestSteps          Check description={2 3 4 5} on both servers
          #@TestPostamble
          #@TestResult         Success if trees are synchronised
          -->
          <testcase name="getTestCaseName
                          ('mod_replace_vs_mod_add_multi')">
            <sequence>
              <call function="'testCase_Preamble'"/>
              <message>
                'Replication: Conflict: mod_replace_vs_mod_add_multi. \
                mod_replace vs mod_add on a multi-valued attribute'
              </message>
              <!-- Add entry to server1 -->
              <script>
                entry = Entry('cn=E2')
                entry.addAttr('description', '1')
                server1replace = ['description:2', 'description:3']
                server2add = ['description:4', 'description:5']
                server1mods = [server1replace]
                server2mods = [server2add]
                mods = [server1mods, server2mods]
                server1changetypes = ['replace']
                server2changetypes = ['add']
                changetypes = [server1changetypes, server2changetypes]
              </script>
              <call function="'addAnEntry'">
                { 'location'       : server1Host,
                  'dsPath'         : server1Path,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'DNToAdd'        : entry.getDn(),
                  'listAttributes' : entry.getAttrList()
                }
              </call>
              <!-- Disconnect Replication Servers -->
              <call function="'disconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <iterate var="server"
                       in="[server1, server2]"
                       indexvar="i">
                <sequence>
                  <!-- Modify entry on one of the servers -->
                  <call function="'modifyAnAttribute'">
                    { 'location'          : server.getHostname(),
                      'dsPath'            : '%s/%s' \
                                            % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost'    : server.getHostname(),
                      'dsInstancePort'    : server.getPort(),
                      'dsInstanceDn'      : server.getRootDn(),
                      'dsInstancePswd'    : server.getRootPwd(),
                      'DNToModify'        : entry.getDn(),
                      'listAttributes'    : mods[i][0],
                      'changetype'        : changetypes[i][0]
                    }
                  </call>
                </sequence>
              </iterate>
              <!-- Check modifies have not been propagated -->
              <paralleliterate var="server" in="[server1, server2]">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : entry.getDn(),
                      'dsFilter'       : 'objectclass=*',
                      'dsAttributes'   : 'description'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Reconnect Replication Servers -->
              <call function="'reconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <!-- Check conflict is resolved -->
              <paralleliterate var="server" in="[server1, server2]">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : entry.getDn(),
                      'dsFilter'       : 'objectclass=*',
                      'dsAttributes'   : 'description'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Verify the synchronization of the trees among the servers in
                the topology -->
              <call function="'verifyTrees'">
                [ clientHost, clientPath, server1, [server2], synchroSuffix ]
              </call>
              <!-- Delete added entry -->
              <call function="'ldapDeleteWithScript'">
                { 'location'       : clientHost,
                  'dsPath'         : clientPath,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'dsDn'           : [entry.getDn()]
                }
              </call>
              <call function="'testCase_Postamble'"/>
            </sequence>
          </testcase>
          <!--- Test Case information
          #@TestMarker         Replication Conflict Tests
          #@TestName           Replication: Conflict:
                               mod_del_vs_mod_replace_multi
          #@TestID             mod_del_vs_mod_replace_multi
          #@TestPurpose        mod_del vs mod_replace on a multi-valued
                               attribute
          #@TestPreamble
          #@TestSteps          Add entry to server1 with
                               description={1 2 3 4}
          #@TestSteps          Disconnect Replication Servers
          #@TestSteps          server1: delete description={2 3}
          #@TestSteps          server2: replace description -> {6 7 8 9 10}
          #@TestSteps          Re-connect Replication Servers
          #@TestSteps          Check description={6 7 8 9 10} on both servers
          #@TestPostamble
          #@TestResult         Success if trees are synchronised
          -->
          <testcase name="getTestCaseName
                          ('mod_del_vs_mod_replace_multi')">
            <sequence>
              <call function="'testCase_Preamble'"/>
              <message>
                'Replication: Conflict: mod_del_vs_mod_replace_multi. \
                mod_del vs mod_replace on a multi-valued attribute'
              </message>
              <!-- Add entry to server1 -->
              <script>
                entry = Entry('cn=F1')
                for x in range(4):
                  entry.addAttr('description', '%i' % (x+1))
                server1del = ['description:2', 'description:3']
                server2replace = []
                for y in range(6,11):
                  server2replace.append('description:%i' % y)
                server1mods = [server1del]
                server2mods = [server2replace]
                mods = [server1mods, server2mods]
                server1changetypes = ['delete']
                server2changetypes = ['replace']
                changetypes = [server1changetypes, server2changetypes]
              </script>
              <call function="'addAnEntry'">
                { 'location'       : server1Host,
                  'dsPath'         : server1Path,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'DNToAdd'        : entry.getDn(),
                  'listAttributes' : entry.getAttrList()
                }
              </call>
              <!-- Disconnect Replication Servers -->
              <call function="'disconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <iterate var="server"
                       in="[server1, server2]"
                       indexvar="i">
                <sequence>
                  <!-- Modify entry on one of the servers -->
                  <call function="'modifyAnAttribute'">
                    { 'location'          : server.getHostname(),
                      'dsPath'            : '%s/%s' \
                                            % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost'    : server.getHostname(),
                      'dsInstancePort'    : server.getPort(),
                      'dsInstanceDn'      : server.getRootDn(),
                      'dsInstancePswd'    : server.getRootPwd(),
                      'DNToModify'        : entry.getDn(),
                      'listAttributes'    : mods[i][0],
                      'changetype'        : changetypes[i][0]
                    }
                  </call>
                </sequence>
              </iterate>
              <!-- Check modifies have not been propagated -->
              <paralleliterate var="server" in="[server1, server2]">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : entry.getDn(),
                      'dsFilter'       : 'objectclass=*',
                      'dsAttributes'   : 'description'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Reconnect Replication Servers -->
              <call function="'reconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <!-- Check conflict is resolved -->
              <paralleliterate var="server" in="[server1, server2]">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : entry.getDn(),
                      'dsFilter'       : 'objectclass=*',
                      'dsAttributes'   : 'description'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Verify the synchronization of the trees among the servers in
                the topology -->
              <call function="'verifyTrees'">
                [ clientHost, clientPath, server1, [server2], synchroSuffix ]
              </call>
              <!-- Delete added entry -->
              <call function="'ldapDeleteWithScript'">
                { 'location'       : clientHost,
                  'dsPath'         : clientPath,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'dsDn'           : [entry.getDn()]
                }
              </call>
              <call function="'testCase_Postamble'"/>
            </sequence>
          </testcase>
          <!--- Test Case information
          #@TestMarker         Replication Conflict Tests
          #@TestName           Replication: Conflict:
                               mod_replace_vs_mod_del_multi
          #@TestID             mod_replace_vs_mod_del_multi
          #@TestPurpose        mod_replace vs mod_del on a multi-valued
                               attribute
          #@TestPreamble
          #@TestSteps          Add entry to server1 with
                               description={1 2 3 4}
          #@TestSteps          Disconnect Replication Servers
          #@TestSteps          server1: replace description -> {1 2 3}
          #@TestSteps          server2: delete description={3 4}
          #@TestSteps          Re-connect Replication Servers
          #@TestSteps          Check description={1 2} on both servers
          #@TestPostamble
          #@TestResult         Success if trees are synchronised
          -->
          <testcase name="getTestCaseName
                          ('mod_replace_vs_mod_del_multi')">
            <sequence>
              <call function="'testCase_Preamble'"/>
              <message>
                'Replication: Conflict: mod_replace_vs_mod_del_multi. \
                mod_replace vs mod_del on a multi-valued attribute'
              </message>
              <!-- Add entry to server1 -->
              <script>
                entry = Entry('cn=F2')
                for x in range(4):
                  entry.addAttr('description', '%i' % (x+1))
                server1replace = ['description:1', 'description:2',
                                  'description:3']
                server2del = ['description:3', 'description:4']
                server1mods = [server1replace]
                server2mods = [server2del]
                mods = [server1mods, server2mods]
                server1changetypes = ['replace']
                server2changetypes = ['delete']
                changetypes = [server1changetypes, server2changetypes]
              </script>
              <call function="'addAnEntry'">
                { 'location'       : server1Host,
                  'dsPath'         : server1Path,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'DNToAdd'        : entry.getDn(),
                  'listAttributes' : entry.getAttrList()
                }
              </call>
              <!-- Disconnect Replication Servers -->
              <call function="'disconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <iterate var="server"
                       in="[server1, server2]"
                       indexvar="i">
                <sequence>
                  <!-- Modify entry on one of the servers -->
                  <call function="'modifyAnAttribute'">
                    { 'location'          : server.getHostname(),
                      'dsPath'            : '%s/%s' \
                                            % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost'    : server.getHostname(),
                      'dsInstancePort'    : server.getPort(),
                      'dsInstanceDn'      : server.getRootDn(),
                      'dsInstancePswd'    : server.getRootPwd(),
                      'DNToModify'        : entry.getDn(),
                      'listAttributes'    : mods[i][0],
                      'changetype'        : changetypes[i][0]
                    }
                  </call>
                </sequence>
              </iterate>
              <!-- Check modifies have not been propagated -->
              <paralleliterate var="server" in="[server1, server2]">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : entry.getDn(),
                      'dsFilter'       : 'objectclass=*',
                      'dsAttributes'   : 'description'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Reconnect Replication Servers -->
              <call function="'reconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <!-- Check conflict is resolved -->
              <paralleliterate var="server" in="[server1, server2]">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : entry.getDn(),
                      'dsFilter'       : 'objectclass=*',
                      'dsAttributes'   : 'description'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Verify the synchronization of the trees among the servers in
                the topology -->
              <call function="'verifyTrees'">
                [ clientHost, clientPath, server1, [server2], synchroSuffix ]
              </call>
              <!-- Delete added entry -->
              <call function="'ldapDeleteWithScript'">
                { 'location'       : clientHost,
                  'dsPath'         : clientPath,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'dsDn'           : [entry.getDn()]
                }
              </call>
              <script>
                knownIssue(3397)
              </script>
              <call function="'testCase_Postamble'"/>
            </sequence>
          </testcase>
          <!--- Test Case information
          #@TestMarker         Replication Conflict Tests
          #@TestName           Replication: Conflict: add_child_del_parent
          #@TestID             add_child_del_parent
          #@TestPurpose        Add a child vs delete his parent
          #@TestPreamble
          #@TestSteps          Add entry cn=P1 to server1
          #@TestSteps          Disconnect Replication Servers
          #@TestSteps          server2: add child cn=C1,cn=P1
          #@TestSteps          server1: delete parent cn=P1
          #@TestSteps          Re-connect Replication Servers
          #@TestSteps          Check servers are synchronised
          #@TestPostamble
          #@TestResult         Success if trees are synchronised
          -->
          <testcase name="getTestCaseName
                          ('add_child_del_parent')">
            <sequence>
              <call function="'testCase_Preamble'"/>
              <message>
                'Replication: Conflict: add_child_del_parent. \
                Add a child vs delete his parent'
              </message>
              <!-- Add entry to server1 -->
              <script>
                parentEntry = Entry('cn=P1')
                parentEntry.addAttr('givenname', 'DUMMY ENTRY')
                childEntry = Entry('cn=C1,cn=P1')
                childEntry.addAttr('givenname', 'DUMMY ENTRY')
                # addedEntries = [[], []]
              </script>
              <call function="'addAnEntry'">
                { 'location'       : server1Host,
                  'dsPath'         : server1Path,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'DNToAdd'        : parentEntry.getDn(),
                  'listAttributes' : parentEntry.getAttrList()
                }
              </call>
              <!-- Disconnect Replication Servers -->
              <call function="'disconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <!-- Add child entry on server2 -->
              <call function="'addAnEntry'">
                { 'location'       : server2Host,
                  'dsPath'         : server2Path,
                  'dsInstanceHost' : server2Host,
                  'dsInstancePort' : server2.getPort(),
                  'dsInstanceDn'   : server2.getRootDn(),
                  'dsInstancePswd' : server2.getRootPwd(),
                  'DNToAdd'        : childEntry.getDn(),
                  'listAttributes' : childEntry.getAttrList()
                }
              </call>
              <!-- Delete parent entry on server1-->
              <call function="'ldapDeleteWithScript'">
                { 'location'       : clientHost,
                  'dsPath'         : clientPath,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'dsDn'           : [parentEntry.getDn()]
                }
              </call>
              <!-- Check modifies have not been propagated -->
              <paralleliterate var="server" in="[server1, server2]">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : synchroSuffix,
                      'dsFilter'       : 'givenname=DUMMY ENTRY',
                      'dsAttributes'   : 'ds-sync-conflict cn'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : 'cn=monitor',
                      'dsFilter'       : monitorFilter,
                      'dsAttributes'   : monitorCounters
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Reconnect Replication Servers -->
              <call function="'reconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <!-- Check conflict is resolved -->
              <paralleliterate var="server"
                               in="[server1, server2]"
                               indexvar="i">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : synchroSuffix,
                      'dsFilter'       : 'givenname=DUMMY ENTRY',
                      'dsAttributes'   : 'ds-sync-conflict cn'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                      <script>
                        resultDnList = []
                        for line in searchResult.splitlines():
                          if line.find('dn: ') != -1:
                            resultDn = line[len('dn: '):]
                            resultDnList.append(resultDn)
                        addedEntries[i] = resultDnList
                      </script>
                    </sequence>
                    <else>
                      <script>
                        addedEntries[i] = []
                      </script>
                    </else>
                  </if>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : 'cn=monitor',
                      'dsFilter'       : monitorFilter,
                      'dsAttributes'   : monitorCounters
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Verify the synchronization of the trees among the servers in
                the topology -->
              <call function="'verifyTrees'">
                [ clientHost, clientPath, server1, [server2], synchroSuffix ]
              </call>
              <!-- Delete added entries -->
              <script>
                list1 = addedEntries[0]
                list2 = addedEntries[1]
                toRemove = []
                # remove potential redundancies, to avoid deleting them twice
                for addedEntry in list2:
                  if addedEntry in list1:
                    toRemove.append(addedEntry)
                for ent in toRemove:
                  list2.remove(ent)
              </script>
              <paralleliterate var="server"
                               in="[server1, server2]"
                               indexvar="i">
                <if expr="len(addedEntries[i]) != 0">
                  <call function="'ldapDeleteWithScript'">
                    { 'location'       : clientHost,
                      'dsPath'         : clientPath,
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsDn'           : addedEntries[i]
                    }
                  </call>
                </if>
              </paralleliterate>
              <!-- Issue visible in the conflict counters, so not automatically
               !   detectable so far.
              <script>
                knownIssue(3400)
              </script>
              -->
              <call function="'testCase_Postamble'"/>
            </sequence>
          </testcase>
          <!--- Test Case information
          #@TestMarker         Replication Conflict Tests
          #@TestName           Replication: Conflict: del_parent_add_child
          #@TestID             del_parent_add_child
          #@TestPurpose        Delete a parent vs add his child
          #@TestPreamble
          #@TestSteps          Add entry cn=P2 to server1
          #@TestSteps          Disconnect Replication Servers
          #@TestSteps          server1: delete parent cn=P2
          #@TestSteps          server2: add child cn=C2,cn=P2
          #@TestSteps          Re-connect Replication Servers
          #@TestSteps          Check servers are synchronised
          #@TestPostamble
          #@TestResult         Success if trees are synchronised
          -->
          <testcase name="getTestCaseName
                          ('del_parent_add_child')">
            <sequence>
              <call function="'testCase_Preamble'"/>
              <message>
                'Replication: Conflict: del_parent_add_child. \
                Delete a parent vs add his child'
              </message>
              <!-- Add entry to server1 -->
              <script>
                parentEntry = Entry('cn=P2')
                parentEntry.addAttr('givenname', 'DUMMY ENTRY')
                childEntry = Entry('cn=C2,cn=P2')
                childEntry.addAttr('givenname', 'DUMMY ENTRY')
                # addedEntries = [[], []]
              </script>
              <call function="'addAnEntry'">
                { 'location'       : server1Host,
                  'dsPath'         : server1Path,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'DNToAdd'        : parentEntry.getDn(),
                  'listAttributes' : parentEntry.getAttrList()
                }
              </call>
              <!-- Disconnect Replication Servers -->
              <call function="'disconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <!-- Delete parent entry on server1-->
              <call function="'ldapDeleteWithScript'">
                { 'location'       : clientHost,
                  'dsPath'         : clientPath,
                  'dsInstanceHost' : server1Host,
                  'dsInstancePort' : server1.getPort(),
                  'dsInstanceDn'   : server1.getRootDn(),
                  'dsInstancePswd' : server1.getRootPwd(),
                  'dsDn'           : [parentEntry.getDn()]
                }
              </call>
              <!-- Add child entry on server2 -->
              <call function="'addAnEntry'">
                { 'location'       : server2Host,
                  'dsPath'         : server2Path,
                  'dsInstanceHost' : server2Host,
                  'dsInstancePort' : server2.getPort(),
                  'dsInstanceDn'   : server2.getRootDn(),
                  'dsInstancePswd' : server2.getRootPwd(),
                  'DNToAdd'        : childEntry.getDn(),
                  'listAttributes' : childEntry.getAttrList()
                }
              </call>
              <!-- Check modifies have not been propagated -->
              <paralleliterate var="server" in="[server1, server2]">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : synchroSuffix,
                      'dsFilter'       : 'givenname=DUMMY ENTRY',
                      'dsAttributes'   : 'ds-sync-conflict cn'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : 'cn=monitor',
                      'dsFilter'       : monitorFilter,
                      'dsAttributes'   : monitorCounters
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Reconnect Replication Servers -->
              <call function="'reconnectReplicationServers'">
                [ clientHost, clientPath, [server1, server2] ]
              </call>
              <!-- Check conflict is resolved -->
              <paralleliterate var="server"
                               in="[server1, server2]"
                               indexvar="i">
                <sequence>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : synchroSuffix,
                      'dsFilter'       : 'givenname=DUMMY ENTRY',
                      'dsAttributes'   : 'ds-sync-conflict cn'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                      <script>
                        resultDnList = []
                        for line in searchResult.splitlines():
                          if line.find('dn: ') != -1:
                            resultDn = line[len('dn: '):]
                            resultDnList.append(resultDn)
                        addedEntries[i] = resultDnList
                      </script>
                    </sequence>
                    <else>
                      <script>
                        addedEntries[i] = []
                      </script>
                    </else>
                  </if>
                  <call function="'ldapSearchWithScript'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : 'cn=monitor',
                      'dsFilter'       : monitorFilter,
                      'dsAttributes'   : monitorCounters
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '+++++++++++ LDAPSEARCH RESULT for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </paralleliterate>
              <!-- Verify the synchronization of the trees among the servers in
                the topology -->
              <call function="'verifyTrees'">
                [ clientHost, clientPath, server1, [server2], synchroSuffix ]
              </call>
              <!-- Delete added entries -->
              <script>
                list1 = addedEntries[0]
                list2 = addedEntries[1]
                toRemove = []
                # remove potential redundancies, to avoid deleting them twice
                for addedEntry in list2:
                  if addedEntry in list1:
                    toRemove.append(addedEntry)
                for ent in toRemove:
                  list2.remove(ent)
              </script>
              <paralleliterate var="server"
                               in="[server1, server2]"
                               indexvar="i">
                <if expr="len(addedEntries[i]) != 0">
                  <call function="'ldapDeleteWithScript'">
                    { 'location'       : clientHost,
                      'dsPath'         : clientPath,
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsDn'           : addedEntries[i]
                    }
                  </call>
                </if>
              </paralleliterate>
              <!-- Issue visible in the conflict counters, so not automatically
               !   detectable so far.
              <script>
                knownIssue(3400)
              </script>
              -->
              <call function="'testCase_Postamble'"/>
            </sequence>
          </testcase>
          <import machine="STAF_LOCAL_HOSTNAME"
            file="'%s/testcases/replication/replication_cleanup.xml'
                  % (TESTS_DIR)"/>
          <call function="'replication_cleanup'" />
          <call function="'testSuite_Postamble'"/>
        </sequence>
      </block>
    </sequence>
  </function>
</stax>
opends/tests/functional-tests/testcases/replication/replication.xml
@@ -40,7 +40,7 @@
          <iterate  var="_test" 
                    in="['totalupdate','binarycopy','ldifimport',
                         'resynchronization','basic','schema','failover',
                         'encryption','changelog']">
                         'encryption','changelog', 'conflict']">
            <sequence>
              <import machine="STAF_LOCAL_HOSTNAME"
                      file="'%s/testcases/replication/%s/%s.xml' % 
opends/tests/functional-tests/testcases/replication/replication_setup.xml
@@ -60,6 +60,23 @@
        </function-arg-description>
        <function-arg-property name="type" value="filename"/>
      </function-arg-def>
      <function-arg-def name="isolateLdapServers"
                        type="optional"
                        default="None">
        <function-arg-description>
          Break the cross-reference between Ldap Servers and Replication Servers
          (i.e. make LS1 point to RS1 exclusively, LS2 to RS2, etc.)
        </function-arg-description>
        <function-arg-property name="type" value="boolean"/>
      </function-arg-def>
      <function-arg-def name="enableDebugLogs"
                        type="optional"
                        default="None">
        <function-arg-description>
          Enable de debug logs
        </function-arg-description>
        <function-arg-property name="type" value="boolean"/>
      </function-arg-def>
    </function-map-args>    
    
    <sequence>
@@ -82,12 +99,14 @@
                 
          <call function="'createTopology'">
            { 'topologyDescFile' : topologyFile,
              'sharedDataFolder' : 'replication' }
              'sharedDataFolder' : 'replication'
            }
          </call>  
      
          <call function="'checkRC'">
            { 'returncode' : RC ,
              'result'     : STAXResult }
              'result'     : STAXResult
            }
          </call>
          <!-- Setup variables -->
@@ -108,7 +127,9 @@
            synchroSuffix = master.getSynchronizedSuffixList()[0].getSuffixDn()
            masterBackupDir = '%s/replication/master_backup' % masterDataDir
            
            consumerList = _topologyServerList[1:]
            consumerList = _topologyServerList[1:]
            domainMap = {}
          </script>       
          <if expr="dataFile">
@@ -151,8 +172,8 @@
          <iterate var="server" in="consumerList">
            <sequence>
              <!-- Configure replication if required so by the server
              !  (i.e. server is a changelog server and/or has synchronized
              !  suffixes)
               !  (i.e. server is a changelog server and/or has synchronized
               !  suffixes)
              -->
              <if expr="server.requiresSynchronization()">
                <sequence>          
@@ -200,6 +221,75 @@
            </sequence>              
          </iterate>           
          <if expr="isolateLdapServers">
            <!-- Make each Ldap Server point only to its own Replication
             !   Server.
             !   This is used by the Conflict testsuite, in order to be able
             !   to simulate conflict scenarios -->
            <paralleliterate var="server" in="_topologyServerList">
              <sequence>
                <script>
                  ldapServer = '%s:%s' % (server.getHostname(),
                                          server.getPort())
                </script>
                <!-- Retrieve replication-domain name -->
                <call function="'dsconfig'">
                  { 'location'       : server.getHostname(),
                    'dsPath'         : '%s/%s' % (server.getDir(),OPENDSNAME),
                    'dsInstanceHost' : server.getHostname(),
                    'dsInstancePort' : server.getPort(),
                    'dsInstanceDn'   : server.getRootDn(),
                    'dsInstancePswd' : server.getRootPwd(),
                    'subcommand'     : 'list-replication-domains',
                    'objectType'     : 'provider-name',
                    'objectName'     : 'Multimaster Synchronization',
                    'optionsString'  : '--script-friendly'
                  }
                </call>
                <if expr='RC == 0'>
                  <script>
                    replicationDomains = STAXResult[0][1]
                    for line in replicationDomains.splitlines():
                      if line.find(synchroSuffix) != -1:
                        domain = line
                        domainMap[ldapServer] = domain
                        break
                  </script>
                </if>
                <script>
                  replicationServer = server.getChangelogServer()
                  replServer = '%s:%s' % (server.getHostname(),
                                          replicationServer.getPort())
                  options = '--domain-name "%s" --set replication-server:%s' \
                            % (domainMap[ldapServer], replServer)
                </script>
                <message>
                  'Removing references to other replication servers \nfor \
                  domain: %s \nfrom server: %s \nkeep replication server: %s' \
                  % (domain, ldapServer, replServer)
                </message>
                <!-- Remove peer RS from replicated domain -->
                <call function="'dsconfig'">
                  { 'location'       : server.getHostname(),
                    'dsPath'         : '%s/%s' % (server.getDir(),OPENDSNAME),
                    'dsInstanceHost' : server.getHostname(),
                    'dsInstancePort' : server.getPort(),
                    'dsInstanceDn'   : server.getRootDn(),
                    'dsInstancePswd' : server.getRootPwd(),
                    'subcommand'     : 'set-replication-domain-prop',
                    'objectType'     : 'provider-name',
                    'objectName'     : 'Multimaster Synchronization',
                    'optionsString'  : options
                  }
                </call>
              </sequence>
            </paralleliterate>
          </if>
          <if expr="dataFile">
            <sequence>
              <message>
@@ -215,11 +305,108 @@
                  'sourceInstancePort' : master.getPort(),
                  'replicationDnList'  : [synchroSuffix]
                }
              </call>
              </call>
              <if expr="0">
              <iterate var="server" in="consumerList">
                <sequence>
<!--                  <call function="'initializeReplication'">
                    { 'location'           : clientHost,
                      'dsPath'             : clientPath,
                      'dsInstanceHost'     : server.getHostname(),
                      'dsInstancePort'     : server.getPort(),
                      'sourceInstanceHost' : masterHost,
                      'sourceInstancePort' : master.getPort(),
                      'replicationDnList'  : [synchroSuffix]
                    }
                  </call> -->
                  <!-- Search initialisation task to check its status -->
                  <call function="'ldapSearchWithScript'">
                    {
                      'location'       : server.getHostname(),
                      'dsPath'         : '%s/%s' \
                                         % (server.getDir(), OPENDSNAME),
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'dsBaseDN'       : 'cn=Tasks',
                      'dsFilter'       : 'ds-task-initialize-domain-dn=%s' \
                                         % synchroSuffix
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <if expr="resultLength != 0">
                    <sequence>
                      <message>
                        '++++++++ INITIALISATION TASK for %s:%s ++++++++\n%s' \
                        % (server.getHostname(), server.getPort(), searchResult)
                      </message>
                    </sequence>
                  </if>
                </sequence>
              </iterate>
              </if>
              
            </sequence>              
          </if>
          </if>
          <if expr="enableDebugLogs">
            <paralleliterate var="server" in="_topologyServerList">
              <sequence>
                <!-- Set the debug logger to "enabled" -->
                <call function="'dsconfigSet'">
                  { 'location'         : server.getHostname(),
                    'dsPath'           : '%s/%s' % (server.getDir(),OPENDSNAME),
                    'dsInstanceHost'   : server.getHostname(),
                    'dsInstancePort'   : server.getPort(),
                    'dsInstanceDn'     : server.getRootDn(),
                    'dsInstancePswd'   : server.getRootPwd(),
                    'objectName'       : 'log-publisher',
                    'propertyType'     : 'publisher',
                    'propertyName'     : 'File-based Debug Logger',
                    'attributeName'    : 'enabled',
                    'attributeValue'   : 'true'
                  }
                </call>
                <!-- Set the debug level to "info" -->
                <call function="'dsconfigSet'">
                  { 'location'         : server.getHostname(),
                    'dsPath'           : '%s/%s' % (server.getDir(),OPENDSNAME),
                    'dsInstanceHost'   : server.getHostname(),
                    'dsInstancePort'   : server.getPort(),
                    'dsInstanceDn'     : server.getRootDn(),
                    'dsInstancePswd'   : server.getRootPwd(),
                    'objectName'       : 'log-publisher',
                    'propertyType'     : 'publisher',
                    'propertyName'     : 'File-based Debug Logger',
                    'attributeName'    : 'default-debug-level',
                    'attributeValue'   : 'info'
                  }
                </call>
                <!-- Set the debug logger log file to "logs/errors" -->
                <call function="'dsconfigSet'">
                  { 'location'         : server.getHostname(),
                    'dsPath'           : '%s/%s' % (server.getDir(),OPENDSNAME),
                    'dsInstanceHost'   : server.getHostname(),
                    'dsInstancePort'   : server.getPort(),
                    'dsInstanceDn'     : server.getRootDn(),
                    'dsInstancePswd'   : server.getRootPwd(),
                    'objectName'       : 'log-publisher',
                    'propertyType'     : 'publisher',
                    'propertyName'     : 'File-based Debug Logger',
                    'attributeName'    : 'log-file',
                    'attributeValue'   : 'logs/errors'
                  }
                </call>
              </sequence>
            </paralleliterate>
          </if>
        </sequence>
      </block>
opends/tests/shared/functions/dsconfig.xml
@@ -2264,4 +2264,185 @@
    </sequence>
  </function>
  <function name="disconnectReplicationServers">
    <function-prolog>
      This function breaks the connection among a group of replication servers
      by resetting the replication-server attribute in the replication server of
      a given list of servers.
    </function-prolog>
    <function-list-args>
      <function-arg-def name="location"
                        type="optional"
                        default="STAF_REMOTE_HOSTNAME">
        <function-arg-description>
          Location of target host
        </function-arg-description>
        <function-arg-property name="type" value="hostname" />
      </function-arg-def>
      <function-arg-def name="dsPath"
                        type="optional"
                        default="'%s/%s' % (DIRECTORY_INSTANCE_DIR,OPENDSNAME)">
        <function-arg-description>
          Pathname to installation root
        </function-arg-description>
        <function-arg-property name="type" value="filepath" />
      </function-arg-def>
      <function-arg-def name="serverList" type="required">
        <function-arg-description>
          List of the servers whose replication servers are to be disconnected.
        </function-arg-description>
        <function-arg-property name="type" value="Server-list"/>
      </function-arg-def>
      <function-arg-def name="expectedRC" type="optional" default="0">
        <function-arg-description>
          Expected return code value. Default value is 0.
          Wildcard 'noCheck' to not check the RC
        </function-arg-description>
        <function-arg-property name="type" value="string" />
      </function-arg-def>
    </function-list-args>
    <sequence>
      <paralleliterate var="server" in="serverList">
        <sequence>
          <script>
            ldapServer = '%s:%s' % (server.getHostname(),
                                    server.getPort())
            replicationServer = server.getChangelogServer()
            replServer = '%s:%s' % (server.getHostname(),
                                    replicationServer.getPort())
          </script>
          <message>
            'Disconnecting \nreplication server: %s \nin server: %s' \
            % (replServer, ldapServer)
          </message>
          <!-- Remove peer RS from replicated domain -->
          <call function="'dsconfig'">
            { 'location'       : server.getHostname(),
              'dsPath'         : '%s/%s' % (server.getDir(),OPENDSNAME),
              'dsInstanceHost' : server.getHostname(),
              'dsInstancePort' : server.getPort(),
              'dsInstanceDn'   : server.getRootDn(),
              'dsInstancePswd' : server.getRootPwd(),
              'subcommand'     : 'set-replication-server-prop',
              'objectType'     : 'provider-name',
              'objectName'     : 'Multimaster Synchronization',
              'optionsString'  : '--reset replication-server',
              'expectedRC'     : expectedRC
            }
          </call>
        </sequence>
      </paralleliterate>
      <return>
        STAXResult
      </return>
    </sequence>
  </function>
  <function name="reconnectReplicationServers">
    <function-prolog>
      This function re-establishes the connection among a group of replication
      servers by setting the replication-server attribute in the replication
      server of a server with the replication servers of a given list of servers
    </function-prolog>
    <function-list-args>
      <function-arg-def name="location"
                        type="optional"
                        default="STAF_REMOTE_HOSTNAME">
        <function-arg-description>
          Location of target host
        </function-arg-description>
        <function-arg-property name="type" value="hostname" />
      </function-arg-def>
      <function-arg-def name="dsPath"
                        type="optional"
                        default="'%s/%s' % (DIRECTORY_INSTANCE_DIR,OPENDSNAME)">
        <function-arg-description>
          Pathname to installation root
        </function-arg-description>
        <function-arg-property name="type" value="filepath" />
      </function-arg-def>
      <function-arg-def name="serverList" type="required">
        <function-arg-description>
          List of the servers whose replication servers are to be reconnected.
        </function-arg-description>
        <function-arg-property name="type" value="Server-list"/>
      </function-arg-def>
      <function-arg-def name="expectedRC" type="optional" default="0">
        <function-arg-description>
          Expected return code value. Default value is 0.
          Wildcard 'noCheck' to not check the RC
        </function-arg-description>
        <function-arg-property name="type" value="string" />
      </function-arg-def>
    </function-list-args>
    <sequence>
      <script>
        optionList = []
        replServerList = []
        mainServer = serverList[0]
      </script>
      <iterate var="server" in="serverList">
        <sequence>
          <script>
            ldapServer = '%s:%s' % (server.getHostname(),
                                    server.getPort())
            replicationServer = server.getChangelogServer()
            replServer = '%s:%s' % (server.getHostname(),
                                    replicationServer.getPort())
            optionList.append('--set replication-server:%s' % replServer)
            replServerList.append(replServer)
          </script>
        </sequence>
      </iterate>
      <script>
        optionString = ' '.join(optionList)
        replServers = ' '.join(replServerList)
      </script>
      <message>
        'Reconnecting \nreplication servers: %s \nin server: %s:%s' \
        % (replServers, mainServer.getHostname(),
           mainServer.getPort())
      </message>
      <!-- Remove peer RS from replicated domain -->
      <call function="'dsconfig'">
        { 'location'       : mainServer.getHostname(),
          'dsPath'         : '%s/%s' \
                             % (mainServer.getDir(),OPENDSNAME),
          'dsInstanceHost' : mainServer.getHostname(),
          'dsInstancePort' : mainServer.getPort(),
          'dsInstanceDn'   : mainServer.getRootDn(),
          'dsInstancePswd' : mainServer.getRootPwd(),
          'subcommand'     : 'set-replication-server-prop',
          'objectType'     : 'provider-name',
          'objectName'     : 'Multimaster Synchronization',
          'optionsString'  : optionString,
          'expectedRC'     : expectedRC
        }
      </call>
      <return>
        STAXResult
      </return>
    </sequence>
  </function>
</stax>
opends/tests/shared/java/ldap/modifyAnAttribute.java
@@ -108,7 +108,12 @@
        ind1= val1.indexOf(":");
        attributeName=val1.substring(0,ind1);
        attributeValue=val1.substring(ind1+1);
        if (ind1+1 < val1.length()) {
          // assume empty strings == no specific value
          attributeValue=val1.substring(ind1+1);
        } else {
          attributeValue = null;
        }
        BasicAttribute attrToComplete = null;
@@ -124,20 +129,29 @@
          attrToComplete = new BasicAttribute(attributeName);
          attributeSet.add(attrToComplete);
        }
        attributeValue=attributeValue.replaceAll("QUOT","\\\"");
        attrToComplete.add(attributeValue);
        if (attributeValue != null) {
          // as opposed to (attributeValue == null), for example in some
          // attribute delete operations
          attributeValue=attributeValue.replaceAll("QUOT","\\\"");
          attrToComplete.add(attributeValue);
        }
      }
      k++;
    }
    if ( attributeToModify != null && newAttributeValue != null ) {
    if ( attributeToModify != null &&
         ( newAttributeValue != null || changetype.equals("delete") ) ) {
      BasicAttribute attrToComplete = null;
      attrToComplete = new BasicAttribute(attributeToModify);
      attributeSet.add(attrToComplete);
      newAttributeValue=newAttributeValue.replaceAll("QUOT","\\\"");
      attrToComplete.add(newAttributeValue);
      if (newAttributeValue != null) {
        // as opposed to (attributeValue == null), for example in some
        // attribute delete operations
        newAttributeValue=newAttributeValue.replaceAll("QUOT","\\\"");
        attrToComplete.add(newAttributeValue);
      }
    }
    Iterator it2 = attributeSet.iterator();