class AbstractPath implements Path {

    @Override
    public boolean isAtOrBelow( Path other ) {
        CheckArg.isNotNull(other, "other");
        if (this == other) return true;
        if (other.isRoot()) return true;
        if (other.size() > this.size()) return false;

        // Find this path's ancestor that is of the same size ...
        Path thisPath = this.getAncestor(this.size() - other.size());
        Path thatPath = other;
        assert thisPath.size() == other.size();

        // Walk up and compare; it is more likely that the lower path segments differ (plus it's usually more efficient) ...
        while (!thisPath.isRoot() && thisPath.getLastSegment().equals(thatPath.getLastSegment())) {
            thisPath = thisPath.getParent();
            thatPath = thatPath.getParent();
        }
        return thisPath.isRoot();
    }

}