anchor.diff:      count/1, 
       dump/1, 
       tick/1,
  +    foreach/2,
       broadcast/2
   ]).
   
   -include_lib("zotonic.hrl").
   
   %% The session server state
  --record(session_srv, {key2pid, pid2key, persist2pid, pid2persist}).
  +-record(session_srv, {context, key2pid, pid2key, persist2pid, pid2persist}).
   
   
   %% @spec start_link(SiteProps) -> {ok,Pid} | ignore | {error,Error}
  
positive.code: %% @spec init(SiteProps) -> {ok, State}
  %% @doc Initialize the session server with an empty session table.  We make the session manager a system process
  %%      so that crashes in sessions are isolated from each other.
  init(_SiteProps) ->
      State = #session_srv{key2pid=dict:new(), pid2key=dict:new(), persist2pid=dict:new(), pid2persist=dict:new()},
      timer:apply_interval(?SESSION_CHECK_EXPIRE * 1000, ?MODULE, tick, [self()]),
      process_flag(trap_exit, true),
      {ok, State}.
  
negative.code: 
  %% @spec tick(pid()) -> void()
  %% @doc Periodic tick used for cleaning up sessions
  tick(SessionManager) when is_pid(SessionManager) ->
      Tick = z_utils:now(),
      foreach(fun(Pid) -> z_session:check_expire(Tick, Pid) end, SessionManager).
  
  %% @spec foreach(?) -> void()
  %% @doc Apply function to all sessions
  foreach(Function, #context{session_manager=SessionManager}) when is_function(Function) ->
      foreach(Function, SessionManager);
  foreach(Function, SessionManager) when is_function(Function) ->
      gen_server:cast(SessionManager, {foreach, Function}).
  
  %% @spec broadcast(#broadcast, Context) -> ok
  %% @doc Broadcast a notification message to all open sessions.
  