[573654] Commits with autoReleaseLocks==false trigger empty lock notification events, nevertheless

https://bugs.eclipse.org/bugs/show_bug.cgi?id=573654
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/LockingManagerTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/LockingManagerTest.java
index e163a21..38920a8 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/LockingManagerTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/LockingManagerTest.java
@@ -19,6 +19,7 @@
 import org.eclipse.emf.cdo.eresource.CDOResource;
 import org.eclipse.emf.cdo.server.IView;
 import org.eclipse.emf.cdo.session.CDOSession;
+import org.eclipse.emf.cdo.session.CDOSessionLocksChangedEvent;
 import org.eclipse.emf.cdo.spi.server.InternalLockManager;
 import org.eclipse.emf.cdo.spi.server.InternalRepository;
 import org.eclipse.emf.cdo.tests.model1.Category;
@@ -36,6 +37,7 @@
 import org.eclipse.net4j.util.concurrent.RWOLockManager;
 import org.eclipse.net4j.util.concurrent.RWOLockManager.LockState;
 import org.eclipse.net4j.util.concurrent.TimeoutRuntimeException;
+import org.eclipse.net4j.util.event.EventUtil;
 import org.eclipse.net4j.util.io.IOUtil;
 
 import java.util.ArrayList;
@@ -45,6 +47,7 @@
 import java.util.Set;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import junit.framework.AssertionFailedError;
 
@@ -53,6 +56,37 @@
  */
 public class LockingManagerTest extends AbstractLockingTest
 {
+  public void testAutoReleaseLocks() throws Exception
+  {
+    CDOSession session = openSession();
+
+    AtomicInteger counter = new AtomicInteger();
+    try (AutoCloseable listener = EventUtil.addListener(session, CDOSessionLocksChangedEvent.class, event -> counter.incrementAndGet()))
+    {
+      CDOTransaction transaction = session.openTransaction();
+      transaction.options().setAutoReleaseLocksEnabled(false);
+
+      CDOResource resource = transaction.createResource(getResourcePath("/test1"));
+      assertWriteLock(false, resource);
+
+      transaction.commit();
+      assertWriteLock(false, resource);
+
+      resource.cdoWriteLock().lock();
+      assertWriteLock(true, resource);
+
+      resource.getContents().add(getModel1Factory().createSupplier());
+      transaction.commit();
+      assertWriteLock(true, resource);
+
+      resource.cdoWriteLock().unlock();
+      assertWriteLock(false, resource);
+
+      sleep(200);
+      assertEquals(2, counter.get());
+    }
+  }
+
   public void testUnlockAll() throws Exception
   {
     RWOLockManager<Integer, Integer> lockingManager = new RWOLockManager<>();
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java
index 834ff02..3d8d3fa 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java
@@ -2201,7 +2201,11 @@
           if (success)
           {
             fireEvent(new SessionInvalidationEvent(sender, commitInfo, invalidationData.getSecurityImpact(), oldPermissionsFinal));
-            fireEvent(new SessionLocksChangedEvent(sender, lockChangeInfo));
+
+            if (lockChangeInfo != null)
+            {
+              fireEvent(new SessionLocksChangedEvent(sender, lockChangeInfo));
+            }
 
             commitInfoManager.notifyCommitInfoHandlers(commitInfo);
           }
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java
index 9f5eb8d..4026bcd 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java
@@ -4972,9 +4972,15 @@
         }
       }
 
-      lockStates.putAll(newLockStates);
+      lockStates.putAll(newLockStates); // Side effect!!!
 
-      CDOLockState[] array = objectsToUnlock.toArray(new CDOLockState[objectsToUnlock.size()]);
+      int size = objectsToUnlock.size();
+      if (size == 0)
+      {
+        return null;
+      }
+
+      CDOLockState[] array = objectsToUnlock.toArray(new CDOLockState[size]);
       return makeLockChangeInfo(CDOLockChangeInfo.Operation.UNLOCK, null, result.getTimeStamp(), array);
     }
 
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java
index 4597fc0..dc069e2 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java
@@ -585,7 +585,7 @@
   @Override
   public void handleLockNotification(InternalCDOView sender, CDOLockChangeInfo lockChangeInfo)
   {
-    CDOLockChangeInfo event = null;
+    CDOLockChangeInfo lockChangeInfoToFire = null;
 
     try
     {
@@ -598,7 +598,7 @@
           if (lockChangeInfo.isInvalidateAll())
           {
             lockStates.clear();
-            event = lockChangeInfo;
+            lockChangeInfoToFire = lockChangeInfo;
             return;
           }
 
@@ -619,7 +619,7 @@
 
           if (options().isLockNotificationEnabled())
           {
-            event = lockChangeInfo;
+            lockChangeInfoToFire = lockChangeInfo;
           }
         }
         finally
@@ -630,9 +630,9 @@
     }
     finally
     {
-      if (event != null)
+      if (lockChangeInfoToFire != null)
       {
-        fireLocksChangedEvent(sender, event);
+        fireLocksChangedEvent(sender, lockChangeInfoToFire);
       }
     }
   }