@Requires(IRepositoryConfig.CAPABILITY_BRANCHING)
  public void testXRefMergeManyValueTest() throws Exception {
    // setup transaction.
    final CDOSession session = openSession();
    final CDOTransaction tr1 = session.openTransaction();
    tr1.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.ALL);

    final CDOResource resource = tr1.createResource(getResourcePath("/test1"));
    RefMultiContained container = getModel4Factory().createRefMultiContained();
    resource.getContents().add(container);

    tr1.commit();
    sleep(1000);

    final CDOBranch otherBranch = tr1.getBranch().createBranch("other");
    final CDOTransaction tr2 = session.openTransaction(otherBranch);

    RefMultiContained otherContainer = tr2.getObject(container);
    assertNotNull(otherContainer);

    // add a new element on other branch at index 0.
    otherContainer.getElements().add(0, getModel4Factory().createMultiContainedElement());

    tr2.commit();

    // sleep to have the merger see the changes.
    sleep(1000);

    // merge the other branch to main.
    tr1.merge(tr2.getBranch().getHead(), new DefaultCDOMerger.PerFeature.ManyValued());

    tr1.commit();
    assertEquals(false, tr1.isDirty());
  }
  @Requires(IRepositoryConfig.CAPABILITY_BRANCHING)
  public void testTargetGoalDeltaVersion() throws Exception {
    skipStoreWithoutChangeSets();

    // setup 2 transactions.
    final CDOSession session1 = openSession();
    final CDOTransaction s1Tr1 = session1.openTransaction();
    s1Tr1.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.ALL);
    final CDOTransaction s1Tr2 = session1.openTransaction();
    s1Tr2.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.ALL);

    // create resource, container and 2 elements using transaction 1.
    final CDOResource resource = s1Tr1.createResource(getResourcePath("/test1"));
    RefMultiContained container = getModel4Factory().createRefMultiContained();
    resource.getContents().add(container);
    MultiContainedElement element1 = getModel4Factory().createMultiContainedElement();
    container.getElements().add(element1);
    MultiContainedElement element2 = getModel4Factory().createMultiContainedElement();
    container.getElements().add(element2);

    commitAndSync(s1Tr1, s1Tr2);

    // access container on transaction 2 to have it updated with a RevisionDelta.
    RefMultiContained container2 = s1Tr2.getObject(container);

    // setup another branch.
    final CDOBranch otherBranch = s1Tr1.getBranch().createBranch("other");
    final CDOTransaction s1Tr3 = session1.openTransaction(otherBranch);

    RefMultiContained otherContainer = s1Tr3.getObject(container);
    assertNotSame(null, otherContainer);
    assertEquals(true, otherContainer.getElements().size() > 0);

    // remove an element on the other branch.
    otherContainer.getElements().remove(0);

    commitAndSync(s1Tr3, s1Tr1);

    // merge the other branch to main (this creates the targetGoalDelta for the RevisionDelta).
    s1Tr1.merge(s1Tr3.getBranch().getHead(), new DefaultCDOMerger.PerFeature.ManyValued());

    commitAndSync(s1Tr1, s1Tr2);

    // check the change on tr2 and do another change.
    assertEquals(false, s1Tr1.isDirty());
    container2.getElements().remove(0);

    commitAndSync(s1Tr2, s1Tr1); // <--- this commit will throw the following exception:
    // java.util.ConcurrentModificationException:
    // Attempt by Transaction[2:2] to modify historical revision: RefMultiContained@OID4:0v1
    assertEquals(false, s1Tr1.isDirty());

    // check revision versions.
    assertEquals(
        CDOUtil.getCDOObject(container).cdoRevision().getVersion(),
        CDOUtil.getCDOObject(container2).cdoRevision().getVersion());
  }