public TreeNode[] findNodeInContext(String startCtxPath, @Nullable final String name) {
    final List<TreeNode> out = new ArrayList<TreeNode>();
    root.iterateThruContext(
        startCtxPath,
        new TreeNodeRoot.TreeNodeHandler2() {
          public boolean handleNode(int ctxPathCounter, TreeNode node) {
            if (name == null || node.getName().equalsIgnoreCase(name)) {
              out.add(node);
            }
            return true;
          }
        });

    return out.toArray(new TreeNode[out.size()]);
    /*
            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 new TreeNode[0];
                }
            }

            return cycled.findChildrenBySuffix(name);
    */
  }
  public ContextItem[] findInRootContext(int[] types) {
    List<ContextItem> out = new ArrayList<ContextItem>();
    for (TreeNode n : root.findChildrenByTypes(types)) {
      // todo -- revise to replace using value directly with a TreeNode instance
      out.add(new ContextItemImpl(n.getPath(), n.getValue()));
    }

    return out.toArray(new ContextItem[out.size()]);
  }
  //  /FL!..$ota_flow_manager_pkg.pks/PS!..$ota_flow_manager_pkg/Va!..$pc_bs_15m_dflt [Value]
  // 1|INTEGER
  public void addContextPath(String ctxPath, String value) {
    String[] path = ctxPath.split("/");

    // validate root context
    if (!("/" + path[1]).startsWith(ContextPath.FILE_CTX_PRX) || ctxPath.indexOf(' ') != -1) {
      throw new ValidationException("Broken Context Path occurred: FILE CTX Path must be first!");
    } else {
      switch (path.length) {
        case 0:
        case 1:
          throw new ValidationException("Broken Context Path occurred");
        case 2: // load file attributes
          String fileName = path[1].substring(6);
          FileEntitiesHolder fileHolder = files.get(fileName);
          if (fileHolder == null) {
            fileHolder = new FileEntitiesHolder(fileName);
            files.put(fileName, fileHolder);
          }
          value = (value == null || value.length() == 0) ? "" : value;
          fileHolder.value = value;
          return;
        default:
          break;
      }
    }

    String encodedName = "/" + path[2];
    String filePath = path[1].substring(6);
    String name = path[2].substring(6); // , path[2].length());
    // try to find existing top node first
    List<TreeNode> addTo = new ArrayList<TreeNode>();
    root.findChildrenBySuffix(name, addTo);
    for (TreeNode node : addTo) {
      final TreeNodeTop top = (TreeNodeTop) node;
      if (encodedName.equals(top.encodedName) && filePath.equals(top.owner.filePath)) {
        // top node found
        addCtxValue(top, path, value);
        return;
      }
    }

    // top node not found, so create one
    int type = ContextPathUtil.prefix2type(encodedName.substring(0, 4));
    TreeNode top = addTopNode(root, type, encodedName, filePath);
    addCtxValue(top, path, value);

    // log adding entry
    println("[Path] " + ctxPath + " [Value] " + value);
  }
  public String getContextPathValue(String ctxPath) {
    // todo -- replace split("/") with Pattern.split("/")
    String[] path = ctxPath.split("/");

    int startWith = ("/" + path[1]).startsWith(ContextPath.FILE_CTX_PRX) ? 2 : 1;
    if (startWith == path.length) {
      FileEntitiesHolder hld = files.get(path[1].substring(6));
      if (hld != null) {
        return hld.value; // Long.toString(hld.timeStamp); //
      }

      return null;
    }

    // expected: startWith == 2
    String filePath = path[1].substring(6);

    // find top nodes the specified name
    // "/" + path[2]
    String encodedName = "/" + path[2];
    String name = path[2].substring(6);
    List<TreeNode> addTo = new ArrayList<TreeNode>();
    root.findChildrenBySuffix(name, addTo);

    for (TreeNode node : addTo) {
      // find among top nodes the one which belongs to the correct file
      final TreeNodeTop top = (TreeNodeTop) node;
      if (encodedName.equals(top.encodedName) && filePath.equals(top.owner.filePath)) {
        // the found top node is considered as a root of target hierarhy
        TreeNode cycled = node;
        for (int i = startWith + 1; i < path.length; i++) {
          encodedName = "/" + path[i];
          cycled = cycled.findChildByEncodedName(encodedName);
          if (cycled == null) {
            return null;
          }
        }

        return cycled.getValue();
      } else {
        // todo -- investige the case
        int hh = 0;
      }
    }

    return null;
  }
 public void findNodesInContextCommon(
     String startCtxPath, String name, @NotNull TreeNode.TreeNodeHandler handler) {
   if (startCtxPath != null) {
     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; // new TreeNode[0];
       }
     }
     cycled.iterateOverChildrenWithSuffix(name, handler);
   } else {
     root.iterateOverChildrenWithSuffix(name, handler);
   }
 }
  public TreeNode[] findNodeInContext(final String ctxPath, final int[] ctxTypes) {
    //        final List<Integer>  types = primitiveArrayToObjectList(ctxTypes);
    final List<TreeNode> out = new ArrayList<TreeNode>();
    root.iterateThruContext(
        ctxPath,
        new TreeNodeRoot.TreeNodeHandler2() {
          public boolean handleNode(int ctxPathCounter, TreeNode node) {
            if (node.getPath().equals(ctxPath)) {
              out.addAll(Arrays.asList(node.findChildrenByTypes(ctxTypes)));
              return false;
            }
            //                if(types.size() == 0 || types.contains(node.getType())){
            //                    out.add(node);
            //                }
            return true;
          }
        });

    return out.toArray(new TreeNode[out.size()]);
  }
 public void cleanUp() {
   files.clear();
   root.getChilds().clear();
 }
 public TreeNode[] findNodeInRootContext(String name) {
   return root.findChildrenBySuffix(name);
 }