public boolean setContextPathAttr(String startCtxPath, String attrName, String value) {
    String[] path = startCtxPath.split("/");
    int startWith = ("/" + path[1]).startsWith(ContextPath.FILE_CTX_PRX) ? 2 : 1;

    TreeNode cycled = root;
    for (int i = startWith; i < path.length; i++) {
      String encodedName = "/" + path[i];
      cycled = cycled.findChildByEncodedName(encodedName);
      if (cycled == null) {
        return false;
      }
    }

    TreeNodeImpl nodeImpl = (TreeNodeImpl) cycled;
    int i = 0;
    for (; i < nodeImpl.extAttr.length; i++) {
      String _attrName = decodeAttrName(nodeImpl.extAttr[i]);
      if (_attrName.equals(attrName)) {
        // replace existing attribute with new one
        nodeImpl.extAttr[i] = encodeAttrValue(attrName, value);
        return true;
      }
    }
    nodeImpl.extAttr = increaseArrayByOne(nodeImpl.extAttr);
    // replace existing attribute with new one
    nodeImpl.extAttr[i] = encodeAttrValue(attrName, value);
    return true;
  }
    public TreeNode addNode(int type, String encodedName) {
      String name = encodedName.substring(7, encodedName.length());

      List<TreeNodeImpl> lst = childs.get(name);
      if (lst == null) {
        lst = new ArrayList<TreeNodeImpl>();
        childs.put(name, lst);
      }
      TreeNodeImpl node = new TreeNodeImpl(this, encodedName);
      node.type = type;
      lst.add(node);

      return node;
    }
 public boolean removeNodeByEncodedName(String encodedName) {
   List<TreeNodeImpl> lst = childs.get(encodedName.substring(7, encodedName.length()));
   if (lst != null) {
     Iterator<TreeNodeImpl> iterator = lst.iterator();
     while (iterator.hasNext()) {
       TreeNodeImpl n = iterator.next();
       if (n.getName().equals(encodedName)) {
         n.dispose();
         iterator.remove();
         return true;
       }
     }
   }
   return false;
 }
  private void findValuedNode(TreeNodeImpl node, IndexEntriesWalker iproc) {
    if (node.childs.size() == 0) {
      iproc.process(node.getPath(), node.value, node.extAttr);
    } else {
      // first call handler for root node then for children
      iproc.process(node.getPath(), node.value, node.extAttr);

      // iterate thru children
      for (String name : node.childs.keySet()) {
        for (TreeNode n : node.childs.get(name)) {
          findValuedNode((TreeNodeImpl) n, iproc);
        }
      }
    }
  }
  public void iterateOverChildren(String ctxPath, IndexEntriesWalkerInterruptable iterator) {
    String[] path = ctxPath.split("/");
    int startWith = ("/" + path[1]).startsWith(ContextPath.FILE_CTX_PRX) ? 2 : 1;

    TreeNode cycled = root;
    for (int i = startWith; i < path.length; i++) {
      String encodedName = "/" + path[i];
      cycled = cycled.findChildByEncodedName(encodedName);
      if (cycled == null) {
        return;
      }
    }

    for (List<TreeNodeImpl> siblings : ((TreeNodeImpl) cycled).childs.values()) {
      for (TreeNodeImpl n : siblings) {
        if (!iterator.process(n.getPath(), n.value)) {
          return;
        }
      }
    }
  }
 public String getParentPath() {
   return parent.getPath();
 }
 public String getPath() {
   return (parent != null ? parent.getPath() : "") + encodedName;
 }