if(log.isInfoEnabled()) log.info("VIEW_CHANGE received: " + members);
if(log.isDebugEnabled()) log.debug("VIEW_CHANGE received: " + members);
    public void down(Event evt) {        Address mbr, tmp_ping_dest;        View v;        switch(evt.getType()) {            case Event.UNSUSPECT:                bcast_task.removeSuspectedMember((Address) evt.getArg());                break;            case Event.CONNECT:                passDown(evt);                srv_sock=Util.createServerSocket(start_port); // grab a random unused port above 10000                srv_sock_addr=new IpAddress(srv_sock.getLocalPort());                startServerSocket();                if(pinger_thread == null)                    startPingerThread();                break;            case Event.VIEW_CHANGE:                synchronized(this) {                    v=(View) evt.getArg();                    members.removeAllElements();                    members.addAll(v.getMembers());                    bcast_task.adjustSuspectedMembers(members);                    pingable_mbrs.removeAllElements();                    pingable_mbrs.addAll(members);                    passDown(evt);                     if(log.isInfoEnabled()) log.info("VIEW_CHANGE received: " + members);                    // 1. Get the addr:pid cache from the coordinator (only if not already fetched)                    if(!got_cache_from_coord) {                        getCacheFromCoordinator();                        got_cache_from_coord=true;                    }                    // 2. Broadcast my own addr:sock to all members so they can update their cache                    if(!srv_sock_sent) {                        if(srv_sock_addr != null) {                            sendIHaveSockMessage(null, // send to all members                                                 local_addr,                                                 srv_sock_addr);                            srv_sock_sent=true;                        }                        else                            if(log.isWarnEnabled()) log.warn("(VIEW_CHANGE): srv_sock_addr == null");                    }                    // 3. Remove all entries in 'cache' which are not in the new membership                    if(members != null) {                        for(Enumeration e=cache.keys(); e.hasMoreElements();) {                            mbr=(Address) e.nextElement();                            if(!members.contains(mbr))                                cache.remove(mbr);                        }                    }                    if(members.size() > 1) {                        if(pinger_thread != null && pinger_thread.isAlive()) {                            tmp_ping_dest=determinePingDest();                            if(ping_dest != null && tmp_ping_dest != null && !ping_dest.equals(tmp_ping_dest)) {                                interruptPingerThread(); // allows the thread to use the new socket                            }                        }                        else                            startPingerThread(); // only starts if not yet running                    }                    else {                        ping_dest=null;                        stopPingerThread();                    }                }                break;            default:                passDown(evt);                break;        }    }