anchor.diff:      remove_subscriber(Pid, P).
   
   send(Message, #pubsub{subscribers=Subs}) ->
  -    [ Pid ! Message || Pid <- Subs ],
  +    [ Pid ! Message
  +      || #sub{pid=Pid, filter=Fn} <- Subs,
  +         Fn =:= ?FILTER_ALL orelse
  +         Fn(Message) ],
       ok.
   
  -subscribed(Pid, #pubsub{subscribers=Subs}) ->
  -    lists:member(Pid, Subs).
  +subscribed(Pid, #pubsub{subscribers=Subs}) when is_pid(Pid) ->
  +    lists:keymember(Pid, #sub.pid, Subs).
   
   %%====================================================================
   %% Internal functions
   %%====================================================================
   
   sub_test() ->
  -    P1 = publish(),
  +    P1 = new(),
       Pid = self(),
       P2 = process_msg({sub, Pid}, P1),
       ?assertMatch(true, subscribed(Pid, P2)),
  
positive.code:         ]).
  
  -record(pubsub, {subscribers = []}).
  
  -include_lib("eunit/include/eunit.hrl").
  
  %%====================================================================
  %% API
  %%====================================================================
  
  publish() ->
      #pubsub{}.
  
  sync_subscribe(Publisher) ->
  
negative.code: sync_unsubscribe(Publisher) ->
      gen_server:call(Publisher, {?MODULE, {unsub, self()}}).
  
  add_subscriber(Pid, P = #pubsub{}) when is_pid(Pid) ->
      add_subscriber(Pid, ?FILTER_ALL, P).
  
  add_subscriber(Pid, Fn, P = #pubsub{subscribers=Subs})
    when is_pid(Pid),
         Fn =:= ?FILTER_ALL; is_function(Fn, 1) ->
      case subscribed(Pid, P) of
          false ->
              P#pubsub{subscribers=[#sub{pid=Pid} | Subs]};
          true ->
              P
      end.
  
  remove_subscriber(Pid, P = #pubsub{subscribers=Subs}) when is_pid(Pid) ->
      P#pubsub{subscribers=lists:keydelete(Pid, #sub.pid, Subs)}.
  
  process_msg({sub, Pid}, P = #pubsub{}) ->
      add_subscriber(Pid, P);
  