private void assertLockOwner(CDOView view, CDOLockOwner lockOwner) {
   CDOLockOwner lo = CDOLockUtil.createLockOwner(view);
   assertEquals(lo, lockOwner);
 }
  private void withExplicitRelease(
      CDOSession session1, CDOView controlView, boolean mustReceiveNotifications)
      throws CommitException {
    TestListener2 controlViewListener = new TestListener2(CDOViewLocksChangedEvent.class);
    controlView.addListener(controlViewListener);

    CDOTransaction tx1 = session1.openTransaction();
    CDOResource res1 = tx1.getOrCreateResource(getResourcePath("r1"));
    TestListener2 transactionListener = new TestListener2(CDOViewLocksChangedEvent.class);
    tx1.addListener(transactionListener);
    res1.getContents().clear();
    Company company = getModel1Factory().createCompany();
    res1.getContents().add(company);
    tx1.commit();

    CDOObject cdoCompany = CDOUtil.getCDOObject(company);

    CDOObject cdoCompanyInControlView = null;
    if (mustReceiveNotifications) {
      cdoCompanyInControlView = controlView.getObject(cdoCompany.cdoID());
    }

    /* Test write lock */

    cdoCompany.cdoWriteLock().lock();
    if (mustReceiveNotifications) {
      controlViewListener.waitFor(1);
      assertEquals(1, controlViewListener.getEvents().size());

      CDOViewLocksChangedEvent event =
          (CDOViewLocksChangedEvent) controlViewListener.getEvents().get(0);
      assertLockOwner(tx1, event.getLockOwner());

      CDOLockState[] lockStates = event.getLockStates();
      assertEquals(1, lockStates.length);
      assertLockedObject(cdoCompany, lockStates[0].getLockedObject());
      assertLockOwner(tx1, lockStates[0].getWriteLockOwner());
      assertSame(cdoCompanyInControlView.cdoLockState(), lockStates[0]);
    }

    cdoCompany.cdoWriteLock().unlock();
    if (mustReceiveNotifications) {
      controlViewListener.waitFor(2);

      assertEquals(2, controlViewListener.getEvents().size());

      CDOViewLocksChangedEvent event =
          (CDOViewLocksChangedEvent) controlViewListener.getEvents().get(1);
      assertLockOwner(tx1, event.getLockOwner());

      CDOLockState[] lockStates = event.getLockStates();
      assertEquals(1, lockStates.length);
      assertLockedObject(cdoCompany, lockStates[0].getLockedObject());
      assertNull(lockStates[0].getWriteLockOwner());
      assertSame(cdoCompanyInControlView.cdoLockState(), lockStates[0]);
    }

    /* Test read lock */

    cdoCompany.cdoReadLock().lock();
    if (mustReceiveNotifications) {
      controlViewListener.waitFor(3);
      assertEquals(3, controlViewListener.getEvents().size());

      CDOViewLocksChangedEvent event =
          (CDOViewLocksChangedEvent) controlViewListener.getEvents().get(2);
      assertLockOwner(tx1, event.getLockOwner());

      CDOLockState[] lockStates = event.getLockStates();
      assertEquals(1, lockStates.length);
      assertLockedObject(cdoCompany, lockStates[0].getLockedObject());
      assertEquals(1, lockStates[0].getReadLockOwners().size());
      CDOLockOwner tx1Lo = CDOLockUtil.createLockOwner(tx1);
      assertEquals(true, lockStates[0].getReadLockOwners().contains(tx1Lo));
      assertSame(cdoCompanyInControlView.cdoLockState(), lockStates[0]);
    }

    cdoCompany.cdoReadLock().unlock();
    if (mustReceiveNotifications) {
      controlViewListener.waitFor(4);

      assertEquals(4, controlViewListener.getEvents().size());

      CDOViewLocksChangedEvent event =
          (CDOViewLocksChangedEvent) controlViewListener.getEvents().get(3);
      assertLockOwner(tx1, event.getLockOwner());

      CDOLockState[] lockStates = event.getLockStates();
      assertEquals(1, lockStates.length);
      assertEquals(0, lockStates[0].getReadLockOwners().size());
      assertSame(cdoCompanyInControlView.cdoLockState(), lockStates[0]);
    }

    /* Test write option */

    cdoCompany.cdoWriteOption().lock();
    if (mustReceiveNotifications) {
      controlViewListener.waitFor(5);
      assertEquals(5, controlViewListener.getEvents().size());

      CDOViewLocksChangedEvent event =
          (CDOViewLocksChangedEvent) controlViewListener.getEvents().get(4);
      assertLockOwner(tx1, event.getLockOwner());

      CDOLockState[] lockStates = event.getLockStates();
      assertEquals(1, lockStates.length);
      assertLockedObject(cdoCompany, lockStates[0].getLockedObject());
      assertLockOwner(tx1, lockStates[0].getWriteOptionOwner());
      assertSame(cdoCompanyInControlView.cdoLockState(), lockStates[0]);
    }

    cdoCompany.cdoWriteOption().unlock();
    if (mustReceiveNotifications) {
      controlViewListener.waitFor(6);

      assertEquals(6, controlViewListener.getEvents().size());

      CDOViewLocksChangedEvent event =
          (CDOViewLocksChangedEvent) controlViewListener.getEvents().get(5);
      assertLockOwner(tx1, event.getLockOwner());

      CDOLockState[] lockStates = event.getLockStates();
      assertEquals(1, lockStates.length);
      assertLockedObject(cdoCompany, lockStates[0].getLockedObject());
      assertNull(lockStates[0].getWriteOptionOwner());
      assertSame(cdoCompanyInControlView.cdoLockState(), lockStates[0]);
    }

    assertEquals(0, transactionListener.getEvents().size());

    if (!mustReceiveNotifications) {
      assertEquals(0, controlViewListener.getEvents().size());
    }
  }