anchor.diff:  
   
   %% @private
  --spec check_data_and_cache_constraints(user_ctx:ctx(), file_ctx:ctx(), boolean()) ->
  -    {subpath, file_ctx:ctx()} |
  -    {ancestor, file_ctx:ctx(), children_list()} |
  -    no_return().
  -check_data_and_cache_constraints(UserCtx, FileCtx, AllowAncestorsOfPaths) ->
  +-spec check_and_cache_data_constraints(user_ctx:ctx(), file_ctx:ctx(),
  +    boolean()) -> relation_ctx().
  +check_and_cache_data_constraints(UserCtx, FileCtx, AllowAncestorsOfPaths) ->
       {AllowedPaths, AllowedGuids} = user_ctx:get_data_constraints(UserCtx),
       check_and_cache_data_constraints(
           UserCtx, FileCtx, AllowedPaths, AllowedGuids, AllowAncestorsOfPaths
  
positive.code: 
  
  %% @private
  -spec sanitize_and_cache_relation(CacheKey :: term(), relation()) ->
      {subpath, file_ctx:ctx()} | {ancestor, file_ctx:ctx(), children_list()}.
  sanitize_and_cache_relation(CacheKey, {subpath, _FileCtx} = Rel) ->
      permissions_cache:cache_permission(CacheKey, subpath),
      Rel;
  sanitize_and_cache_relation(CacheKey, {{ancestor, ChildrenSet}, FileCtx}) ->
      ChildrenList = gb_sets:to_list(ChildrenSet),
      CacheVal = {ancestor, ChildrenList},
      permissions_cache:cache_permission(CacheKey, CacheVal),
      {ancestor, FileCtx, ChildrenList}.
  
  
  %% @private
  -spec check_data_constraints(user_ctx:ctx(), file_ctx:ctx(), allowed_paths(),
      allowed_guids(), AllowAncestorsOfPaths :: boolean()
  ) ->
      {relation(), file_ctx:ctx()} | no_return().
  check_data_constraints(_, FileCtx0, AllowedPaths, AllowedGuids, AllowAncestorsOfPaths) ->
      {PathRel, FileCtx1} = check_data_path_constraints(
          FileCtx0, AllowedPaths, AllowAncestorsOfPaths
      ),
      {GuidRel, FileCtx2} = check_data_guid_constraint(
          FileCtx1, AllowedGuids, AllowAncestorsOfPaths
      ),
      case {PathRel, GuidRel} of
          {subpath, subpath} ->
              {subpath, FileCtx2};
          {{ancestor, _Children} = Ancestor, subpath} ->
              {Ancestor, FileCtx2};
          {subpath, {ancestor, _Children} = Ancestor} ->
              {Ancestor, FileCtx2};
          {{ancestor, ChildrenA}, {ancestor, ChildrenB}} ->
              {{ancestor, gb_sets:intersection(ChildrenA, ChildrenB)}, FileCtx2}
      end.
  
  
  %% @private
  -spec check_data_guid_constraint(file_ctx:ctx(), all | [file_meta:path()],
      boolean()) -> {relation(), file_ctx:ctx()} | no_return().
  check_data_guid_constraint(FileCtx, _, _AllowAncestorsOfPaths) ->
      {subpath, FileCtx}.
  %%check_data_guid_constraint(FileCtx0, AllowedGuids, false) ->
  %%    case is_guid_allowed(UserCtx, SessionDiscriminator, FileCtx0, AllowedGuids) of
  %%        {true, FileCtx1} ->
  %%            {subpath, FileCtx1};
  %%        {false, _} ->
  %%            throw(?EACCES)
  %%    end;
  %%check_data_guid_constraint(FileCtx0, AllowedGuids, true) ->
  %%    case is_guid_allowed() of
  %%        true ->
  %%            {subpath, FileCtx0};
  %%        false ->
  %%            {FilePath0, FileCtx1} = file_ctx:get_canonical_path(FileCtx0),
  %%            FilePath1 = string:trim(FilePath0, trailing, "/"),
  %%            AllowedPaths = guids_to_paths(AllowedGuids),
  %%            case check_data_path_relation(FilePath1, AllowedPaths) of
  %%                undefined ->
  %%                    throw(?EACCES);
  %%                subpath ->
  %%                    {subpath, FileCtx1};
  %%                {ancestor, Children} ->
  %%                    {ancestor, FileCtx1, Children}
  %%            end
  %%    end.
  %%
  %%
  %%is_guid_allowed(UserCtx, SessionDiscriminator, FileCtx, AllowedGuids0) ->
  %%    Guid = file_ctx:get_guid_const(FileCtx),
  %%    CacheKey = {guid_constraint, SessionDiscriminator, Guid},
  %%
  %%    case permissions_cache:check_permission(CacheKey) of
  %%        {ok, true} ->
  %%            {true, FileCtx};
  %%        {ok, false} ->
  %%            {false, FileCtx};
  %%        _ ->
  %%            AllowedGuids1 = lists:filter(fun(GuidsSet) ->
  %%                not lists:member(Guid, GuidsSet)
  %%            end, AllowedGuids0),
  %%            case AllowedGuids1 of
  %%                [] ->
  %%                    {true, FileCtx};
  %%                _ ->
  %%                    {FileCtx1, ParentCtx} = file_ctx:get_parent(FileCtx, UserCtx),
  %%                    {IsParentAllowed, _} = is_guid_allowed(
  %%                        UserCtx, SessionDiscriminator,
  %%                        ParentCtx, AllowedGuids1
  %%                    ),
  %%                    permissions_cache:cache_permission(CacheKey, IsParentAllowed),
  %%                    {IsParentAllowed, FileCtx1}
  %%            end
  %%    end.
  
  
  %% @private
  
negative.code: %% @end
  %%--------------------------------------------------------------------
  -spec ensure_authorized_readdir(user_ctx:ctx(), file_ctx:ctx(),
      [fslogic_access:requirement()]) -> relation_ctx().
  ensure_authorized_readdir(UserCtx, FileCtx0, AccessRequirements) ->
      FileCtx1 = fslogic_access:assert_granted(
          UserCtx, FileCtx0, AccessRequirements
      ),
      check_and_cache_data_constraints(UserCtx, FileCtx1, true).
  
  
  %%%===================================================================
  