PingHeader hdr;
    public void down(Event evt) {        Message msg;        PingHeader hdr;        long time_to_wait, start_time;        switch(evt.getType()) {            case Event.FIND_INITIAL_MBRS:   // sent by GMS layer, pass up a GET_MBRS_OK event                initial_members.removeAllElements();                IpAddress h;                List hlist;                msg=new Message(null, null, null);                msg.putHeader(getName(), new PingHeader(PingHeader.GET_MBRS_REQ, null));                synchronized(members) {                    int numMembers=members.size();                    int numMemberInitialHosts = 0;                    Address coord=numMembers > 0 ? (Address)members.firstElement() : local_addr;                                                    for(Enumeration en=initial_hosts.elements(); en.hasMoreElements();) {                        hlist=(List)en.nextElement();                        boolean isMember = false;                        for(Enumeration hen=hlist.elements(); hen.hasMoreElements() && !isMember && numMemberInitialHosts < numMembers;) {                            h=(IpAddress)hen.nextElement();                            if (members_set.contains(h)) {                                //update the initial_members list for this already connected member                                initial_members.add(new PingRsp(h, coord));                                isMember = true;                                numMemberInitialHosts++;                                if(log.isTraceEnabled()) log.trace("[FIND_INITIAL_MBRS] " + h + " is already a member");                            }                        }                        for(Enumeration hen=hlist.elements(); hen.hasMoreElements() && !isMember;) {                            h=(IpAddress)hen.nextElement();                            msg.setDest(h);                            if(log.isTraceEnabled()) log.trace("[FIND_INITIAL_MBRS] sending PING request to " + msg.getDest());                            passDown(new Event(Event.MSG, msg.copy()));                        }                    }                }                // 2. Wait 'timeout' ms or until 'num_initial_members' have been retrieved                synchronized(initial_members) {                    start_time=System.currentTimeMillis();                    time_to_wait=timeout;                    while(initial_members.size() < num_initial_members && time_to_wait > 0) {                        try {                            initial_members.wait(time_to_wait);                        }                        catch(Exception e) {                        }                        time_to_wait-=System.currentTimeMillis() - start_time;                    }                }            if(log.isTraceEnabled()) log.trace("[FIND_INITIAL_MBRS] initial members are " + initial_members);                // 3. Send response                passUp(new Event(Event.FIND_INITIAL_MBRS_OK, initial_members));                break;            case Event.TMP_VIEW:            case Event.VIEW_CHANGE:                Vector tmp;                if((tmp=((View)evt.getArg()).getMembers()) != null) {                    synchronized(members) {                        members.clear();                        members.addAll(tmp);                        members_set.clear();                        members_set.addAll(tmp);                    }                }                passDown(evt);                break;            case Event.BECOME_SERVER: // called after client has joined and is fully working group member                passDown(evt);                is_server=true;                break;            case Event.CONNECT:                group_addr=(String) evt.getArg();                passDown(evt);                break;            case Event.DISCONNECT:                passDown(evt);                break;            default:                passDown(evt);          // Pass on to the layer below us                break;        }    }