anchor.diff:      end.
   
   -spec check_write_token(binary(), replyto(), #state{},
  -                        fun(() -> #state{})) -> #state{}.
  +                        fun((tokentype()) -> #state{})) -> #state{}.
   check_write_token(Token, ReplyTo, S, Op) ->
  -    {_, WriteToken, _, _} = get_current_values(S),
  -    check_token(Token, ReplyTo, WriteToken, Op, S).
  -
  --spec check_read_token(binary(), replyto(), #state{},
  -                       fun(() -> #state{})) -> #state{}.
  -check_read_token(Token, ReplyTo, S, Op) ->
  -    {ReadToken, _, _, _} = get_current_values(S),
  -    check_token(Token, ReplyTo, ReadToken, Op, S).
  -
  --spec check_token(token(), replyto(), token(),
  -                  fun(() -> #state{}), #state{}) -> #state{}.
  -check_token(Token, ReplyTo, CurrentToken, Op, S) ->
  -    Auth = (Token =:= internal) or (Token =:= CurrentToken)
  -        or (CurrentToken =:= null),
  -    case Auth of
  -        true ->
  -            Op();
  +    {ReadToken, WriteToken, _, _} = get_current_values(S),
  +    case check_token(write, Token, ReadToken, WriteToken) of
           false ->
               send_replies(ReplyTo, {error, unauthorized}),
  -            S
  +            S;
  +        TokenType ->
  +            Op(TokenType)
  +    end.
  +
  +-spec check_read_token(binary(), replyto(), #state{},
  +                       fun((tokentype()) -> #state{})) ->
  +    #state{}.
  +check_read_token(Token, ReplyTo, S, Op) ->
  +    {ReadToken, WriteToken, _, _} = get_current_values(S),
  +    case check_token(read, Token, ReadToken, WriteToken) of
  +        false ->
  +            send_replies(ReplyTo, {error, unauthorized}),
  +            S;
  +        TokenType ->
  +            Op(TokenType)
  +    end.
  +
  +-spec check_token(tokentype(), token(), token(), token()) -> tokentype() | 'false'.
  +check_token(TokenType, Token, ReadToken, WriteToken) ->
  +    Auth = fun (Token, CurrentToken) ->
  +               (Token =:= internal) or (CurrentToken =:= null)
  +                   or (Token =:= CurrentToken)
  +           end,
  +    case TokenType of
  +        read ->
  +            case Auth(Token, ReadToken) of
  +                true ->
  +                    % It is possible that the Token also carries
  +                    % write-privileges, either because the write-token
  +                    % is not set, or because ReadToken =:= WriteToken.
  +                    case (WriteToken =:= null) or (ReadToken =:= WriteToken) of
  +                        true -> write;
  +                        false -> read
  +                    end;
  +                false ->
  +                    case Auth(Token, WriteToken) of
  +                        true ->
  +                            % We should not allow reads if the
  +                            % WriteToken check passes just because it
  +                            % hasn't been set.
  +                            case WriteToken of
  +                                null -> false;
  +                                _ -> write
  +                            end;
  +                        false ->
  +                            false
  +                    end
  +            end;
  +        write ->
  +            case Auth(Token, WriteToken) of
  +                true -> write;
  +                false -> false
  +            end
       end.
   
   % THOUGHT: Eventually we want to partition tag keyspace instead
  
positive.code: 
  handle_cast({{get, Attrib, Token}, ReplyTo}, #state{data = #tagcontent{} = D} = S) ->
      S1 = check_read_token(Token, ReplyTo, S,
                            fun () ->
                                    do_get(Attrib, ReplyTo, D, S)
                            end),
      {noreply, S1, S1#state.timeout};
  
  
negative.code: -type user_attr() :: [{binary(), binary()}].
  % An 'internal' token is also used by internal consumers, but never stored.
  -type token() :: 'null' | binary().
  -type tokentype() :: 'read' | 'write'.
  -type replyto() :: {pid(), reference()}.
  
  -record(tagcontent, {id :: binary(),
  