@Override
  public void onLiveInstanceChange(
      List<LiveInstance> liveInstances, NotificationContext changeContext) {
    if (connectionPool == null) {
      LOGGER.info("init hasn't been called yet on the live instances listener...");
      return;
    }

    LOGGER.info("Connection pool found, moving on...");

    for (LiveInstance instance : liveInstances) {

      String instanceId = instance.getInstanceName();
      String sessionId = instance.getSessionId();

      if (instanceId.startsWith("Broker_")) {
        LOGGER.info("skipping broker instances {}", instanceId);
        continue;
      }

      String namePortStr = instanceId.split("Server_")[1];
      String hostName = namePortStr.split("_")[0];
      int port;
      try {
        port = Integer.parseInt(namePortStr.split("_")[1]);
      } catch (Exception e) {
        LOGGER.warn("Port for server instance " + instanceId + " does not appear to be numeric", e);
        port = CommonConstants.Helix.DEFAULT_SERVER_NETTY_PORT;
      }
      ServerInstance ins = new ServerInstance(hostName, port);

      if (liveInstanceToSessionIdMap.containsKey(instanceId)) {
        // sessionId has changed
        LOGGER.info(
            "found instance Id : {} with new session Id : {} old session Id {}",
            instanceId,
            sessionId,
            liveInstanceToSessionIdMap.get(instanceId));
        if (!sessionId.equals(liveInstanceToSessionIdMap.get(instanceId))) {
          try {
            connectionPool.validatePool(ins, DO_NOT_RECREATE);
            liveInstanceToSessionIdMap.put(instanceId, sessionId);
          } catch (Exception e) {
            LOGGER.error(
                "Error trying to validate & destroy dead connections for {}", instanceId, e);
          }
        }
      } else {
        LOGGER.info("found instance Id : {} with new session Id : {}", instanceId, sessionId);
        // we don't have this instanceId
        // lets first check if the connection is valid or not
        try {
          connectionPool.validatePool(ins, DO_NOT_RECREATE);
          liveInstanceToSessionIdMap.put(instanceId, sessionId);
        } catch (Exception e) {
          LOGGER.error("Error trying to destroy dead connections for {}", instanceId, e);
        }
      }
    }
  }
  @Override
  public boolean isLeader() {
    if (_instanceType != InstanceType.CONTROLLER
        && _instanceType != InstanceType.CONTROLLER_PARTICIPANT) {
      return false;
    }

    if (!isConnected()) {
      return false;
    }

    try {
      LiveInstance leader = _dataAccessor.getProperty(_keyBuilder.controllerLeader());
      if (leader != null) {
        String leaderName = leader.getInstanceName();
        String sessionId = leader.getSessionId();
        if (leaderName != null
            && leaderName.equals(_instanceName)
            && sessionId != null
            && sessionId.equals(_sessionId)) {
          return true;
        }
      }
    } catch (Exception e) {
      // log
    }
    return false;
  }
  @Test
  public void testLiveInstanceInfoProvider() throws Exception {
    System.out.println(
        "START "
            + className
            + ".testLiveInstanceInfoProvider() at "
            + new Date(System.currentTimeMillis()));
    final String clusterName = CLUSTER_PREFIX + "_" + className + "_liveInstanceInfoProvider";
    class provider implements LiveInstanceInfoProvider {
      boolean _flag = false;

      public provider(boolean genSessionId) {
        _flag = genSessionId;
      }

      @Override
      public ZNRecord getAdditionalLiveInstanceInfo() {
        ZNRecord record = new ZNRecord("info");
        record.setSimpleField("simple", "value");
        List<String> listFieldVal = new ArrayList<String>();
        listFieldVal.add("val1");
        listFieldVal.add("val2");
        listFieldVal.add("val3");
        record.setListField("list", listFieldVal);
        Map<String, String> mapFieldVal = new HashMap<String, String>();
        mapFieldVal.put("k1", "val1");
        mapFieldVal.put("k2", "val2");
        mapFieldVal.put("k3", "val3");
        record.setMapField("map", mapFieldVal);
        if (_flag) {
          record.setSimpleField("SESSION_ID", "value");
          record.setSimpleField("LIVE_INSTANCE", "value");
          record.setSimpleField("Others", "value");
        }
        return record;
      }
    }

    TestHelper.setupEmptyCluster(_gZkClient, clusterName);
    int[] ids = {0, 1, 2, 3, 4, 5};
    setupInstances(clusterName, ids);

    // ///////////////////
    ZKHelixManager manager =
        new ZKHelixManager(clusterName, "localhost_0", InstanceType.PARTICIPANT, ZK_ADDR);
    manager.connect();
    HelixDataAccessor accessor = manager.getHelixDataAccessor();

    LiveInstance liveInstance =
        accessor.getProperty(accessor.keyBuilder().liveInstance("localhost_0"));
    Assert.assertTrue(liveInstance.getRecord().getListFields().size() == 0);
    Assert.assertTrue(liveInstance.getRecord().getMapFields().size() == 0);
    Assert.assertTrue(liveInstance.getRecord().getSimpleFields().size() == 3);

    manager = new ZKHelixManager(clusterName, "localhost_1", InstanceType.PARTICIPANT, ZK_ADDR);
    manager.setLiveInstanceInfoProvider(new provider(false));

    manager.connect();
    accessor = manager.getHelixDataAccessor();

    liveInstance = accessor.getProperty(accessor.keyBuilder().liveInstance("localhost_1"));
    Assert.assertTrue(liveInstance.getRecord().getListFields().size() == 1);
    Assert.assertTrue(liveInstance.getRecord().getMapFields().size() == 1);
    Assert.assertTrue(liveInstance.getRecord().getSimpleFields().size() == 4);

    manager = new ZKHelixManager(clusterName, "localhost_2", InstanceType.PARTICIPANT, ZK_ADDR);
    manager.setLiveInstanceInfoProvider(new provider(true));

    manager.connect();
    accessor = manager.getHelixDataAccessor();

    liveInstance = accessor.getProperty(accessor.keyBuilder().liveInstance("localhost_2"));
    Assert.assertTrue(liveInstance.getRecord().getListFields().size() == 1);
    Assert.assertTrue(liveInstance.getRecord().getMapFields().size() == 1);
    Assert.assertTrue(liveInstance.getRecord().getSimpleFields().size() == 5);
    Assert.assertFalse(liveInstance.getSessionId().equals("value"));
    Assert.assertFalse(liveInstance.getLiveInstance().equals("value"));

    // //////////////////////////////////

    ZkHelixTestManager manager2 =
        new ZkHelixTestManager(clusterName, "localhost_3", InstanceType.PARTICIPANT, ZK_ADDR);
    manager2.setLiveInstanceInfoProvider(new provider(true));

    manager2.connect();
    accessor = manager2.getHelixDataAccessor();

    liveInstance = accessor.getProperty(accessor.keyBuilder().liveInstance("localhost_3"));
    Assert.assertTrue(liveInstance.getRecord().getListFields().size() == 1);
    Assert.assertTrue(liveInstance.getRecord().getMapFields().size() == 1);
    Assert.assertTrue(liveInstance.getRecord().getSimpleFields().size() == 5);
    Assert.assertFalse(liveInstance.getSessionId().equals("value"));
    Assert.assertFalse(liveInstance.getLiveInstance().equals("value"));
    String sessionId = liveInstance.getSessionId();

    ZkTestHelper.expireSession(manager2.getZkClient());
    Thread.sleep(1000);

    liveInstance = accessor.getProperty(accessor.keyBuilder().liveInstance("localhost_3"));
    Assert.assertTrue(liveInstance.getRecord().getListFields().size() == 1);
    Assert.assertTrue(liveInstance.getRecord().getMapFields().size() == 1);
    Assert.assertTrue(liveInstance.getRecord().getSimpleFields().size() == 5);
    Assert.assertFalse(liveInstance.getSessionId().equals("value"));
    Assert.assertFalse(liveInstance.getLiveInstance().equals("value"));
    Assert.assertFalse(sessionId.equals(liveInstance.getSessionId()));

    System.out.println(
        "END "
            + className
            + ".testLiveInstanceInfoProvider() at "
            + new Date(System.currentTimeMillis()));
  }