anchor.diff:  %%%
   %%% When any statistic is changed, executor for directory is started. It
   %%% caches changes of statistics for directory, periodically flushing them.
  -%%% Flush has two steps: 1) saving statistics in datastore and 2) propagating them
  -%%% to directory parent. If statistics for a specific dir are not updated or
  -%%% retrieved for ?CACHED_DIR_STATS_INACTIVITY_PERIOD and have been
  -%%% successfully flushed, the executor clears them from cache. If the executor
  -%%% has no statistics left in cache, it terminates after the idle timeout.
  +%%% Flush has three steps:
  +%%%     1) saving statistics in datastore,
  +%%%     2) propagating accumulated updates to directory parent
  +%%%        (difference since the previous propagation),
  +%%%     3) pruning the cache of no longer needed entries, either those to be
  +%%%        deleted or those which were inactive (not updated or retrieved for
  +%%%        ?CACHED_DIR_STATS_INACTIVITY_PERIOD)
  +%%% If the executor has no statistics left in cache, it terminates after the idle timeout.
   %%% @end
   %%%-------------------------------------------------------------------
   -module(dir_stats_collector).
  
positive.code: 
  
  %% @private
  -spec flush_cached_dir_stats(cached_dir_stats_key(), cached_dir_stats()) -> UpdatedCachedDirStats :: cached_dir_stats().
  flush_cached_dir_stats({Guid, CollectionType} = _CachedDirStatsKey,
      #cached_dir_stats{current_stats = CurrentStats} = CachedDirStats) ->
      try
          CollectionType:save(Guid, CurrentStats),
          propagate_to_parent(Guid, CollectionType, CachedDirStats)
      catch
          Error:Reason:Stacktrace ->
              ?error_stacktrace("Dir stats collector save error for collection type: ~p and guid ~p: ~p:~p",
                  [CollectionType, Guid, Error, Reason], Stacktrace),
              CachedDirStats
      end.
  
negative.code: 
  
  %% @private
  -spec flush_all(state()) -> state().
  flush_all(#state{
      flush_timer_ref = undefined,
      dir_stats_cache = DirStatsCache
  } = State) ->
      lists:foldl(fun(CachedDirStatsKey, StateAcc) ->
          {HasSucceeded, UpdatedStateAcc} = flush_cached_dir_stats(CachedDirStatsKey, prune_inactive, StateAcc),
          UpdatedStateAcc#state{
              has_unflushed_changes = StateAcc#state.has_unflushed_changes orelse not HasSucceeded
          }
      end, State#state{has_unflushed_changes = false}, maps:keys(DirStatsCache));
  
  flush_all(#state{
      flush_timer_ref = Ref
  } = State) ->
      erlang:cancel_timer(Ref),
      flush_all(State#state{flush_timer_ref = undefined}).
  
  
  %% @private
  -spec flush_cached_dir_stats(cached_dir_stats_key(), pruning_strategy(), state()) ->
      {HasSucceeded :: boolean(), state()}.
  flush_cached_dir_stats(CachedDirStatsKey, _, State) when not is_map_key(CachedDirStatsKey, State#state.dir_stats_cache) ->
      {true, State};
  flush_cached_dir_stats(CachedDirStatsKey, PruningStrategy, State) ->
      CachedDirStats = maps:get(CachedDirStatsKey, State#state.dir_stats_cache),
      case has_unflushed_changes(CachedDirStats) of
          true ->
              UpdatedCachedDirStats = save_and_propagate_cached_dir_stats(CachedDirStatsKey, CachedDirStats),
              SuccessfullyFlushed = not has_unflushed_changes(UpdatedCachedDirStats),
              case SuccessfullyFlushed and (PruningStrategy =:= prune_flushed) of
                  true ->
                      {SuccessfullyFlushed, prune_cached_dir_stats(CachedDirStatsKey, State)};
                  false ->
                      {SuccessfullyFlushed, update_cached_dir_stats(CachedDirStatsKey, UpdatedCachedDirStats, State)}
              end;
          false ->
              case (PruningStrategy =:= prune_flushed) orelse is_inactive(CachedDirStats) of
                  true ->
                      {true, prune_cached_dir_stats(CachedDirStatsKey, State)};
                  false ->
                      {true, State}
              end
      end.
  
  
  %% @private
  