public StoredNode getReindexRoot(StoredNode node, NodePath path, boolean includeSelf) {
   if (node.getNodeType() == Node.ATTRIBUTE_NODE) return null;
   IndexSpec indexConf =
       node.getDocument().getCollection().getIndexConfiguration(node.getDocument().getBroker());
   if (indexConf != null) {
     FulltextIndexSpec config = indexConf.getFulltextIndexSpec();
     if (config == null) return null;
     boolean reindexRequired = false;
     int len =
         node.getNodeType() == Node.ELEMENT_NODE && !includeSelf
             ? path.length() - 1
             : path.length();
     for (int i = 0; i < len; i++) {
       QName qn = path.getComponent(i);
       if (config.hasQNameIndex(qn)) {
         reindexRequired = true;
         break;
       }
     }
     if (reindexRequired) {
       StoredNode topMost = null;
       StoredNode currentNode = node;
       while (currentNode != null) {
         if (config.hasQNameIndex(currentNode.getQName())) topMost = currentNode;
         currentNode = (StoredNode) currentNode.getParentNode();
       }
       return topMost;
     }
   }
   return null;
 }
 public void attribute(Txn transaction, AttrImpl attrib, NodePath path) {
   path.addComponent(attrib.getQName());
   if (config == null || config.matchAttribute(path)) {
     engine.storeAttribute(
         attrib,
         null,
         NativeTextEngine.ATTRIBUTE_NOT_BY_QNAME,
         config,
         mode == REMOVE_ALL_NODES);
   }
   if (config != null && config.hasQNameIndex(attrib.getQName())) {
     engine.storeAttribute(
         attrib, null, NativeTextEngine.ATTRIBUTE_BY_QNAME, config, mode == REMOVE_ALL_NODES);
   }
   path.removeLastComponent();
   super.attribute(transaction, attrib, path);
 }