anchor.diff:  %% RFC 6455 section 7.4.1: status code 1000 means "normal"
   -define(NORMAL_WS_STATUS, 1000).
   
  +-record(state, {
  +          arg,
  +          sconf,
  +          cbmod,
  +          opts,
  +          wsstate,
  +          cbstate,
  +          cbtype
  +         }).
  +
  +-export([start/3, send/2]).
  +-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
  +         terminate/2, code_change/3]).
  +%%
   %% API
  --export([start/3, send/2]).
  -
  -%% Exported for spawn
  --export([receive_control/4]).
  -
  +%%
   start(Arg, CallbackMod, Opts) ->
       SC = get(sc),
       CliSock = Arg#arg.clisock,
       PrepdOpts = preprocess_opts(Opts),
  -    OwnerPid = spawn(?MODULE, receive_control,
  -                     [Arg, SC, CallbackMod, PrepdOpts]),
  +    {ok, OwnerPid} = gen_server:start(?MODULE, [Arg, SC, CallbackMod, PrepdOpts], []),
       CliSock = Arg#arg.clisock,
  -    case SC#sconf.ssl of
  -        undefined ->
  -            inet:setopts(CliSock, [{packet, raw}, {active, once}]),
  -            TakeOverResult =
  -                gen_tcp:controlling_process(CliSock, OwnerPid);
  -        _ ->
  -            ssl:setopts(CliSock, [{packet, raw}, {active, once}]),
  -            TakeOverResult =
  -                ssl:controlling_process(CliSock, OwnerPid)
  -    end,
  +    TakeOverResult = case SC#sconf.ssl of
  +                         undefined ->
  +                             inet:setopts(CliSock, [{packet, raw}, {active, once}]),
  +                             gen_tcp:controlling_process(CliSock, OwnerPid);
  +                         _ ->
  +                             ssl:setopts(CliSock, [{packet, raw}, {active, once}]),
  +                             ssl:controlling_process(CliSock, OwnerPid)
  +                     end,
       case TakeOverResult of
           ok ->
  -            OwnerPid ! ok,
  +            gen_server:cast(OwnerPid, ok),
               exit(normal);
  -        {error, Reason} ->
  -            OwnerPid ! {error, Reason},
  +        {error, Reason}=Error ->
  +            gen_server:cast(OwnerPid, Error),
               exit({websocket, Reason})
       end.
   
  -send(#ws_state{sock=Socket, vsn=ProtoVsn}, {Type, Data}) ->
  -    DataFrame = frame(ProtoVsn, Type,  Data),
  -    case Socket of
  -        {sslsocket,_,_} ->
  -            ssl:send(Socket, DataFrame);
  -        _ ->
  -            gen_tcp:send(Socket, DataFrame)
  -    end;
  -
   send(Pid, {Type, Data}) ->
  -    Pid ! {send, {Type, Data}}.
  -
  -preprocess_opts(GivenOpts) ->
  -    Fun = fun({Key, Default}, Opts) ->
  -                  case lists:keyfind(Key, 1, Opts) of
  -                      false ->
  -                          [{Key, Default}|Opts];
  -                      _ -> Opts
  -                  end
  -          end,
  -    Defaults = [{origin, any},
  -                {callback, basic}],
  -    lists:foldl(Fun, GivenOpts, Defaults).
  -
  -receive_control(Arg, SC, CallbackMod, Opts) ->
  -    receive
  -        ok ->
  -            handshake(Arg, SC, CallbackMod, Opts);
  -        {error, Reason} ->
  -            exit(Reason)
  -    end.
  -
  -handshake(Arg, SC, CallbackMod, Opts) ->
  +    gen_server:cast(Pid, {send, {Type, Data}}).
  +
  +%%
  +%% gen_server functions
  +%%
  +init([Arg, SC, CallbackMod, Opts]) ->
  +    {ok, #state{arg=Arg, sconf=SC, cbmod=CallbackMod, opts=Opts}}.
  +
  +handle_call(_Req, _From, State) ->
  +    {reply, ok, State}.
  +
  +handle_cast(ok, #state{arg=Arg, sconf=SC, opts=Opts}=State) ->
       CliSock = Arg#arg.clisock,
       OriginOpt = lists:keyfind(origin, 1, Opts),
       Origin = get_origin_header(Arg#arg.headers),
       case origin_check(Origin, OriginOpt) of
           {error, Error} ->
               error_logger:error_msg(Error),
  -            exit({error, Error});
  +            {stop, {error, Error}, State};
           ok ->
               ProtocolVersion = ws_version(Arg#arg.headers),
               Protocol = get_protocol_header(Arg#arg.headers),
  
positive.code: 
  handle_message(#ws_frame_info{opcode=ping,
                                data=Data,
                                ws_state=State},
                  Acc) ->
      send(State, {pong, Data}),
      Acc;
  
  handle_message(#ws_frame_info{opcode=pong}, Acc) ->
  
negative.code:                  _ when is_integer(Reason) -> Reason;
                   _ -> ?NORMAL_WS_STATUS
               end,
      do_send(WSState, {close, <<Status:16/big>>}).
  
  basic_messages(FrameInfos, {FragType, FragAcc}) ->
      {Messages, NewFragType, NewFragAcc} =
          lists:foldl(fun handle_message/2, {[], FragType, FragAcc}, FrameInfos),
      {Messages, {NewFragType, NewFragAcc}}.
  
  %% start of a fragmented message
  