anchor.diff:  %% @doc Non gen-server message handler callbacks
   %% @end
   %%--------------------------------------------------------------------
  +handle_info({irc, user, Ref, From = {Pid,Nick}, {nick, N}}, S = #state{users=U}) ->
  +    case lists:keysearch(N, #user.nick, U) of
  +        {value, #user{}} ->
  +            send(srv_msg({error, nicknameinuse}, Ref, S), From),
  +            {noreply, S};
  +        false ->
  +            case lists:keysearch(Nick, #user.nick, U) of
  +                {value, User = #user{}} ->
  +                    NewUser = User#user{nick=N},
  +                    NewUsers = [NewUser|lists:delete(User, U)],
  +                    send(srv_msg(ok, Ref, S), From),
  +                    {noreply, S#state{users=NewUsers}};
  +                false ->
  +                    URef = erlang:monitor(process, Pid),
  +                    NewUser = #user{nick=N, pid=Pid, ref=URef},
  +                    NewUsers = [NewUser|U],
  +                    send(srv_msg(ok, Ref, S), From),
  +                    {noreply, S#state{users=NewUsers}}
  +            end
  +    end;
  +handle_info({irc, channel, Ref, From, {join, Chan}},
  +            S = #state{channels=C}) ->
  +    case lists:keysearch(Chan, #chan.name, C) of
  +        {value, #chan{pid=P}} ->
  +            P ! gen_irc:msg(channel, Ref, From, join),
  +            {noreply, S};
  +        false ->
  +            case irc_channel:start_monitor(S#state.net, Chan) of
  +                {ok, CPid, CRef} ->
  +                    NewChan = #chan{pid=CPid,name=Chan,ref=CRef},
  +                    NewChans = [NewChan|C],
  +                    CPid ! gen_irc:msg(channel, Ref, From, join),
  +                    {noreply, S#state{channels=NewChans}};
  +                Error ->
  +                    ?WARN("Couldn't start channel ~p: ~p", [Chan, Error]),
  +                    send(gen_irc:msg(channel, Ref, S#state.name, {error, toomanychannels}), From),
  +                    {noreply, S}
  +            end
  +    end;
  +handle_info(M = {'DOWN', Ref, process, _Pid, _}, S = #state{channels=C,users=U}) ->
  +    case lists:keysearch(Ref, #user.ref, U) of
  +        {value, User} ->
  +            {noreply, S#state{users=lists:delete(User,U)}};
  +        false ->
  +            case lists:keysearch(Ref, #chan.ref, C) of
  +                {value, Chan} ->
  +                    {noreply, S#state{channels=lists:delete(Chan,c)}};
  +                false ->
  +                    ?WARN("Unexpected monitor message ~p",[M]),
  +                    {noreply, S}
  +            end
  +    end;
   handle_info(Info, State) ->
       ?WARN("Unexpected info ~p", [Info]),
       {noreply, State}.
  
positive.code: -export([init/1, handle_call/3, handle_cast/2, handle_info/2,
           terminate/2, code_change/3]).
  
  -record(state, {net, name}).
  -define(SERVER, ?MODULE).
  
  %%====================================================================
  
negative.code: %%--------------------------------------------------------------------
  %%% Internal functions
  %%--------------------------------------------------------------------
  
  send(Msg, {To, _Nick}) when is_pid(To); is_atom(To) ->
      To ! Msg;
  send(Msg, To) when is_pid(To); is_atom(To) ->
      To ! Msg.
  
  srv_msg(Msg, Ref, C = #state{}) when is_reference(Ref) ->
      gen_irc:msg(server, Ref, C#state.name, Msg).
  