anchor.diff:      end, Numpeers, Piecelist).
   
   
  --spec send_updates(pieceset() | pos_integer(), [#watcher{}], array()) -> ok.
  +-spec send_updates(pieceset() | pos_integer(), [#watcher{}], array()) ->
  +    [#watcher{}].
   send_updates(Index, Watchers, Numpeers) when is_integer(Index) ->
  -    Matching = [Watch || #watcher{pieceset=Watchedset}=Watch <- Watchers,
  -        etorrent_pieceset:is_member(Index, Watchedset)],
  -    [send_update(Watcher, Numpeers) || Watcher <- Matching],
  -    ok;
  +    HasChanged = fun(Watchedset) ->
  +        etorrent_pieceset:is_member(Index, Watchedset)
  +    end,
  +    [send_update(HasChanged, Watcher, Numpeers) || Watcher <- Watchers];
   
   send_updates(Pieceset, Watchers, Numpeers) ->
  -    IsMatching = fun(Watchedset) ->
  -        Intersection = etorrent_pieceset:intersection(Pieceset, Watchedset),
  -        not etorrent_pieceset:is_empty(Intersection)
  +    HasChanged = fun(Watchedset) ->
  +        Inter = etorrent_pieceset:intersection(Pieceset, Watchedset),
  +        not etorrent_pieceset:is_empty(Inter)
       end,
  -    Matching = [Watch || #watcher{pieceset=Watchedset}=Watch <- Watchers,
  -        IsMatching(Watchedset)],
  -    [send_update(Watcher, Numpeers) || Watcher <- Matching],
  -    ok.
  -
  -
  --spec send_update(#watcher{}, array()) -> ok.
  +    [send_update(HasChanged, Watcher, Numpeers) || Watcher <- Watchers].
  +
  +-spec send_update(fun((pieceset()) -> boolean()), #watcher{}, array()) -> ok.
  +send_update(HasChanged, Watcher, Numpeers) ->
  +    #watcher{
  +        pieceset=Pieceset,
  +        changed=Changed,
  +        timer_ref=TRef} = Watcher,
  +    case {Changed, TRef} of
  +        %% waiting
  +        {false, none} ->
  +            case HasChanged(Pieceset) of
  +                %% waiting -> limited
  +                true ->
  +                    NewTRef = send_update(Watcher, Numpeers),
  +                    Watcher#watcher{timer_ref=NewTRef};
  +                %% waiting -> waiting
  +                false ->
  +                    Watcher
  +            end;
  +        %% limited -> updated
  +        {false, TRef} ->
  +            Watcher#watcher{changed=HasChanged(Pieceset)};
  +        %% updated -> updated
  +        {true, TRef} ->
  +            Watcher
  +    end.
  +
  +-spec send_update(#watcher{}, array()) -> reference().
   send_update(Watcher, Numpeers) ->
       #watcher{
           pid=Pid,
  -        ref=Ref,
  +        ref=MRef,
           tag=Tag,
  -        pieceset=Pieceset} = Watcher,
  +        pieceset=Pieceset,
  +        interval=Interval} = Watcher,
       Piecelist = sorted_piecelist(Pieceset, Numpeers),
  -    Pid ! {scarcity, Ref, Tag, Piecelist},
  -    ok.
  +    Pid ! {scarcity, MRef, Tag, Piecelist},
  +    erlang:start_timer(Interval, self(), MRef).
   
   
   -ifdef(TEST).
  
positive.code:         watchers=Watchers} = State,
      NewNumpeers = increment(Pieceset, Numpeers),
      NewMonitors = etorrent_monitorset:insert(PeerPid, Pieceset, Monitors),
      send_updates(Pieceset, Watchers, NewNumpeers),
      NewState = State#state{
          peer_monitors=NewMonitors,
          num_peers=NewNumpeers},
      {reply, ok, NewState};
  
  handle_call({add_piece, Pid, PieceIndex, Pieceset}, _, State) ->
  
negative.code: -spec watch(torrent_id(), term(), pieceset()) ->
      {ok, reference(), [pos_integer()]}.
  watch(TorrentID, Tag, Pieceset) ->
      watch(TorrentID, Tag, Pieceset, 0).
  
  
  %% @doc Receive updates to changes in scarcity
  %%
  %% @end
  -spec watch(torrent_id(), term(), pieceset(), pos_integer()) ->
      {ok, reference(), [pos_integer()]}.
  watch(TorrentID, Tag, Pieceset, Interval) ->
      SrvPid = lookup_scarcity_server(TorrentID),
      gen_server:call(SrvPid, {watch, self(), Interval, Tag, Pieceset}).
  
  %% @doc Cancel updates to changes in scarcity
  %%
  