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]));
  }
  /** 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++;
    }
  }
  public void testSeparateSession_CUSTOM() throws Exception {
    CDOIDFilterChangeSubscriptionPolicy customPolicy = new CDOIDFilterChangeSubscriptionPolicy();

    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(customPolicy);

    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();

    customPolicy.getCdoIDs().add(CDOUtil.getCDOObject(category1A).cdoID());

    category1A.eAdapters().add(adapter);
    companyA.eAdapters().add(adapter);

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

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

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

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

    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();

    // Switching policy to the other
    transaction.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.ALL);

    adapter.clearNotifications();

    msg("Changing name");
    category1B.setName("CHANGED NAME_VERSION 2");
    company1B.setName("TEST2");

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

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

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