@Override
  public void getChildren(final String path, final boolean watch, final AsyncCallback.ChildrenCallback cb, final Object ctx)
  {
    if (!SymlinkUtil.containsSymlink(path))
    {
      _zk.getChildren(path, watch, cb, ctx);
    }
    else
    {
      SymlinkChildrenCallback compositeCallback = new SymlinkChildrenCallback(path, _defaultWatcher, cb);
      getChildren0(path, watch ? compositeCallback : null, compositeCallback, ctx);
    }
  }
@Test
  public void testSymlinkWithChildrenWatch() throws InterruptedException
  {
    final CountDownLatch latch = new CountDownLatch(1);
    final CountDownLatch latch2 = new CountDownLatch(1);
    final AsyncCallback.ChildrenCallback childrenCallback = new AsyncCallback.ChildrenCallback()
    {
      @Override
      public void processResult(int rc, String path, Object ctx, List<String> children)
      {
        KeeperException.Code result = KeeperException.Code.get(rc);
        Assert.assertEquals(result, KeeperException.Code.OK);
        Assert.assertEquals(children.size(), 11);
        latch.countDown();
      }
    };
    Watcher childrenWatch = new Watcher()
    {
      @Override
      public void process(WatchedEvent event)
      {
        Assert.assertEquals(event.getType(), Event.EventType.NodeChildrenChanged);
        _zkClient.getZooKeeper().getChildren(event.getPath(), null, childrenCallback, null);
      }
    };
    AsyncCallback.ChildrenCallback childrenCallback2 = new AsyncCallback.ChildrenCallback()
    {
      @Override
      public void processResult(int rc, String path, Object ctx, List<String> children)
      {
        KeeperException.Code result = KeeperException.Code.get(rc);
        Assert.assertEquals(result, KeeperException.Code.OK);
        latch2.countDown();
      }
    };
    // symlink: /foo/$link -> /foo/bar
    _zkClient.getZooKeeper().getChildren("/foo/$link", childrenWatch, childrenCallback2, null);
    latch2.await(30, TimeUnit.SECONDS);
    _zkClient.ensurePersistentNodeExists("/foo/bar/newNode", new FutureCallback<>());
    latch.await(30, TimeUnit.SECONDS);
    _zkClient.removeNodeUnsafe("/foo/bar/newNode", new FutureCallback<>());
  }