/* (non-Javadoc)
   * @see org.eclipse.tm.tcf.protocol.Protocol.ChannelOpenListener#onChannelOpen(org.eclipse.tm.tcf.protocol.IChannel)
   */
  @Override
  public void onChannelOpen(IChannel channel) {
    Assert.isNotNull(channel);
    Assert.isTrue(Protocol.isDispatchThread());

    // Trace the channel opening
    LogUtils.logMessageForChannel(
        channel,
        Messages.InternalChannelOpenListener_onChannelOpen_message,
        "debug/channels",
        this); //$NON-NLS-1$

    // As the channel has just opened, there should be no channel listener, but better be safe and
    // check.
    IChannel.IChannelListener channelListener = channelListeners.remove(channel);
    if (channelListener != null) channel.removeChannelListener(channelListener);
    // Create a new channel listener instance
    channelListener = new InternalChannelListener(channel);
    // Add the channel listener to the global map
    setChannelListener(channel, channelListener);
    // Attach channel listener to the channel
    channel.addChannelListener(channelListener);

    // Fire the property change event for the channel
    Tcf.fireChannelStateChangeListeners(channel, IChannel.STATE_OPEN);
  }
  /* (non-Javadoc)
   * @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent)
   */
  @Override
  public Object execute(final ExecutionEvent event) throws ExecutionException {
    // Get the active menu selection
    ISelection activeSelection = HandlerUtil.getActiveMenuSelection(event);
    // The selection is expected to be a structured exception
    if (activeSelection instanceof IStructuredSelection && !activeSelection.isEmpty()) {
      IStructuredSelection selection = (IStructuredSelection) activeSelection;
      // Loop the selection
      Iterator<?> iterator = selection.iterator();
      while (iterator.hasNext()) {
        Object element = iterator.next();
        // The selected element is expected to be a peer node
        if (element instanceof IPeerModel) {
          final IPeerModel node = (IPeerModel) element;
          IPeer peer = node.getPeer();
          // If the peer is available, we can open a channel to the remote peer
          if (peer != null) {
            // Get the channel
            Tcf.getChannelManager()
                .openChannel(
                    peer,
                    new IChannelManager.DoneOpenChannel() {
                      @Override
                      public void doneOpenChannel(final Throwable error, final IChannel channel) {
                        if (error == null) {
                          // Invoke the execute within the UI thread again.
                          Runnable runnable =
                              new Runnable() {
                                @Override
                                public void run() {
                                  execute(
                                      event,
                                      channel,
                                      node,
                                      new DoneExecute() {
                                        @Override
                                        public void doneExecute(IStatus status, Object result) {
                                          if (status.getSeverity() != IStatus.OK
                                              && status.getSeverity() != IStatus.CANCEL) {
                                            handleException(channel, new CoreException(status));
                                          } else {
                                            // Close the channel
                                            if (channel != null) {
                                              final IChannel finChannel = channel;
                                              if (Protocol.isDispatchThread()) {
                                                finChannel.close();
                                              } else {
                                                Protocol.invokeAndWait(
                                                    new Runnable() {
                                                      @Override
                                                      public void run() {
                                                        finChannel.close();
                                                      }
                                                    });
                                              }
                                            }
                                          }
                                        }
                                      });
                                }
                              };

                          DisplayUtil.safeAsyncExec(runnable);

                        } else {
                          handleException(channel, error);
                        }
                      }
                    });
          }
        }
      }
    }

    return null;
  }