I dislike the use of context data. The Session's data map is intended to be immutable during the lifetime of the session. There are several disadvantages of using it for access-control logic:

1. Because the data map (stored in ExecutionContext) is immutable, you have to create a new ExecutionContext every time something needs to be added to or removed from the data map. This is expensive, both in terms of number of objects but also in terms of garbage collection (especially with the circular reference between ExecutionContext and JcrSession).
1. The session can actually be used in multiple threads, yet doing this will prevent access checks in other concurrent threads that use the same session.
1. It is actually possible for the user to add the "role"->"ACCESS_CONTROL" entry into their session's data map (via Credentials), and this will circumvent the authorization checks.
1. If `hasPrivileges` (or any other method that uses this pattern) is called from within another such method, then the inner method will remove the context data.

This mechanism is needed, but also needs to be thread safe and less expensive. I suggest adding to `JcrSession` a thread local variable (perhaps named `accessControlScope`) that is used to determine whether the calling thread is within the scope of an access control method. Then, there are two ways to proceed:

The first is use a similar try-finally block, but to define a method on JcrSession that will set `accessControlScope` only if not already set, _and_ return whether the scope was changed. Then, the finally block needs to unset the scope only if it was set.

Alternatively, you could use lambdas. For example, define a single method that will take a `UncheckedOperation` instance (that has a single `execute` method throwing appropriate exceptions, which might be the tricky part). This method would attempt to set the scope if not set, call the `execute` method, and unset the scope only if it was set. To use (for example in the `hasPrivileges` method), you'd do something like this:

    public boolean hasPrivileges( final String path, final Privilege[] privileges ) throws ... {
        return session.executeUnchecked( new UncheckedOperation<Boolean>() {
            public boolean execute() throws ... {
                if (!found(acl = findAccessList(path))) {
                   ...
                }
                return ...
            }
        });
    }

Obviously, `UncheckedOperation.execute` would need to be generic based upon the return type, and `JcrSession.executeUnchecked(UncheckedOperation<T> operation)` would need to be similarly generic.

The UncheckedOperation approach might not work because the throws clause might not be compatible for all places its needed.