/**
   * Un-marshal an object instance from the data input stream
   *
   * @param o the object to un-marshal
   * @param dataIn the data input stream to build the object from
   * @throws IOException
   */
  public void tightUnmarshal(
      OpenWireFormat wireFormat, Object o, DataInput dataIn, BooleanStream bs) throws IOException {
    super.tightUnmarshal(wireFormat, o, dataIn, bs);

    ConnectionControl info = (ConnectionControl) o;
    info.setClose(bs.readBoolean());
    info.setExit(bs.readBoolean());
    info.setFaultTolerant(bs.readBoolean());
    info.setResume(bs.readBoolean());
    info.setSuspend(bs.readBoolean());
  }
  /**
   * Un-marshal an object instance from the data input stream
   *
   * @param o the object to un-marshal
   * @param dataIn the data input stream to build the object from
   * @throws IOException
   */
  public void looseUnmarshal(OpenWireFormat wireFormat, Object o, DataInput dataIn)
      throws IOException {
    super.looseUnmarshal(wireFormat, o, dataIn);

    ConnectionControl info = (ConnectionControl) o;
    info.setClose(dataIn.readBoolean());
    info.setExit(dataIn.readBoolean());
    info.setFaultTolerant(dataIn.readBoolean());
    info.setResume(dataIn.readBoolean());
    info.setSuspend(dataIn.readBoolean());
  }
  @Override
  protected void populateObject(Object object) throws Exception {
    super.populateObject(object);
    ConnectionControl info = (ConnectionControl) object;

    info.setClose(true);
    info.setExit(false);
    info.setFaultTolerant(true);
    info.setResume(false);
    info.setSuspend(true);
    info.setConnectedBrokers("ConnectedBrokers:1");
    info.setReconnectTo("ReconnectTo:2");
    info.setRebalanceConnection(false);
  }
  @Override
  public Response processAddConnection(ConnectionInfo info) throws Exception {
    WireFormatInfo wireFormatInfo = wireFormat.getPreferedWireFormatInfo();
    // Older clients should have been defaulting this field to true.. but
    // they were not.
    if (wireFormatInfo != null && wireFormatInfo.getVersion() <= 2) {
      info.setClientMaster(true);
    }

    state = new ConnectionState(info);

    context = new AMQConnectionContext();

    state.reset(info);

    this.faultTolerantConnection = info.isFaultTolerant();
    // Setup the context.
    String clientId = info.getClientId();
    context.setBroker(protocolManager);
    context.setClientId(clientId);
    context.setClientMaster(info.isClientMaster());
    context.setConnection(this);
    context.setConnectionId(info.getConnectionId());
    // for now we pass the manager as the connector and see what happens
    // it should be related to activemq's Acceptor
    context.setConnector(this.acceptorUsed);
    context.setMessageAuthorizationPolicy(getMessageAuthorizationPolicy());
    context.setNetworkConnection(networkConnection);
    context.setFaultTolerant(faultTolerantConnection);
    context.setTransactions(new ConcurrentHashMap<TransactionId, AMQTransaction>());
    context.setUserName(info.getUserName());
    context.setWireFormatInfo(wireFormatInfo);
    context.setReconnect(info.isFailoverReconnect());
    this.manageable = info.isManageable();
    context.setConnectionState(state);
    if (info.getClientIp() == null) {
      info.setClientIp(getRemoteAddress());
    }

    try {
      protocolManager.addConnection(context, info);
    } catch (Exception e) {
      if (e instanceof SecurityException) {
        // close this down - in case the peer of this transport doesn't play
        // nice
        delayedStop(2000, "Failed with SecurityException: " + e.getLocalizedMessage(), e);
      }
      Response resp = new ExceptionResponse(e);
      return resp;
    }
    if (info.isManageable()) {
      // send ConnectionCommand
      ConnectionControl command = this.acceptorUsed.getConnectionControl();
      command.setFaultTolerant(protocolManager.isFaultTolerantConfiguration());
      if (info.isFailoverReconnect()) {
        command.setRebalanceConnection(false);
      }
      dispatchAsync(command);
    }
    return null;
  }