private Set<CDORemoteSession> sendMessage(
      CDORemoteSessionMessage message, Iterator<CDORemoteSession> recipients) {
    List<CDORemoteSession> subscribed = new ArrayList<CDORemoteSession>();
    while (recipients.hasNext()) {
      CDORemoteSession recipient = recipients.next();
      if (recipient.isSubscribed()) {
        subscribed.add(recipient);
      }
    }

    if (subscribed.isEmpty()) {
      return Collections.emptySet();
    }

    Set<Integer> sessionIDs =
        localSession.getSessionProtocol().sendRemoteMessage(message, subscribed);
    Set<CDORemoteSession> result = new HashSet<CDORemoteSession>();
    for (CDORemoteSession recipient : subscribed) {
      if (sessionIDs.contains(recipient.getSessionID())) {
        result.add(recipient);
      }
    }

    return result;
  }
  /** Needs to be synchronized externally. */
  private IEvent[] subscribe() {
    List<CDORemoteSession> result = localSession.getSessionProtocol().getRemoteSessions(this, true);
    ContainerEvent<CDORemoteSession> event = new ContainerEvent<CDORemoteSession>(this);
    for (CDORemoteSession remoteSession : result) {
      remoteSessions.put(remoteSession.getSessionID(), remoteSession);
      event.addDelta(remoteSession, IContainerDelta.Kind.ADDED);
    }

    subscribed = true;
    IEvent[] events = {new LocalSubscriptionChangedEventImpl(true), event.isEmpty() ? null : event};
    return events;
  }