/**
  * Notifies this instance that the <tt>SctpConnection</tt> of/associated with a specific
  * <tt>Endpoint</tt> participating in this <tt>Conference</tt> has changed.
  *
  * @param endpoint the <tt>Endpoint</tt> participating in this <tt>Conference</tt> which has had
  *     its (associated) <tt>SctpConnection</tt> changed
  */
 private void endpointSctpConnectionChanged(
     Endpoint endpoint, SctpConnection oldValue, SctpConnection newValue) {
   // We want to fire initial events (e.g. dominant speaker) over the
   // SctpConnection as soon as it is ready.
   if (oldValue != null) {
     oldValue.removeChannelListener(webRtcDataStreamListener);
   }
   if (newValue != null) {
     newValue.addChannelListener(webRtcDataStreamListener);
     // The SctpConnection may itself be ready already. If this is the
     // case, then it has now become ready for this Conference.
     if (newValue.isReady()) sctpConnectionReady(newValue);
   }
 }
  /**
   * Notifies this instance that a specific <tt>SctpConnection</tt> has become ready i.e. connected
   * to a/the remote peer and operational.
   *
   * @param sctpConnection the <tt>SctpConnection</tt> which has become ready and is the cause of
   *     the method invocation
   */
  private void sctpConnectionReady(SctpConnection sctpConnection) {
    /*
     * We want to fire initial events over the SctpConnection as soon as it
     * is ready, we do not want to fire them multiple times i.e. every time
     * the SctpConnection becomes ready.
     */
    sctpConnection.removeChannelListener(webRtcDataStreamListener);

    if (!isExpired() && !sctpConnection.isExpired() && sctpConnection.isReady()) {
      Endpoint endpoint = sctpConnection.getEndpoint();

      if (endpoint != null) endpoint = getEndpoint(endpoint.getID());
      if (endpoint != null) {
        /*
         * It appears that this Conference, the SctpConnection and the
         * Endpoint are in states which allow them to fire the initial
         * events.
         */
        Endpoint dominantSpeaker = speechActivity.getDominantEndpoint();

        if (dominantSpeaker != null) {
          try {
            endpoint.sendMessageOnDataChannel(
                createDominantSpeakerEndpointChangeEvent(dominantSpeaker));
          } catch (IOException e) {
            logger.error("Failed to send message on data channel.", e);
          }
        }

        /*
         * Determining the instant at which an SctpConnection associated
         * with an Endpoint becomes ready (i.e. connected to the remote
         * peer and operational) is a multi-step ordeal. The Conference
         * class implements the procedure so do not make other classes
         * implement it as well.
         */
        endpoint.sctpConnectionReady(sctpConnection);
      }
    }
  }