anchor.diff:      Space#od_space{providers_supports = lists:keydelete(ProviderId, 1, Providers)}.
   
   
  -refresh_entity(WhichWay, ModelType, EntityId) ->
  -    OtherWay = case WhichWay of
  -        top_down -> bottom_up;
  -        bottom_up -> top_down
  -    end,
  -    {ok, #document{value = Entity}} = ModelType:get(EntityId),
  -    Neighbours = extract_neighbours(WhichWay, Entity),
  -
  -
  -
  -refresh_entity_top_down(ModelType, EntityId) ->
  -    {ok, #document{value = Entity}} = ModelType:get(EntityId),
  -    ParentRelations = extract_parents(Entity),
  -    ToAggregate = parents_to_aggregate_from(ModelType),
  -    EffRelations = lists:flatmap(
  -        fun(ParentType) ->
  -            Parents = maps:get(ParentType, ParentRelations),
  -            lists:map(
  -                fun(ParentId) ->
  -                    aggregate_from_parent(ModelType, ParentType, ParentId)
  -                end, Parents)
  -        end, ToAggregate),
  -    AggregatedParentRelations = lists:foldl(
  -        fun(RelationsMap, AccMapOuter) ->
  -            lists:foldl(
  -                fun({ModelType, Entities}, AccMapInner) ->
  -                    NewEntities = ordsets:union(
  -                        ordsets:from_list(Entities),
  -                        maps:get(ModelType, RelationsMap, [])
  -                    ),
  -                    AccMapInner#{ModelType => NewEntities}
  -                end, AccMapOuter, maps:to_list(RelationsMap))
  -        end, #{}, [ParentRelations | EffRelations]),
  -    % Check if parents should be marked dirty
  -    case AggregatedParentRelations =:= eff_relations(Entity) of
  -        true ->
  -            % Nothing changed, no action is needed
  -            ok;
  -        false ->
  -            % Mark all children as dirty
  -            ChildrenRelations = extract_children(Entity),
  -            lists:foreach(
  -                fun({ModelType, Entities}) ->
  -                    lists:foreach(
  -                        fun(EntityId) ->
  -                            ModelType:update(EntityId, fun(E) ->
  -                                {ok, mark_dirty(top_down, true, ModelType, EntityId, E)}
  -                            end)
  -                        end, Entities)
  -                end, maps:to_list(ChildrenRelations))
  -    end,
  -    % Update the record marking it not dirty and setting newly calculated
  -    % effective relations.
  -    {ok, _} = ModelType:update(EntityId, fun(Ent) ->
  -        {ok, mark_dirty(top_down, false, ModelType, EntityId, update_eff_relations(
  -            Ent, AggregatedParentRelations
  -        ))}
  -    end),
  -    ok.
  -
  -% TODO should return lists without privs
  -extract_parents(#od_user{} = User) ->
  -    #od_user{
  -        groups = Groups, spaces = Spaces,
  -        handle_services = HServices, handles = Handles
  -    } = User,
  -    #{
  -        od_group => Groups, od_space => Spaces,
  -        od_handle_service => HServices, od_handle => Handles
  -    }.
  -
  +extract_neighbours(bottom_up, #od_group{} = Group) ->
  +    #od_group{users = Users, children = Groups} = Group,
  +    #{od_user => Users, od_group => Groups};
  +extract_neighbours(bottom_up, #od_space{} = Space) ->
  +    #od_space{users = Users, groups = Groups} = Space,
  +    #{od_user => Users, od_group => Groups};
  +extract_neighbours(bottom_up, #od_share{} = Share) ->
  +    #od_share{space = Space} = Share,
  +    #{od_space => [Space]};
  +extract_neighbours(bottom_up, #od_provider{} = Provider) ->
  +    #od_provider{spaces = Spaces} = Provider,
  +    #{od_space => Spaces};
  +extract_neighbours(bottom_up, #od_handle_service{} = HService) ->
  +    #od_handle_service{users = Users, groups = Groups} = HService,
  +    #{od_user => Users, od_group => Groups};
  +extract_neighbours(bottom_up, #od_handle{} = Handle) ->
  +    #od_handle{users = Users, groups = Groups} = Handle,
  +    #{od_user => Users, od_group => Groups};
   extract_neighbours(top_down, #od_user{} = User) ->
       #od_user{
           groups = Groups, spaces = Spaces,
  
positive.code:             NewState = case {WhichWay, Flag} of
                  {bottom_up, true} ->
                      ?emergency("bottom-up dirty: ~p#~s", [Model, Id]),
                      #entity_graph_state{
                          bottom_up_dirty = lists:sort([{Priority, Model, Id} | BottomUpDirty])
                      };
                  {bottom_up, false} ->
                      ?emergency("bottom-up clean: ~s", [Id]),
                      #entity_graph_state{
                          bottom_up_dirty = lists:keydelete(Id, 3, BottomUpDirty)
                      };
                  {top_down, true} ->
                      ?emergency("top-down dirty: ~p#~s", [Model, Id]),
                      #entity_graph_state{
                          top_down_dirty = lists:sort([{Priority, Model, Id} | TopDownDirty])
                      };
                  {top_down, false} ->
                      ?emergency("top-down clean: ~s", [Id]),
                      #entity_graph_state{
                          top_down_dirty = lists:keydelete(Id, 3, TopDownDirty)
                      }
              end,
              {ok, NewState}
          end),
      set_dirty_flag(WhichWay, Flag, Entity).
  
  
negative.code: %%    end.
  
  
  
  aggregate_eff_neighbours([{_, _} | _] = ProplistA, [{_, _} | _] = ProplistB) ->
      privileges_proplists_union(ProplistA ++ ProplistB);
  aggregate_eff_neighbours(PrivilegesA, PrivilegesB) ->
      privileges_union(PrivilegesA, PrivilegesB).
  
  
  
  privileges_union(PrivilegesA, PrivilegesB) ->
      ordsets:union(
          ordsets:from_list(PrivilegesA),
          ordsets:from_list(PrivilegesB)
      ).
  
  
  privileges_proplists_union(PrivilegesProplist) ->
      PrivilegesMap = lists:foldl(
          fun({Id, Privs}, AccMap) ->
              NewPrivs = case maps:get(Id, AccMap, undefined) of
                  undefined ->
                      ordsets:from_list(Privs);
                  OtherPrivs ->
                      privileges_union(Privs, OtherPrivs)
              end,
              maps:put(Id, NewPrivs, AccMap)
          end, #{}, PrivilegesProplist),
      ordsets:from_list(maps:to_list(PrivilegesMap)).
  
  
  override_privileges(PrivilegesProplist, NewPrivileges) ->
      lists:map(
          fun({Id, _}) ->
              {Id, NewPrivileges}
          end, PrivilegesProplist).
  