logger.info("doLayout:" + " annealTime=" + annealTime + " newNodes=" + newNodes + " deadNodes=" + deadNodes + " excludedNodes=" + excludedNodes);
  protected void getLayout(final LoadBalancerListener lbl) {    logger.info("getLayout:");    // Ping "ACTIVE" nodes to verify they're still alive before invoking EN4J    String allNodes[] = model.listEntries(model.NODE);    Set excludedNodes = getExcludedNodes();    Set nodesToPing = new HashSet();    for (int i = 0; i < allNodes.length; i++) {      if (!deadNodes.contains(allNodes[i]) &&          !excludedNodes.contains(allNodes[i]))        nodesToPing.add(allNodes[i]);    }    final long pingTimeout = getLongAttribute("PING_TIMEOUT", PING_TIMEOUT);    PingListener pl = new PingListener() {      public void pingComplete(PingResult[] pingResults) {        // Update list of DEAD nodes        String deadNodesFromModel[] = model.listEntries(model.NODE, DEAD);        for (int i = 0; i < deadNodesFromModel.length; i++) {          deadNodes.add(deadNodesFromModel[i]);        }        for (int i = 0; i < pingResults.length; i++) {          if (pingResults[i].getStatus() == PingResult.FAIL) {            deadNodes.add(pingResults[i].getName());            logger.info("Found new DEAD node during LoadBalance node check: " +                        pingResults[i].getName());            model.setCurrentState(pingResults[i].getName(), DEAD);          }        }        List excludedNodes = new ArrayList(getExcludedNodes());        // Update list of NEW nodes        if (!newNodes.isEmpty()) {          for (Iterator it = newNodes.iterator(); it.hasNext(); ) {            String newNode = (String)it.next();            if (!isVacantNode(newNode) ||                excludedNodes.contains(newNode) ||                deadNodes.contains(newNode)) {              it.remove();            }          }        }        if (!loadBalanceInProcess) {          // Guard against overlapping doLayout requests          loadBalanceInProcess = true;          LoadBalancerListener newLbl = new LoadBalancerListener() {            public void layoutReady(Map layout) {              lbl.layoutReady(layout);              loadBalanceInProcess = false;            }          };          // Use ping timeout to calculate annealTime:          //  - convert ms to secs          //  - divide by 2 to provide some margin          //  - divide by 9 for EN multi-pass          long annealTime = pingTimeout > 0 ? pingTimeout / 1000 / 2 / 9 :              LoadBalancer.DEFAULT_ANNEAL_TIME;          logger.debug("Get restart destinations from LoadBalancer");          getLoadBalancer().doLayout( (int) annealTime,                                     true,                                     new ArrayList(newNodes),                                     new ArrayList(deadNodes),                                     excludedNodes,                                     newLbl);          newNodes.clear();        }      }    };    getPingHelper().ping((String[])nodesToPing.toArray(new String[0]), pingTimeout, pl);  }