Why did you implement this to first find the path (which requires traversing up the ancestors) and then ask for the Node by path (which requires traversing down the path)? This results in between N and 2N node accesses (depending upon how quickly the ACL might prevent read permission), where N is the depth of the path. So for all nodes that can be read, it requires 2N node accesses.

Wouldn't it have been easier to look up the Node by identifier? I understand that checking ACLs requires doing so along the ancestors, stopping as soon as an ACL prevents read. But even doing this would result in between 1 and N+1 node accesses; for all nodes that can be read, it would require only N+1 operations (rather than 2N in the current impl).

On second thought, does `getNodeByIdentifier` even check the ACLs? I don't see it, though it may be buried in one of the methods.