/**
   * Handles incoming control commands on channel zero.
   *
   * @see ChannelN#processAsync
   */
  @SuppressWarnings("unused")
  public boolean processControlCommand(Command c) throws IOException {
    // Similar trick to ChannelN.processAsync used here, except
    // we're interested in whole-connection quiescing.

    // See the detailed comments in ChannelN.processAsync.

    Method method = c.getMethod();

    if (isOpen()) {
      if (method instanceof AMQP.Connection.Close) {
        handleConnectionClose(c);
        return true;
      } else if (method instanceof AMQP.Connection.Blocked) {
        AMQP.Connection.Blocked blocked = (AMQP.Connection.Blocked) method;
        try {
          for (BlockedListener l : this.blockedListeners) {
            l.handleBlocked(blocked.getReason());
          }
        } catch (Throwable ex) {
          getExceptionHandler().handleBlockedListenerException(this, ex);
        }
        return true;
      } else if (method instanceof AMQP.Connection.Unblocked) {
        try {
          for (BlockedListener l : this.blockedListeners) {
            l.handleUnblocked();
          }
        } catch (Throwable ex) {
          getExceptionHandler().handleBlockedListenerException(this, ex);
        }
        return true;
      } else {
        return false;
      }
    } else {
      if (method instanceof AMQP.Connection.Close) {
        // Already shutting down, so just send back a CloseOk.
        try {
          _channel0.quiescingTransmit(new AMQP.Connection.CloseOk.Builder().build());
        } catch (IOException ignored) {
        } // ignore
        return true;
      } else if (method instanceof AMQP.Connection.CloseOk) {
        // It's our final "RPC". Time to shut down.
        _running = false;
        // If Close was sent from within the MainLoop we
        // will not have a continuation to return to, so
        // we treat this as processed in that case.
        return !_channel0.isOutstandingRpc();
      } else { // Ignore all others.
        return true;
      }
    }
  }
  @SuppressWarnings("unused")
  public void handleConnectionClose(Command closeCommand) {
    ShutdownSignalException sse =
        shutdown(closeCommand.getMethod(), false, null, _inConnectionNegotiation);
    try {
      _channel0.quiescingTransmit(new AMQP.Connection.CloseOk.Builder().build());
    } catch (IOException ignored) {
    } // ignore
    _brokerInitiatedShutdown = true;
    SocketCloseWait scw = new SocketCloseWait(sse);

    // if shutdown executor is configured, use it. Otherwise
    // execut socket close monitor the old fashioned way.
    // see rabbitmq/rabbitmq-java-client#91
    if (shutdownExecutor != null) {
      shutdownExecutor.execute(scw);
    } else {
      final String name =
          "RabbitMQ connection shutdown monitor " + getHostAddress() + ":" + getPort();
      Thread waiter = Environment.newThread(threadFactory, scw, name);
      waiter.start();
    }
  }