anchor.diff:  
   
   %% @private
  --spec get_from_cache(token_auth(), Now :: timestamp()) ->
  -    {ok, cache_item()} | ?ERROR_NOT_FOUND.
  -get_from_cache(TokenAuth, Now) ->
  -    try ets:lookup(?CACHE_NAME, TokenAuth) of
  -        [#cache_item{cache_expiration = Expiration} = Item] when Now < Expiration ->
  -            {ok, Item};
  -        _ ->
  -            ?ERROR_NOT_FOUND
  -    catch Type:Reason ->
  -        ?warning("Failed to lookup ~p cache (ets table) due to ~p:~p", [
  -            ?MODULE, Type, Reason
  -        ]),
  -        ?ERROR_NOT_FOUND
  -    end.
  -
  -
  -%% @private
  --spec save_in_cache(cache_item()) -> ok.
  -save_in_cache(Item) ->
  -    try
  -        ets:insert(?CACHE_NAME, Item),
  -        ok
  -    catch Type:Reason ->
  -        ?warning("Failed to save entry in ~p cache (ets table) due to ~p:~p", [
  -            ?MODULE, Type, Reason
  -        ]),
  -        ok
  -    end.
  -
  -
  -%% @private
  --spec verify_token_auth(Now :: timestamp(), token_auth()) ->
  -    {verification_result(), VerificationResultExpiration :: timestamp()}.
  -verify_token_auth(Now, #token_auth{
  -    access_token = SerializedAccessToken,
  +-spec verify_token_auth(token_auth()) ->
  +    {token_ref(), verification_result()}.
  +verify_token_auth(#token_auth{
  +    access_token = AccessToken,
       peer_ip = PeerIp,
       interface = Interface,
       data_access_caveats_policy = DataAccessCaveatsPolicy
   }) ->
  -    CacheDefaultTTL = ?CACHE_ITEM_DEFAULT_TTL,
  -
  -    case deserialize_token(SerializedAccessToken) of
  +    case deserialize_token(AccessToken) of
           {ok, #token{subject = Subject} = Token} ->
               case token_logic:verify_access_token(
  -                SerializedAccessToken, PeerIp, Interface,
  +                AccessToken, PeerIp, Interface,
                   DataAccessCaveatsPolicy
               ) of
  -                {ok, Subject, undefined} ->
  +                {ok, Subject, TokenTTL} ->
  +                    TokenExpiration = case TokenTTL of
  +                        undefined -> undefined;
  +                        _ -> ?NOW() + TokenTTL
  +                    end,
                       Auth = #auth{
                           subject = Subject,
                           caveats = tokens:get_caveats(Token)
                       },
  -                    {{ok, Auth, undefined}, Now + CacheDefaultTTL};
  -                {ok, Subject, TokenTTL} ->
  -                    Auth = #auth{
  -                        subject = Subject,
  -                        caveats = tokens:get_caveats(Token)
  -                    },
  -                    Expiration = Now + min(TokenTTL, CacheDefaultTTL),
  -                    {{ok, Auth, Now + TokenTTL}, Expiration};
  +                    {get_token_ref(Token), {ok, Auth, TokenExpiration}};
                   {error, _} = VerificationError ->
  -                    {VerificationError, Now + CacheDefaultTTL}
  +                    {undefined, VerificationError}
               end;
           {error, _} = DeserializationError ->
  -            {DeserializationError, Now + CacheDefaultTTL}
  +            {undefined, DeserializationError}
       end.
   
   
  
positive.code:     token_revoked = false :: boolean(),
      cache_expiration :: timestamp()
  }).
  -type cache_item() :: #cache_item{}.
  
  -record(state, {
      cache_invalidation_timer = undefined :: undefined | reference()
  
negative.code: %% @private
  -spec get_from_cache_or_verify_token_auth(token_auth()) -> verification_result().
  get_from_cache_or_verify_token_auth(TokenAuth) ->
      case get_from_cache(TokenAuth) of
          {ok, CachedVerificationResult} ->
              CachedVerificationResult;
          ?ERROR_NOT_FOUND ->
              try
                  {TokenRef, VerificationResult} = verify_token_auth(TokenAuth),
                  save_in_cache(TokenAuth, TokenRef, VerificationResult),
  
                  %% Fetches user doc to trigger user setup if token verification
                  %% succeeded. Otherwise does nothing.
                  %% It must be called after caching verification result as to
                  %% avoid infinite loop (gs_client_worker would try to verify
                  %% given TokenAuth).
                  case VerificationResult of
                      {ok, ?USER(UserId), _} ->
                          case user_logic:get(TokenAuth, UserId) of
                              {ok, _} ->
                                  VerificationResult;
                              {error, _} = Error ->
                                  Error
                          end;
                      _ ->
                          VerificationResult
                  end
              catch Type:Reason ->
                  ?error_stacktrace("Cannot verify user auth due to ~p:~p", [
  