void sendLeave(VirtualSocketAddress address) {
    if (address.equals(serverSocket.getLocalSocketAddress())) {
      // do not connect to self
      return;
    }

    try {
      long start = System.currentTimeMillis();
      Connection connection =
          new Connection(address, LEAVE_CONNECTION_TIMEOUT, true, socketFactory);

      connection.out().writeByte(Protocol.MAGIC_BYTE);
      connection.out().writeByte(Protocol.OPCODE_LEAVE);
      registry.getIbisIdentifier().writeTo(connection.out());

      connection.getAndCheckReply();

      connection.close();
      if (statistics != null) {
        statistics.add(
            Protocol.OPCODE_LEAVE,
            System.currentTimeMillis() - start,
            connection.read(),
            connection.written(),
            false);
      }
    } catch (IOException e) {
      logger.debug(serverSocket.getLocalSocketAddress() + " could not send leave to " + address);
    }
  }
  CommunicationHandler(
      TypedProperties properties,
      Registry registry,
      MemberSet members,
      ElectionSet elections,
      Statistics statistics)
      throws IbisConfigurationException, IOException {
    this.registry = registry;
    this.pool = members;
    this.elections = elections;
    this.statistics = statistics;

    nrOfLeavesSend = properties.getIntProperty(RegistryProperties.LEAVES_SEND);

    gossipSize = properties.getIntProperty(RegistryProperties.GOSSIP_COUNT);

    String clientID = properties.getProperty(Ibis.ID_PROPERTY);
    Client client = Client.getOrCreateClient(clientID, properties, 0);
    socketFactory = client.getFactory();

    serverSocket = socketFactory.createServerSocket(0, CONNECTION_BACKLOG, null);

    VirtualSocketAddress serverAddress = client.getServiceAddress(Protocol.VIRTUAL_PORT);

    String[] bootstrapStringList = properties.getStringList(RegistryProperties.BOOTSTRAP_LIST);
    VirtualSocketAddress[] bootstrapList = new VirtualSocketAddress[bootstrapStringList.length];

    for (int i = 0; i < bootstrapList.length; i++) {
      bootstrapList[i] = new VirtualSocketAddress(bootstrapStringList[i]);
    }

    logger.debug("local address = " + serverSocket.getLocalSocketAddress());
    logger.debug("server address = " + serverAddress);

    arrg =
        new ARRG(
            serverSocket.getLocalSocketAddress(),
            false,
            bootstrapList,
            serverAddress,
            registry.getPoolName(),
            socketFactory,
            statistics);
  }
  public void gossip() {
    VirtualSocketAddress address = arrg.getRandomMember();

    if (address == null || address.equals(serverSocket.getLocalSocketAddress())) {
      logger.debug("noone to gossip with, or (not) gossiping with self");
      return;
    }

    try {
      long start = System.currentTimeMillis();
      Connection connection = new Connection(address, CONNECTION_TIMEOUT, true, socketFactory);

      connection.out().writeByte(Protocol.MAGIC_BYTE);
      connection.out().writeByte(Protocol.OPCODE_GOSSIP);
      registry.getIbisIdentifier().writeTo(connection.out());

      pool.writeGossipData(connection.out(), gossipSize);
      elections.writeGossipData(connection.out());

      connection.getAndCheckReply();

      pool.readGossipData(connection.in());
      elections.readGossipData(connection.in());

      connection.close();
      if (statistics != null) {
        statistics.add(
            Protocol.OPCODE_GOSSIP,
            System.currentTimeMillis() - start,
            connection.read(),
            connection.written(),
            false);
      }
    } catch (IOException e) {
      logger.debug("could not gossip with " + address, e);
    }
  }
 VirtualSocketAddress getAddress() {
   return serverSocket.getLocalSocketAddress();
 }