anchor.diff:      [{PathMatch :: string() | binary(), rest_handler, State :: #reqstate{}}].
   %% ====================================================================
   routes() ->
  -    S = #reqstate{module = ?MODULE},
  +    O = #opts{module = ?MODULE},
  +    M = rest_handler,
       [
  -        {"/spaces/create", rest_handler, S#reqstate{resource = create}},
  -        {"/spaces/:id", rest_handler, S#reqstate{resource = main}},
  -        {"/spaces/:id/tokens/userInvite/create", rest_handler, S#reqstate{resource = invite_token}},
  -        {"/spaces/:id/tokens/providerSupport/create", rest_handler, S#reqstate{resource = provider_support_token}}
  +        {<<"/spaces">>,                              M, O#opts{resource = spaces,    methods = [post]        }},
  +        {<<"/spaces/:id">>,                          M, O#opts{resource = space,     methods = [get, patch, delete]}},
  +        {<<"/spaces/:id/users">>,                    M, O#opts{resource = users,     methods = [get]         }},
  +        {<<"/spaces/:id/users/token">>,              M, O#opts{resource = uinvite,   methods = [get]         }},
  +        {<<"/spaces/:id/users/:uid">>,               M, O#opts{resource = user,      methods = [get, delete] }},
  +        {<<"/spaces/:id/users/:uid/privileges">>,    M, O#opts{resource = upriv,     methods = [get, put]    }},
  +        {<<"/spaces/:id/groups">>,                   M, O#opts{resource = groups,    methods = [get]         }},
  +        {<<"/spaces/:id/groups/token">>,             M, O#opts{resource = ginvite,   methods = [get]         }},
  +        {<<"/spaces/:id/groups/:gid">>,              M, O#opts{resource = group,     methods = [get, delete] }},
  +        {<<"/spaces/:id/groups/:gid/privileges">>,   M, O#opts{resource = gpriv,     methods = [get, put]    }},
  +        {<<"/spaces/:id/providers">>,                M, O#opts{resource = providers, methods = [get]         }},
  +        {<<"/spaces/:id/providers/token">>,          M, O#opts{resource = pinvite,   methods = [get]         }},
  +        {<<"/spaces/:id/providers/:pid">>,           M, O#opts{resource = provider,  methods = [get, delete] }}
       ].
   
   
  -%% is_authorized/2
  +%% is_authorized/4
   %% ====================================================================
   %% @doc Returns a boolean() determining if the authenticated client is
   %% authorized to carry the request on the resource.
   %% @see rest_module_behavior
   %% @end
   %% ====================================================================
  --spec is_authorized(Method :: binary(), State :: #reqstate{}) -> boolean().
  -%% ====================================================================
  -is_authorized(<<"POST">>, #reqstate{resource = create, client = #reqclient{type = user}}) ->
  +-spec is_authorized(Resource :: atom(), Method :: rest_handler:method(),
  +                    SpaceId :: binary(), Client :: rest_handler:client()) ->
  +    boolean().
  +%% ====================================================================
  +is_authorized(spaces, post, _SpaceId, _Client) ->
       true;
  -is_authorized(<<"POST">>, #reqstate{resource = create, client = #reqclient{type = provider, id = ProviderId}, data = Data}) ->
  -    Token = proplists:get_value(<<"token">>, Data),
  -    space_logic:can_provider_create(ProviderId, Token);
  -is_authorized(<<"POST">>, #reqstate{resource = main, client = #reqclient{type = user, id = UserId}, data = Data, resid = SpaceId}) ->
  -    space_logic:can_modify(SpaceId, UserId, Data);
  -is_authorized(<<"GET">>, #reqstate{resource = main, client = #reqclient{type = user, id = UserId}, resid = SpaceId}) ->
  -    space_logic:can_user_view(SpaceId, UserId);
  -is_authorized(<<"GET">>, #reqstate{resource = main, client = #reqclient{type = provider, id = ProviderId}, resid = SpaceId}) ->
  -    space_logic:can_provider_view(SpaceId, ProviderId);
  -is_authorized(<<"POST">>, #reqstate{resource = invite_token, client = #reqclient{type = user, id = UserId}, resid = SpaceId}) ->
  -    space_logic:can_invite(SpaceId, UserId);
  -is_authorized(<<"POST">>, #reqstate{resource = provider_support_token, client = #reqclient{type = user, id = UserId}, resid = SpaceId}) ->
  -    space_logic:can_add_providers(SpaceId, UserId);
  -is_authorized(<<"DELETE">>, #reqstate{resource = main, client = #reqclient{type = user, id = UserId}, resid = SpaceId}) ->
  -    space_logic:can_delete(SpaceId, UserId).
  -
  -
  -%% accept_resource/1
  -%% ====================================================================
  -%% @doc Processes data submitted by a client through POST on a REST resource.
  -%% @see rest_module_behavior
  -%% @end
  -%% ====================================================================
  --spec accept_resource(State :: #reqstate{}) ->
  -    {ok, Response :: reqdata()} | ok | {error, Reason :: term()}.
  -%% ====================================================================
  -accept_resource(#reqstate{resource = create, client = #reqclient{type = user, id = UserId}, data = Data}) ->
  +is_authorized(space, patch, SpaceId, #client{type = user, id = UserId}) ->
  +    space_logic:has_privilege(SpaceId, UserId, space_change_data);
  +is_authorized(space, delete, SpaceId, #client{type = user, id = UserId}) ->
  +    space_logic:has_privilege(SpaceId, UserId, space_remove);
  +is_authorized(uinvite, get, SpaceId, #client{type = user, id = UserId}) ->
  +    space_logic:has_privilege(SpaceId, UserId, space_invite_user);
  +is_authorized(user, delete, SpaceId, #client{type = user, id = UserId}) ->
  +    space_logic:has_privilege(SpaceId, UserId, space_remove_user);
  +is_authorized(ginvite, get, SpaceId, #client{type = user, id = UserId}) ->
  +    space_logic:has_privilege(SpaceId, UserId, space_invite_group);
  +is_authorized(group, delete, SpaceId, #client{type = user, id = UserId}) ->
  +    space_logic:has_privilege(SpaceId, UserId, space_remove_group);
  +is_authorized(pinvite, get, SpaceId, #client{type = user, id = UserId}) ->
  +    space_logic:has_privilege(SpaceId, UserId, space_add_provider);
  +is_authorized(provider, delete, SpaceId, #client{type = user, id = UserId}) ->
  +    space_logic:has_privilege(SpaceId, UserId, space_remove_provider);
  +is_authorized(R, put, SpaceId, #client{type = user, id = UserId})
  +        when R =:= upriv; R =:= gpriv ->
  +    space_logic:has_privilege(SpaceId, UserId, space_set_privileges);
  +is_authorized(_, get, SpaceId, #client{type = user, id = UserId}) ->
  +    space_logic:has_privilege(SpaceId, UserId, space_view_data);
  +is_authorized(R, get, SpaceId, #client{type = provider, id = ProviderId})
  +        when R =/= groups, R =/= ginvite, R =/= group, R =/= gpriv ->
  +    space_logic:has_provider(SpaceId, ProviderId);
  +is_authorized(_, _, _, _) ->
  +    false.
  +
  +
  +%% resource_exists/3
  +%% ====================================================================
  +%% @doc Returns whether a resource exists.
  +%% @see rest_module_behavior
  +%% @end
  +%% ====================================================================
  +-spec resource_exists(Resource :: atom(), SpaceId :: binary(),
  +                      Bindings :: [{atom(), any()}]) -> boolean().
  +%% ====================================================================
  +resource_exists(spaces, _SpaceId, _Bindings) ->
  +    true;
  +resource_exists(SpaceBound, SpaceId, _Bindings)
  +        when SpaceBound =:= space; SpaceBound =:= users; SpaceBound =:= uinvite;
  +             SpaceBound =:= groups; SpaceBound =:= ginvite;
  +             SpaceBound =:= providers; SpaceBound =:= pinvite ->
  +    space_logic:exists(SpaceId);
  +resource_exists(UserBound, SpaceId, Bindings) when UserBound =:= user; UserBound =:= upriv ->
  +    UID = proplists:get_value(uid, Bindings),
  +    space_logic:has_user(SpaceId, UID);
  +resource_exists(GroupBound, SpaceId, Bindings) when GroupBound =:= group; GroupBound =:= gpriv ->
  +    GID = proplists:get_value(gid, Bindings),
  +    space_logic:has_group(SpaceId, GID);
  +resource_exists(provider, SpaceId, Bindings) ->
  +    PID = proplists:get_value(pid, Bindings),
  +    space_logic:has_provider(SpaceId, PID).
  +
  +
  +%% accept_resource/6
  +%% ====================================================================
  +%% @doc Processes data submitted by a client through POST, PATCH on a REST
  +%% resource.
  +%% @see rest_module_behavior
  +%% @end
  +%% ====================================================================
  +-spec accept_resource(Resource :: atom(), Method :: rest_handler:method(),
  +                      SpaceId :: binary(), Data :: [proplists:property()],
  +                      Client :: rest_handler:client(),
  +                      Bindings :: [{atom(), any()}]) ->
  +    {true, URL :: binary()} | boolean().
  +%% ====================================================================
  +accept_resource(spaces, post, _SpaceId, Data, #client{type = user, id = UserId}, _Bindings) ->
       Name = proplists:get_value(<<"name">>, Data),
  -    {ok, SpaceId} = space_logic:user_create(Name, UserId),
  -    {ok, [{spaceId, SpaceId}]};
  -accept_resource(#reqstate{resource = create, client = #reqclient{type = provider, id = ProviderId}, data = Data}) ->
  +    if
  +        Name =:= undefined -> false;
  +        true ->
  +            {ok, SpaceId} = space_logic:create({user, UserId}, Name),
  +            {true, <<"/spaces/", SpaceId/binary>>}
  +    end;
  +accept_resource(spaces, post, _SpaceId, Data, #client{type = provider, id = ProviderId}, _Bindings) ->
       Name = proplists:get_value(<<"name">>, Data),
       Token = proplists:get_value(<<"token">>, Data),
  -    {ok, SpaceId} = space_logic:provider_create(Name, ProviderId, Token),
  -    {ok, [{spaceId, SpaceId}]};
  -accept_resource(#reqstate{resource = main, client = #reqclient{id = UserId}, data = Data, resid = SpaceId}) ->
  -    space_logic:modify(SpaceId, UserId, Data);
  -accept_resource(#reqstate{resource = invite_token, client = #reqclient{id = UserId}, data = Data, resid = SpaceId}) ->
  -    case proplists:get_value(<<"groupId">>, Data) of
  -        undefined -> space_logic:new_user_invite_token(SpaceId, UserId);
  -        GroupId -> space_logic:new_group_invite_token(SpaceId, GroupId, UserId)
  -    end;
  -accept_resource(#reqstate{resource = provider_support_token, client = #reqclient{id = UserId}, resid = SpaceId}) ->
  -    space_logic:new_support_token(SpaceId, UserId).
  +    if
  +        Name =:= undefined -> false;
  +        Token =:= undefined -> false;
  +        not token_logic:is_valid(Token, space_create_token) -> false;
  +        true ->
  +            {ok, SpaceId} = space_logic:create({provider, ProviderId}, Name, Token),
  +            {true, <<"/spaces/", SpaceId/binary>>}
  +    end;
  +accept_resource(space, patch, SpaceId, Data, _Client, _Bindings) ->
  +    Name = proplists:get_value(<<"name">>, Data),
  +    if
  +        Name =:= undefined -> false;
  +        true ->
  +            ok = space_logic:modify(SpaceId, Name),
  +            true
  +    end;
  +accept_resource(upriv, put, SpaceId, Data, _Client, Bindings) ->
  +    UID = proplists:get_value(uid, Bindings),
  +    BinPrivileges = proplists:get_value(<<"privileges">>, Data),
  +    if
  +        BinPrivileges =:= undefined -> false;
  +        true ->
  +            Privileges = [binary_to_existing_atom(P, latin1) || P <- BinPrivileges],
  +            ok = space_logic:set_privileges(SpaceId, {user, UID}, Privileges),
  +            true
  +    end;
  +accept_resource(gpriv, put, SpaceId, Data, _Client, Bindings) ->
  +    GID = proplists:get_value(gid, Bindings),
  +    BinPrivileges = proplists:get_value(<<"privileges">>, Data),
  +    if
  +        BinPrivileges =:= undefined -> false;
  +        true ->
  +            Privileges = [binary_to_existing_atom(P, latin1) || P <- BinPrivileges],
  +            ok = space_logic:set_privileges(SpaceId, {group, GID}, Privileges),
  +            true
  +    end.
   
   
   %% provide_resource/1
  
positive.code: 
  
  %% API
  -export([routes/0, is_authorized/2, accept_resource/1, provide_resource/1,
      delete_resource/1]).
  
  
  %% routes/0
  
negative.code: %% @see rest_module_behavior
  %% @end
  %% ====================================================================
  -spec provide_resource(Resource :: atom(), SpaceId :: binary(),
                         Client :: rest_handler:client(),
                         Bindings :: [{atom(), any()}]) ->
      {ok, Data :: reqdata()} | {error, Reason :: term()}.
  %% ====================================================================
  provide_resource(space, SpaceId, #client{type = ClientType}, _Bindings) ->
      {ok, Data} = space_logic:get_data(SpaceId, ClientType),
      Data
  provide_resource(users, SpaceId, #client{type = ClientType}, _Bindings) ->
      {ok, Users} = space_logic:get_users(SpaceId, ClientType),
      Users;
  provide_resource(uinvite, SpaceId, _Client, _Bindings) ->
      {ok, Token} = token_logic:create(space_invite_user_token, SpaceId, user),
      [{token, Token}];
  provide_resource(user, SpaceId, #client{type = ClientType}, Bindings) ->
      UID = proplists:get_value(uid, Bindings),
      {ok, User} = space_logic:get_user(SpaceId, ClientType, UID),
      User;
  provide_resource(upriv, SpaceId, _Client, Bindings) ->
      UID = proplists:get_value(uid, Bindings),
      {ok, Privileges} = space_logic:get_privileges(SpaceId, {user, UID}),
      [{privileges, Privileges}];
  provide_resource(groups, SpaceId, _Client, _Bindings) ->
      {ok, Groups} = space_logic:get_groups(SpaceId),
      Groups
  provide_resource(ginvite, SpaceId, _Client, _Bindings) ->
      {ok, Token} = token_logic:create(space_invite_group_token, SpaceId, group),
      {ok, [{token, Token}]};
  provide_resource(group, SpaceId, _Client, Bindings) ->
      GID = proplists:get_value(gid, Bindings),
      {ok, Group} = space_logic:get_group(SpaceId, GID),
      Group;
  provide_resource(gpriv, SpaceId, _Client, Bindings) ->
      GID = proplists:get_value(gid, Bindings),
      {ok, Privileges} = space_logic:get_privileges(SpaceId, {group, GID}),
      {ok, [{privileges, Privileges}]};
  provide_resource(providers, SpaceId, #client{type = ClientType}, _Bindings) ->
      {ok, Providers} = space_logic:get_providers(SpaceId, ClientType),
      Providers;
  provide_resource(pinvite, SpaceId, _Client, _Bindings) ->
      {ok, Token} = token_logic:create(space_support_token, SpaceId),
      {ok, [{token, Token}]};
  provide_resource(provider, SpaceId, #client{type = ClientType}, Bindings) ->
      PID = proplists:get_value(pid, Bindings),
      {ok, Provider} = space_logic:get_provider(SpaceId, ClientType, PID),
      Provider.
  
  
  %% delete_resource/2
  