public void testTemporaryObject() throws Exception {
    msg("Opening session");
    final CDOSession session = openSession();

    // ************************************************************* //

    msg("Creating category1");
    final Category category1A = getModel1Factory().createCategory();
    category1A.setName("category1");

    msg("Creating company");
    final Company companyA = getModel1Factory().createCompany();

    msg("Adding categories");
    companyA.getCategories().add(category1A);

    msg("Opening transaction");
    final CDOTransaction transaction = session.openTransaction();
    transaction.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.ALL);
    msg("Creating resource");
    final CDOResource resourceA = transaction.createResource(getResourcePath("/test1"));

    msg("Adding company");
    resourceA.getContents().add(companyA);

    msg("Committing");

    final TestAdapter adapter = new TestAdapter();
    category1A.eAdapters().add(adapter);

    transaction.commit();

    // ************************************************************* //

    msg("Opening view");
    final CDOSession session2 = openSession();
    final CDOTransaction transaction2 = session2.openTransaction();
    transaction.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.ALL);

    final Category category1B =
        (Category)
            CDOUtil.getEObject(
                transaction2.getObject(CDOUtil.getCDOObject(category1A).cdoID(), true));

    msg("Changing name");
    category1B.setName("CHANGED NAME");

    assertEquals(0, adapter.getNotifications().length);

    msg("Committing");
    transaction2.commit();

    msg("Checking after commit");
    new PollingTimeOuter() {
      @Override
      protected boolean successful() {
        return adapter.getNotifications().length == 1;
      }
    }.assertNoTimeOut();
  }
  public void testSameSession_WithoutPolicy() throws Exception {
    final Category category1A = getModel1Factory().createCategory();
    category1A.setName("category1");

    final Company companyA = getModel1Factory().createCompany();
    companyA.getCategories().add(category1A);

    final CDOSession session = openSession();

    // ************************************************************* //

    final CDOTransaction transaction = session.openTransaction();

    final CDOResource resourceA = transaction.createResource(getResourcePath("/test1"));
    resourceA.getContents().add(companyA);

    transaction.commit();
    final TestAdapter adapter = new TestAdapter();
    category1A.eAdapters().add(adapter);

    // ************************************************************* //

    final CDOTransaction transaction2 = session.openTransaction();

    final Category category1B =
        (Category)
            CDOUtil.getEObject(
                transaction2.getObject(CDOUtil.getCDOObject(category1A).cdoID(), true));
    category1B.setName("CHANGED NAME");
    assertEquals(0, adapter.getNotifications().length);

    transaction2.commit();

    new PollingTimeOuter() {
      @Override
      protected boolean successful() {
        // Commit notifications from the same session always have full deltas
        Notification[] notifications = adapter.getNotifications();
        return notifications.length == 1;
      }
    }.assertNoTimeOut();

    // Adding policy
    transaction.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.ALL);
    adapter.clearNotifications();

    category1B.setName("CHANGED NAME_VERSION 2");
    assertEquals(0, adapter.getNotifications().length);

    transaction2.commit();

    new PollingTimeOuter() {
      @Override
      protected boolean successful() {
        // Commit notifications from the same session always have full deltas
        Notification[] notifications = adapter.getNotifications();
        return notifications.length == 1;
      }
    }.assertNoTimeOut();
  }
  private CDOID setUpChangesOnBranches() throws Exception {
    CDOSession session = openSession();
    CDOBranch b1Branch = session.getBranchManager().getMainBranch().createBranch(B1_BRANCH_NAME);

    CDOTransaction transaction = session.openTransaction(b1Branch);
    CDOResource resource = transaction.getResource(getResourcePath(RESOURCE_NAME));
    Company company = (Company) resource.getContents().get(0);
    for (int i = 0; i < NB_CATEGORY; i++) {
      company.getCategories().add(getModel1Factory().createCategory());
    }
    transaction.commit();
    transaction.close();

    CDOBranch b2Branch = b1Branch.createBranch(B11_BRANCH_NAME);

    transaction = session.openTransaction(b2Branch);
    resource = transaction.getResource(getResourcePath(RESOURCE_NAME));
    company = (Company) resource.getContents().get(0);
    for (int i = 0; i < NB_CATEGORY; i++) {
      company.getCategories().add(getModel1Factory().createCategory());
    }
    transaction.commit();
    transaction.close();
    session.close();

    return CDOUtil.getCDOObject(company).cdoID();
  }
  private void implicitRelease(
      Company company,
      LockType type,
      CDOTransaction tx,
      TestListener2 controlViewListener,
      boolean mustReceiveNotifications)
      throws CommitException {
    CDOViewLocksChangedEvent e;
    CDOObject cdoCompany = CDOUtil.getCDOObject(company);

    company.setName(company.getName() + "x"); // Make name field dirty
    cdoCompany.cdoWriteLock().lock();

    if (mustReceiveNotifications) {
      controlViewListener.waitFor(1);
      e = (CDOViewLocksChangedEvent) controlViewListener.getEvents().get(0);
      assertSame(Operation.LOCK, e.getOperation());
      assertSame(LockType.WRITE, e.getLockType());
    }

    tx.commit();

    if (mustReceiveNotifications) {
      controlViewListener.waitFor(2);
      e = (CDOViewLocksChangedEvent) controlViewListener.getEvents().get(1);
      assertSame(Operation.UNLOCK, e.getOperation());
      assertNull(e.getLockType());
    }

    if (!mustReceiveNotifications) {
      assertEquals(0, controlViewListener.getEvents().size());
    }
  }
  public void testAddNewObjectInObject() throws Exception {
    {
      msg("Open session & local transaction");
      CDOSession session = openSession();
      CDOTransaction transaction = session.openTransaction();
      CDOPushTransaction pushTransaction = openPushTransaction(transaction);
      file = pushTransaction.getFile();
      CDOResource resource = transaction.getOrCreateResource(getResourcePath(resourcePath));
      msg("Create a new element");
      Category category = getModel1Factory().createCategory();
      Company company = (Company) resource.getContents().get(1);
      company.getCategories().add(category);
      msg("Commit");
      pushTransaction.commit();
      session.close();
    }

    {
      msg("Reload previous local session");
      CDOSession session = openSession();
      CDOTransaction transaction = session.openTransaction();
      CDOPushTransaction pushTransaction = openPushTransaction(transaction, file);
      assertEquals(true, transaction.isDirty());
      assertEquals(1, transaction.getRevisionDeltas().size());
      CDORevisionDelta delta = transaction.getRevisionDeltas().values().iterator().next();
      assertNotNull(delta);
      push(transaction, pushTransaction);
      session.close();
    }

    CDOSession session = openSession();
    CDOView view = session.openView();
    CDOResource resource = view.getResource(getResourcePath(resourcePath));
    assertEquals(2, resource.getContents().size());
  }
  public void testSeparateSession() throws Exception {
    Category category1A = getModel1Factory().createCategory();
    category1A.setName("category1");

    Company companyA = getModel1Factory().createCompany();
    companyA.getCategories().add(category1A);

    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();
    transaction.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.ALL);

    CDOResource resourceA = transaction.createResource(getResourcePath("/test1"));
    resourceA.getContents().add(companyA);
    transaction.commit();

    final TestAdapter adapter = new TestAdapter();
    category1A.eAdapters().add(adapter);

    // ************************************************************* //

    CDOSession session2 = openSession();
    CDOTransaction transaction2 = session2.openTransaction();

    Category category1B =
        (Category)
            CDOUtil.getEObject(
                transaction2.getObject(CDOUtil.getCDOObject(category1A).cdoID(), true));
    category1B.setName("CHANGED NAME");
    assertEquals(0, adapter.getNotifications().length);

    transaction2.commit();

    new PollingTimeOuter() {
      @Override
      protected boolean successful() {
        // Change subscription leads to delta nnotification
        Notification[] notifications = adapter.getNotifications();
        return notifications.length == 1;
      }
    }.assertNoTimeOut();

    // Removing policy
    transaction.options().removeChangeSubscriptionPolicy(CDOAdapterPolicy.ALL);
    adapter.clearNotifications();

    category1B.setName("CHANGED NAME_VERSION 2");
    assertEquals(0, adapter.getNotifications().length);

    transaction2.commit();

    new PollingTimeOuter() {
      @Override
      protected boolean successful() {
        // No change subscription, other session ==> no delta notification
        Notification[] notifications = adapter.getNotifications();
        return notifications.length != 0;
      }
    }.assertTimeOut();
  }
  @Requires(IRepositoryConfig.CAPABILITY_AUDITING)
  public void testReloadingRevisions() throws Exception {
    final String RESOURCE_NAME = "resource";

    Set<CDOID> ids = new HashSet<CDOID>();
    long timeStampOfHoleCommit;

    CDOSession initialSession = openSession();
    {
      // create model history
      CDOTransaction openTransaction = initialSession.openTransaction();
      CDOResource resource = openTransaction.getOrCreateResource(getResourcePath(RESOURCE_NAME));

      // creating initial commit
      Company createdCompany = getModel1Factory().createCompany();
      createdCompany.setName("CompanyTesting");
      createdCompany.setCity("City");
      createdCompany.setStreet("Street");

      resource.getContents().add(createdCompany);

      openTransaction.commit();

      // collect id's
      for (TreeIterator<EObject> allContents = resource.getAllContents(); allContents.hasNext(); ) {
        CDOObject next = CDOUtil.getCDOObject(allContents.next());
        ids.add(next.cdoID());
      }

      // making holes - detaching
      List<EObject> contents = new ArrayList<EObject>(resource.getContents());
      for (int i = 0; i < contents.size(); i++) {
        EcoreUtil.delete(contents.get(i), true);
      }

      timeStampOfHoleCommit = openTransaction.commit().getTimeStamp();
    }

    // check when locally cached elements are availabe
    checkRevisionsOnGivenSession(ids, timeStampOfHoleCommit, 2, initialSession);

    // turn of revision download by timestamp
    checkRevisionsOnGivenSession(ids, -1, 2, initialSession);
    initialSession.close();

    checkRevisions(ids, timeStampOfHoleCommit, 2);

    // turn of revision download by timestamp
    checkRevisions(ids, -1, 2);

    // clear caches
    clearCache(getRepository().getRevisionManager());
    checkRevisions(ids, timeStampOfHoleCommit, 2);

    // turn of revision download by timestamp
    clearCache(getRepository().getRevisionManager());
    checkRevisions(ids, -1, 2);
  }
  public void testRemoveContained() throws Exception {
    List<Category> categories = new ArrayList<Category>();
    categories.add(getModel1Factory().createCategory());

    Company company = getModel1Factory().createCompany();
    company.getCategories().add(getModel1Factory().createCategory());
    company.getCategories().add(getModel1Factory().createCategory());
    company.getCategories().add(getModel1Factory().createCategory());
    company.getCategories().addAll(categories);
    company.getCategories().add(getModel1Factory().createCategory());
    company.getCategories().add(getModel1Factory().createCategory());
    company.getCategories().add(getModel1Factory().createCategory());

    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();
    CDOResource resource = transaction.createResource(getResourcePath("/test1"));
    resource.getContents().add(company);
    transaction.commit();

    CDOSession session2 = openSession();
    CDOView view = session2.openView();
    view.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.ALL);

    CDOResource resource2 = view.getResource(getResourcePath("/test1"));
    Company company2 = (Company) resource2.getContents().get(0);

    Object[] strongRefs = company2.getCategories().toArray(); // Keep those in memory
    msg(strongRefs);

    final TestAdapter adapter = new TestAdapter();
    company2.eAdapters().add(adapter);

    company.getCategories().removeAll(categories);
    transaction.commit();

    final Object[] oldValue = {null};
    new PollingTimeOuter() {
      @Override
      protected boolean successful() {
        for (Notification notification : adapter.getNotifications()) {
          if (notification.getEventType() == Notification.REMOVE
              && notification.getFeature() == getModel1Package().getCompany_Categories()) {
            oldValue[0] = notification.getOldValue();
            return true;
          }
        }

        return false;
      }
    }.assertNoTimeOut();

    assertInstanceOf(Category.class, CDOUtil.getEObject((EObject) oldValue[0]));
  }
 @Override
 public void setUp() throws Exception {
   super.setUp();
   CDOSession session = openSession();
   CDOTransaction transaction = session.openTransaction();
   CDOResource resource = transaction.createResource(getResourcePath(RESOURCE_NAME));
   Company company = getModel1Factory().createCompany();
   for (int i = 0; i < NB_CATEGORY; i++) {
     Category category = getModel1Factory().createCategory();
     company.getCategories().add(category);
   }
   resource.getContents().add(company);
   transaction.commit();
   transaction.close();
   session.close();
 }
  private void testCDORevisionFetchWithChangesOnAllBranches(
      CDOSession session,
      CDOBranch currentBranch,
      SignalCounter signalCounter,
      CDOID companyCDOID,
      int expectedNbCategories,
      boolean prefetch) {
    CDOView view = session.openView(currentBranch);
    assertEquals(0, signalCounter.getCountFor(LoadRevisionsRequest.class));

    String resourcePath = getResourcePath(RESOURCE_NAME);
    List<String> pathSegments = CDOURIUtil.analyzePath(resourcePath);
    CDOResource resource = view.getResource(resourcePath);
    assertEquals(pathSegments.size(), signalCounter.getCountFor(LoadRevisionsRequest.class));

    if (prefetch) {
      resource.cdoPrefetch(CDORevision.DEPTH_INFINITE);
    }
    assertEquals(RESOURCE_NAME, resource.getName());
    EObject eObject = resource.getContents().get(0);
    Assert.assertTrue(eObject instanceof Company);
    Company company = (Company) eObject;
    assertEquals(pathSegments.size() + 1, signalCounter.getCountFor(LoadRevisionsRequest.class));
    Assert.assertEquals(expectedNbCategories, company.getCategories().size());

    view.getRevision(companyCDOID);

    assertEquals(pathSegments.size() + 1, signalCounter.getCountFor(LoadRevisionsRequest.class));

    view.getResourceSet().eAdapters().add(new EContentAdapter());

    assertEquals(pathSegments.size() + 1, signalCounter.getCountFor(LoadRevisionsRequest.class));

    view.close();
    signalCounter.clearCounts();
  }
  /** See bug 315409. */
  @Requires(IRepositoryConfig.CAPABILITY_BRANCHING)
  public void _testInvalidationWithDeltas_SubBranch() throws Exception {
    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();

    Company company = getModel1Factory().createCompany();
    company.setName("main-v1");

    CDOResource resource = transaction.createResource(getResourcePath("/test1"));
    resource.getContents().add(company);

    transaction.commit();

    company.setName("main-v2");
    transaction.commit();

    CDOBranch subBranch = transaction.getBranch().createBranch("SUB_BRANCH");
    transaction.setBranch(subBranch);

    CDOView view = session.openView(subBranch);
    view.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.ALL);
    Company company2 = view.getObject(company);
    company2.eAdapters().add(new AdapterImpl());

    company.setName("sub-v1");
    commitAndSync(transaction, view);

    CDORevision revision2 = CDOUtil.getCDOObject(company2).cdoRevision();
    assertEquals(1, revision2.getVersion());
    assertEquals(transaction.getBranch(), revision2.getBranch());
    assertEquals(transaction.getLastCommitTime(), revision2.getTimeStamp());

    company.setName("sub-v2");
    commitAndSync(transaction, view);

    revision2 = CDOUtil.getCDOObject(company2).cdoRevision();
    assertEquals(2, revision2.getVersion());
    assertEquals(transaction.getBranch(), revision2.getBranch());
    assertEquals(transaction.getLastCommitTime(), revision2.getTimeStamp());
  }
  /** See bug 315409. */
  public void testInvalidationWithDeltas_SameBranch() throws Exception {
    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();
    CDOView view = session.openView();

    Company company = getModel1Factory().createCompany();
    company.setName("main-v1");

    CDOResource resource = transaction.createResource(getResourcePath("/test1"));
    resource.getContents().add(company);

    commitAndSync(transaction, view);

    company.setName("main-v2");
    commitAndSync(transaction, view);

    view.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.ALL);
    Company company2 = view.getObject(company);
    company2.eAdapters().add(new AdapterImpl());

    company.setName("main-v3");
    commitAndSync(transaction, view);

    CDORevision revision2 = CDOUtil.getCDOObject(company2).cdoRevision();
    assertEquals(3, revision2.getVersion());
    assertEquals(transaction.getBranch(), revision2.getBranch());
    assertEquals(transaction.getLastCommitTime(), revision2.getTimeStamp());

    company.setName("main-v4");
    commitAndSync(transaction, view);

    revision2 = CDOUtil.getCDOObject(company2).cdoRevision();
    assertEquals(4, revision2.getVersion());
    assertEquals(transaction.getBranch(), revision2.getBranch());
    assertEquals(transaction.getLastCommitTime(), revision2.getTimeStamp());
  }
  public void testRemoveManyContained() throws Exception {
    final List<Category> categories = new ArrayList<Category>();
    categories.add(getModel1Factory().createCategory());
    categories.add(getModel1Factory().createCategory());
    categories.add(getModel1Factory().createCategory());
    categories.add(getModel1Factory().createCategory());

    Company company = getModel1Factory().createCompany();
    company.getCategories().add(getModel1Factory().createCategory());
    company.getCategories().add(getModel1Factory().createCategory());
    company.getCategories().add(getModel1Factory().createCategory());
    company.getCategories().addAll(categories);
    company.getCategories().add(getModel1Factory().createCategory());
    company.getCategories().add(getModel1Factory().createCategory());
    company.getCategories().add(getModel1Factory().createCategory());

    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();
    CDOResource resource = transaction.createResource(getResourcePath("/test1"));
    resource.getContents().add(company);
    transaction.commit();

    CDOSession session2 = openSession();
    CDOView view = session2.openView();
    view.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.ALL);

    CDOResource resource2 = view.getResource(getResourcePath("/test1"));
    Company company2 = (Company) resource2.getContents().get(0);

    Object[] strongRefs = company2.getCategories().toArray(); // Keep those in memory
    msg(strongRefs);

    final TestAdapter adapter = new TestAdapter();
    company2.eAdapters().add(adapter);

    company.getCategories().removeAll(categories);
    transaction.commit();

    // TODO Consider to uncomment the following if bug 317144 is addressed in EMF
    // final Object[] oldValue = { null };

    new PollingTimeOuter() {
      @Override
      protected boolean successful() {
        return adapter.getNotifications().length == categories.size();

        // TODO Consider to uncomment the following if bug 317144 is addressed in EMF
        // for (Notification notification : adapter.getNotifications())
        // {
        // if (notification.getEventType() == Notification.REMOVE_MANY
        // && notification.getFeature() == getModel1Package().getCompany_Categories())
        // {
        // oldValue[0] = notification.getOldValue();
        // return true;
        // }
        // }
        //
        // return false;
      }
    }.assertNoTimeOut();

    // TODO Consider to uncomment the following if bug 317144 is addressed in EMF
    // assertInstanceOf(Collection.class, oldValue[0]);
    // assertEquals(categories.size(), ((Collection<?>)oldValue[0]).size());
  }
  public void testNotificationChain() throws Exception {
    msg("Opening session");
    final CDOSession session = openSession();

    // ************************************************************* //

    msg("Creating category1");
    final Category category1A = getModel1Factory().createCategory();
    category1A.setName("category1");

    msg("Creating company");
    final Company companyA = getModel1Factory().createCompany();

    msg("Adding categories");
    companyA.getCategories().add(category1A);

    msg("Opening transaction");
    final CDOTransaction transaction = session.openTransaction();

    transaction.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.ALL);

    msg("Creating resource");
    final CDOResource resourceA = transaction.createResource(getResourcePath("/test1"));

    msg("Adding company");
    resourceA.getContents().add(companyA);

    msg("Committing");
    transaction.commit();

    final TestAdapter adapter = new TestAdapter();

    companyA.eAdapters().add(adapter);

    // ************************************************************* //

    msg("Opening view");
    final CDOSession session2 = openSession();
    final CDOTransaction transaction2 = session2.openTransaction();

    final Company company1B =
        (Company)
            CDOUtil.getEObject(
                transaction2.getObject(CDOUtil.getCDOObject(companyA).cdoID(), true));

    msg("Changing name");
    company1B.setName("TEST1");
    company1B.setCity("CITY1");

    final Category category2B = getModel1Factory().createCategory();
    company1B.getCategories().add(category2B);

    assertEquals(0, adapter.getNotifications().length);

    msg("Committing");
    transaction2.commit();

    msg("Checking after commit");
    new PollingTimeOuter() {
      @Override
      protected boolean successful() {
        return adapter.getNotifications().length == 3;
      }
    }.assertNoTimeOut();

    int count = 0;
    for (Notification notification : adapter.getNotifications()) {
      CDODeltaNotification cdoNotification = (CDODeltaNotification) notification;
      if (adapter.getNotifications().length - 1 == count) {
        assertEquals(false, cdoNotification.hasNext());
      } else {
        assertEquals(true, cdoNotification.hasNext());
      }

      if (notification.getFeature() == getModel1Package().getCategory_Name()) {
        assertEquals(Notification.SET, notification.getEventType());
        assertEquals("TEST1", notification.getNewStringValue());
      } else if (notification.getFeature() == getModel1Package().getAddress_City()) {
        assertEquals(Notification.SET, notification.getEventType());
        assertEquals("CITY1", notification.getNewStringValue());
      } else if (notification.getFeature() == getModel1Package().getCompany_Categories()) {
        assertEquals(Notification.ADD, notification.getEventType());
        assertEquals(1, notification.getPosition());
        assertEquals(
            transaction.getObject(CDOUtil.getCDOObject(category2B).cdoID(), true),
            notification.getNewValue());
      } else {
        assertEquals(false, false);
      }

      count++;
    }
  }
  @Requires(IRepositoryConfig.CAPABILITY_OFFLINE)
  @Skips("DB.ranges")
  // Too slow in DB.ranges (11 minutes), see bug 357441
  public void testOfflineCloneSynchronization() throws Exception {
    disableConsole();

    // create an offline clone.
    InternalRepository clone = getRepository();
    waitForOnline(clone);

    // create master session & transaction.
    InternalRepository master = getRepository("master");
    CDOSession masterSession = openSession(master.getName());
    CDOTransaction masterTransaction = masterSession.openTransaction();

    // create client session & transaction.
    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();

    // doing this that client notifications are built upon RevisionDeltas instead of RevisionKeys.
    session.options().setPassiveUpdateMode(PassiveUpdateMode.CHANGES);

    // create additional client sessions.
    CDOView[] cloneViews = new CDOView[NUM_CLIENT_VIEWS + 1];
    for (int i = 0; i < NUM_CLIENT_VIEWS; i++) {
      CDOView view = session.openView();
      cloneViews[i] = view;
    }

    cloneViews[NUM_CLIENT_VIEWS] = transaction;

    // create resource and base model.
    CDOResource resource = masterTransaction.createResource(getResourcePath("/my/resource"));
    Company company = getModel1Factory().createCompany();
    Category catA = getModel1Factory().createCategory();
    catA.setName("CatA");
    company.getCategories().add(catA);
    Category catB = getModel1Factory().createCategory();
    catB.setName("CatB");
    company.getCategories().add(catB);
    resource.getContents().add(company);

    for (int i = 0; i < NUM_PRODUCTS; i++) {
      Product1 product = getModel1Factory().createProduct1();
      product.setName("Product" + i);
      catA.getProducts().add(product);
    }

    masterTransaction.commit();
    transaction.waitForUpdate(masterTransaction.getLastCommitTime(), 1000);

    // touch the objects on the views to actually receive updates.
    for (CDOView view : cloneViews) {
      Category vCatA = (Category) view.getObject(CDOUtil.getCDOObject(catA).cdoID());
      Category vCatB = (Category) view.getObject(CDOUtil.getCDOObject(catB).cdoID());
      vCatB.getName();
      for (Product1 vProduct : vCatA.getProducts()) {
        vProduct.getName();
      }
    }

    // do a lot of changes on master session.
    long start = System.currentTimeMillis();
    for (int i = 0; i < NUM_PRODUCTS; i++) {
      Product1 p = catA.getProducts().remove(0);
      catB.getProducts().add(p);
      catB.getProducts().move(0, p);

      masterTransaction.commit();
    }

    Thread.sleep(100);
    catA.setName(catA.getName() + " empty");
    masterTransaction.commit();

    System.out.println(
        MessageFormat.format(
            "## Committing changes on {0} products took: {1}",
            NUM_PRODUCTS, System.currentTimeMillis() - start));

    // session.waitForUpdate(masterTransaction.getLastCommitTime(), 5000);
    for (CDOView view : cloneViews) {
      view.waitForUpdate(masterTransaction.getLastCommitTime(), 5000);
    }

    // adding this sleep as the waitForUpdate does not seem to work as expected in case of an error.
    sleep(5000);
    System.out.println("## Started checking....");

    // check if all changes are made.
    Category cloneCatA = (Category) transaction.getObject(CDOUtil.getCDOObject(catA).cdoID());
    Category cloneCatB = (Category) transaction.getObject(CDOUtil.getCDOObject(catB).cdoID());
    System.out.println(
        "CatA IdVersion: " + CDOUtil.getCDOObject(cloneCatA).cdoRevision().toString());
    System.out.println(
        "CatB IdVersion: " + CDOUtil.getCDOObject(cloneCatB).cdoRevision().toString());
    assertEquals(NUM_PRODUCTS, cloneCatB.getProducts().size());
    assertEquals(0, cloneCatA.getProducts().size());
    assertEquals(catA.getName(), cloneCatA.getName());
  }