docs: public Set<Dependency<Label, Label, Object>> dependencies(Filter<Dependency<Label, Label, Object>> f, HeadFinder hf) {
      Set<Dependency<Label, Label, Object>> deps = Generics.newHashSet();
      for (Tree t : this) {
  
        TreeGraphNode node = safeCast(t);
        if (node == null || node.isLeaf() || node.children().length < 2) {
          continue;
        }
  
        TreeGraphNode headWordNode;
        if (hf != null) {
          headWordNode = safeCast(node.headTerminal(hf));
        } else {
          headWordNode = node.headWordNode();
        }
        
        for (Tree k : node.children()) {
          TreeGraphNode kid = safeCast(k);
          if (kid == null) {
            continue;
          }
          TreeGraphNode kidHeadWordNode;
          if (hf != null) {
            kidHeadWordNode = safeCast(kid.headTerminal(hf));
          } else {
            kidHeadWordNode = kid.headWordNode();
          }
  
          if (headWordNode != null && headWordNode != kidHeadWordNode && kidHeadWordNode != null) {
            int headWordNodeIndex = headWordNode.index();
            int kidHeadWordNodeIndex = kidHeadWordNode.index();
            
            // If the two indices are equal, then the leaves haven't been indexed. Just return an ordinary
            // UnnamedDependency. This mirrors the implementation of super.dependencies().
            Dependency<Label, Label, Object> d = (headWordNodeIndex == kidHeadWordNodeIndex) ?
                new UnnamedDependency(headWordNode, kidHeadWordNode) : 
                new UnnamedConcreteDependency(headWordNode, headWordNodeIndex, kidHeadWordNode, kidHeadWordNodeIndex);
                
            if (f.accept(d)) {
              deps.add(d);
            }
          }
        }
      }
      return deps;
    }