[576802] Collaborations view does not properly disconnect from closed CDOSession

https://bugs.eclipse.org/bugs/show_bug.cgi?id=576802
diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/views/CDORemoteSessionsView.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/views/CDORemoteSessionsView.java
index 754ec51..6667230 100644
--- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/views/CDORemoteSessionsView.java
+++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/views/CDORemoteSessionsView.java
@@ -18,6 +18,7 @@
 import org.eclipse.emf.cdo.util.CDOUtil;
 
 import org.eclipse.net4j.util.event.IListener;
+import org.eclipse.net4j.util.lifecycle.ILifecycle;
 import org.eclipse.net4j.util.ui.UIUtil;
 import org.eclipse.net4j.util.ui.views.ContainerView;
 
@@ -109,6 +110,12 @@
         }
       }
     }
+
+    @Override
+    protected void onDeactivated(ILifecycle lifecycle)
+    {
+      setContainer(null);
+    }
   };
 
   public CDORemoteSessionsView()
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/remote/CDORemoteSessionManagerImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/remote/CDORemoteSessionManagerImpl.java
index ead4270..0c329d5 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/remote/CDORemoteSessionManagerImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/remote/CDORemoteSessionManagerImpl.java
@@ -41,6 +41,8 @@
  */
 public class CDORemoteSessionManagerImpl extends Container<CDORemoteSession> implements InternalCDORemoteSessionManager
 {
+  private static final CDORemoteSession[] NO_REMOTE_SESSIONS = {};
+
   private InternalCDOSession localSession;
 
   private boolean forceSubscription;
@@ -70,14 +72,19 @@
   {
     synchronized (this)
     {
-      if (subscribed)
+      if (localSession.isActive())
       {
-        Collection<CDORemoteSession> values = remoteSessions.values();
-        return values.toArray(new CDORemoteSession[values.size()]);
+        if (subscribed)
+        {
+          Collection<CDORemoteSession> values = remoteSessions.values();
+          return values.toArray(new CDORemoteSession[values.size()]);
+        }
+
+        List<CDORemoteSession> loadedRemoteSessions = localSession.getSessionProtocol().getRemoteSessions(this, false);
+        return loadedRemoteSessions.toArray(new CDORemoteSession[loadedRemoteSessions.size()]);
       }
 
-      List<CDORemoteSession> loadedRemoteSessions = localSession.getSessionProtocol().getRemoteSessions(this, false);
-      return loadedRemoteSessions.toArray(new CDORemoteSession[loadedRemoteSessions.size()]);
+      return NO_REMOTE_SESSIONS;
     }
   }
 
@@ -320,7 +327,11 @@
    */
   private IEvent[] unsubscribe()
   {
-    localSession.getSessionProtocol().unsubscribeRemoteSessions();
+    if (localSession.isActive())
+    {
+      localSession.getSessionProtocol().unsubscribeRemoteSessions();
+    }
+
     ContainerEvent<CDORemoteSession> event = new ContainerEvent<>(this);
     for (CDORemoteSession remoteSession : remoteSessions.values())
     {
diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/ContainerEventAdapter.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/ContainerEventAdapter.java
index 6b1341d..edb38e4 100644
--- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/ContainerEventAdapter.java
+++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/ContainerEventAdapter.java
@@ -14,6 +14,7 @@
 import org.eclipse.net4j.util.event.IEvent;
 import org.eclipse.net4j.util.event.IListener;
 import org.eclipse.net4j.util.lifecycle.ILifecycle;
+import org.eclipse.net4j.util.lifecycle.ILifecycleEvent;
 import org.eclipse.net4j.util.lifecycle.LifecycleEventAdapter;
 import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
 
@@ -57,6 +58,11 @@
       IContainerEvent<E> e = (IContainerEvent<E>)event;
       notifyContainerEvent(e);
     }
+    else if (event instanceof ILifecycleEvent)
+    {
+      ILifecycleEvent e = (ILifecycleEvent)event;
+      notifyLifecycleEvent(e);
+    }
     else
     {
       notifyOtherEvent(event);
@@ -97,6 +103,28 @@
     });
   }
 
+  /**
+   * @since 3.16
+   */
+  protected void notifyLifecycleEvent(ILifecycleEvent event)
+  {
+    switch (event.getKind())
+    {
+    case ABOUT_TO_ACTIVATE:
+      onAboutToActivate(event.getSource());
+      break;
+    case ACTIVATED:
+      onActivated(event.getSource());
+      break;
+    case ABOUT_TO_DEACTIVATE:
+      onAboutToDeactivate(event.getSource());
+      break;
+    case DEACTIVATED:
+      onDeactivated(event.getSource());
+      break;
+    }
+  }
+
   protected void notifyOtherEvent(IEvent event)
   {
   }
@@ -108,4 +136,32 @@
   protected void onRemoved(IContainer<E> container, E element)
   {
   }
+
+  /**
+   * @since 3.16
+   */
+  protected void onAboutToActivate(ILifecycle lifecycle)
+  {
+  }
+
+  /**
+   * @since 3.16
+   */
+  protected void onActivated(ILifecycle lifecycle)
+  {
+  }
+
+  /**
+   * @since 3.16
+   */
+  protected void onAboutToDeactivate(ILifecycle lifecycle)
+  {
+  }
+
+  /**
+   * @since 3.16
+   */
+  protected void onDeactivated(ILifecycle lifecycle)
+  {
+  }
 }