/**
   * @throws KeeperException
   * @throws InterruptedException
   * @throws NoSuchElementException
   */
  protected byte[] getNext(boolean waitForElement, boolean deleteElement)
      throws KeeperException, InterruptedException, NoSuchElementException {
    TreeMap<KEY, String> orderedChildren;

    // element, take, and remove follow the same pattern.
    // We want to return the child node with the smallest sequence number.
    // Since other clients are remove()ing and take()ing nodes concurrently,
    // the child with the smallest sequence number in orderedChildren might
    // be gone by the time we check.
    // We don't call getChildren again until we have tried the rest of the
    // nodes in sequence order,
    // BUT if the children change with a higher priority
    // than the current child we are getting, then we reload all the
    // children.

    while (true) {
      PriorityLatchChildWatcher childWatcher = new PriorityLatchChildWatcher();
      try {
        orderedChildren = orderedChildren(childWatcher);
      } catch (KeeperException.NoNodeException e) {

        if (waitForElement) {
          zookeeper.create(dir, new byte[0], acl, CreateMode.PERSISTENT);
          continue;
        } else {
          throw new NoSuchElementException();
        }
      }

      if (orderedChildren.size() == 0) {
        if (waitForElement) {
          childWatcher.awaitChange();
          continue;
        } else {
          throw new NoSuchElementException();
        }
      }

      for (String headNode : orderedChildren.values()) {
        String path = dir + "/" + headNode;
        try {
          byte[] data = zookeeper.getData(path, false, null);

          if (childWatcher.hasChangedHigherThan(keyHandler.getPriority(headNode))) {
            break;
          }

          if (deleteElement) {
            zookeeper.delete(path, -1);
          }
          return data;
        } catch (KeeperException.NoNodeException e) {
          // Another client deleted the node first.
        }
      }
    } // while loop end
  }