/**
   * return null if the algorithm should stop (monitor was cancelled) return DOMASTNodeLeafContinue
   * if the algorithm should continue but no valid DOMASTNodeLeaf was added (i.e. node was null
   * return the DOMASTNodeLeaf added to the DOM AST View's model otherwise
   *
   * @param node
   * @return
   */
  private DOMASTNodeLeaf addRoot(IASTNode node) {
    if (monitor != null && monitor.isCanceled()) return null;
    if (node == null) return new DOMASTNodeLeafContinue(null);

    // only do length check for ASTNode (getNodeLocations on PreprocessorStatements is very
    // expensive)
    if (node instanceof ASTNode && ((ASTNode) node).getLength() <= 0)
      return new DOMASTNodeLeafContinue(null);

    DOMASTNodeParent parent = null;

    // if it's a preprocessor statement being merged then do a special search for parent (no search)
    if (node instanceof IASTPreprocessorStatement) {
      parent = root;
    } else {
      IASTNode tempParent = node.getParent();
      if (tempParent instanceof IASTPreprocessorStatement) {
        parent = root.findTreeParentForMergedNode(node);
      } else {
        parent = root.findTreeParentForNode(node);
      }
    }

    if (parent == null) parent = root;

    return createNode(parent, node);
  }
  public void groupIncludes(DOMASTNodeLeaf[] treeIncludes) {
    // loop through the includes and make sure that all of the nodes
    // that are children of the TU are in the proper include (based on offset)
    for (int i = treeIncludes.length - 1; i >= 0; i--) {
      final DOMASTNodeLeaf nodeLeaf = treeIncludes[i];
      if (nodeLeaf == null || !(nodeLeaf.getNode() instanceof IASTPreprocessorIncludeStatement))
        continue;

      final String path = ((IASTPreprocessorIncludeStatement) nodeLeaf.getNode()).getPath();
      final DOMASTNodeLeaf[] children = root.getChildren(false);
      for (final DOMASTNodeLeaf child : children) {
        if (child != null
            && child != nodeLeaf
            && child.getNode().getContainingFilename().equals(path)) {
          root.removeChild(child);
          ((DOMASTNodeParent) nodeLeaf).addChild(child);
        }
      }
    }
  }
  private DOMASTNodeLeaf createNode(DOMASTNodeParent parent, IASTNode node) {
    DOMASTNodeParent tree = new DOMASTNodeParent(node);
    parent.addChild(tree);

    // set filter flags
    if (node instanceof IASTProblemHolder || node instanceof IASTProblem) {
      tree.setFiltersFlag(DOMASTNodeLeaf.FLAG_PROBLEM);

      if (node instanceof IASTProblemHolder)
        astProblems =
            (IASTProblem[])
                ArrayUtil.append(
                    IASTProblem.class, astProblems, ((IASTProblemHolder) node).getProblem());
      else astProblems = (IASTProblem[]) ArrayUtil.append(IASTProblem.class, astProblems, node);
    }
    if (node instanceof IASTPreprocessorStatement)
      tree.setFiltersFlag(DOMASTNodeLeaf.FLAG_PREPROCESSOR);
    if (node instanceof IASTPreprocessorIncludeStatement)
      tree.setFiltersFlag(DOMASTNodeLeaf.FLAG_INCLUDE_STATEMENTS);

    return tree;
  }