anchor.diff:  
   -type opcode() :: 0 | 1 | 2 | 8 | 9 | 10.
   -type mask_key() :: 0..16#ffffffff.
  -
  -%% The websocket_data/4 function may be called multiple times for a message.
  -%% The websocket_dispatch/4 function is only called once for each message.
  --type frag_state() ::
  -	undefined | %% no fragmentation has been seen.
  -	{nofin, opcode()} | %% first fragment has been seen.
  -	{nofin, opcode(), binary()} | %% first fragment has been unmasked.
  -	{fin, opcode(), binary()}. %% last fragment has been seen.
  +-type frag_state() :: undefined
  +	| {nofin, opcode(), binary()} | {fin, opcode(), binary()}.
   
   -record(state, {
   	env :: cowboy_middleware:env(),
  
positive.code: 				SoFar, websocket_info, Message, fun handler_before_loop/4)
  	end.
  
  -spec websocket_data(#state{}, Req, any(), binary())
  	-> {ok, Req, cowboy_middleware:env()}
  	| {suspend, module(), atom(), [any()]}
  	when Req::cowboy_req:req().
  %% No more data.
  websocket_data(State, Req, HandlerState, <<>>) ->
  	handler_before_loop(State, Req, HandlerState, <<>>);
  %% Incomplete.
  websocket_data(State, Req, HandlerState, Data) when byte_size(Data) =:= 1 ->
  	handler_before_loop(State, Req, HandlerState, Data);
  %% 7 bit payload length prefix exists
  websocket_data(State, Req, HandlerState,
  		<< Fin:1, Rsv:3, Opcode:4, 1:1, PayloadLen:7, Rest/bits >>
  		= Data) when PayloadLen < 126 ->
  	websocket_data(State, Req, HandlerState,
  		Fin, Rsv, Opcode, PayloadLen, Rest, Data);
  %% 7+16 bits payload length prefix exists
  websocket_data(State, Req, HandlerState,
  		<< Fin:1, Rsv:3, Opcode:4, 1:1, 126:7, PayloadLen:16, Rest/bits >>
  		= Data) when PayloadLen > 125 ->
  	websocket_data(State, Req, HandlerState,
  		Fin, Rsv, Opcode, PayloadLen, Rest, Data);
  %% 7+16 bits payload length prefix missing
  websocket_data(State, Req, HandlerState,
  		<< _Fin:1, _Rsv:3, _Opcode:4, 1:1, 126:7, Rest/bits >>
  		= Data) when byte_size(Rest) < 2 ->
  	handler_before_loop(State, Req, HandlerState, Data);
  %% 7+64 bits payload length prefix exists
  websocket_data(State, Req, HandlerState,
  		<< Fin:1, Rsv:3, Opcode:4, 1:1, 127:7, 0:1, PayloadLen:63,
  		   Rest/bits >> = Data) when PayloadLen > 16#FFFF ->
  	websocket_data(State, Req, HandlerState,
  		Fin, Rsv, Opcode, PayloadLen, Rest, Data);
  %% 7+64 bits payload length prefix missing
  websocket_data(State, Req, HandlerState,
  		<< _Fin:1, _Rsv:3, _Opcode:4, 1:1, 127:7, Rest/bits >>
  		= Data) when byte_size(Rest) < 8 ->
  	handler_before_loop(State, Req, HandlerState, Data);
  %% Invalid payload length or mask bit was not set.
  websocket_data(State, Req, HandlerState, _Data) ->
  	websocket_close(State, Req, HandlerState, {error, badframe}).
  
  -spec websocket_data(#state{}, Req, any(), non_neg_integer(),
  		non_neg_integer(), non_neg_integer(),
  		non_neg_integer(), binary(), binary())
  	-> {ok, Req, cowboy_middleware:env()}
  	when Req::cowboy_req:req().
  %% A fragmented message MUST start a non-zero opcode.
  websocket_data(State=#state{frag_state=undefined}, Req, HandlerState,
  		_Fin=0, _Rsv=0, _Opcode=0, _PayloadLen, _Rest, _Buffer) ->
  	websocket_close(State, Req, HandlerState, {error, badframe});
  %% A control message MUST NOT be fragmented.
  websocket_data(State, Req, HandlerState, _Fin=0, _Rsv=0, Opcode,
  		_PayloadLen, _Rest, _Buffer) when Opcode >= 8 ->
  	websocket_close(State, Req, HandlerState, {error, badframe});
  %% The opcode is only included in the first message fragment.
  websocket_data(State=#state{frag_state=undefined}, Req, HandlerState,
  		_Fin=0, _Rsv=0, Opcode, PayloadLen, Rest, Data) ->
  	websocket_before_unmask(
  		State#state{frag_state={nofin, Opcode}}, Req, HandlerState,
  		Data, Rest, 0, PayloadLen);
  %% non-control opcode when expecting control message or next fragment.
  websocket_data(State=#state{frag_state={nofin, _, _}}, Req, HandlerState, _Fin,
  		_Rsv=0, Opcode, _Ln, _Rest, _Data) when Opcode > 0, Opcode < 8 ->
  	websocket_close(State, Req, HandlerState, {error, badframe});
  %% If the first message fragment was incomplete, retry unmasking.
  websocket_data(State=#state{frag_state={nofin, Opcode}}, Req, HandlerState,
  		_Fin=0, _Rsv=0, Opcode, PayloadLen, Rest, Data) ->
  	websocket_before_unmask(
  		State#state{frag_state={nofin, Opcode}}, Req, HandlerState,
  		Data, Rest, 0, PayloadLen);
  %% if the opcode is zero and the fin flag is zero, unmask and await next.
  websocket_data(State=#state{frag_state={nofin, _Opcode, _Payloads}}, Req,
  		HandlerState, _Fin=0, _Rsv=0, _Opcode2=0, PayloadLen, Rest,
  		Data) ->
  	websocket_before_unmask(
  		State, Req, HandlerState, Data, Rest, 0, PayloadLen);
  %% when the last fragment is seen. Update the fragmentation status.
  websocket_data(State=#state{frag_state={nofin, Opcode, Payloads}}, Req,
  		HandlerState, _Fin=1, _Rsv=0, _Opcode=0, PayloadLen, Rest,
  		Data) ->
  	websocket_before_unmask(
  		State#state{frag_state={fin, Opcode, Payloads}},
  		Req, HandlerState, Data, Rest, 0, PayloadLen);
  %% control messages MUST NOT use 7+16 bits or 7+64 bits payload length prefixes
  websocket_data(State, Req, HandlerState, _Fin, _Rsv, Opcode, PayloadLen,
  		_Rest, _Data) when Opcode >= 8, PayloadLen > 125 ->
  	 websocket_close(State, Req, HandlerState, {error, badframe});
  %% unfragmented message. unmask and dispatch the message.
  websocket_data(State, Req, HandlerState, _Fin=1, _Rsv=0,
  		Opcode, PayloadLen, Rest, Data) ->
  	websocket_before_unmask(
  			State, Req, HandlerState, Data, Rest, Opcode, PayloadLen);
  %% Something was wrong with the frame. Close the connection.
  websocket_data(State, Req, HandlerState, _Fin, _Rsv, _Opcode,
  		_PayloadLen, _Rest, _Data) ->
  	websocket_close(State, Req, HandlerState, {error, badframe}).
  
  %% Routing depending on whether unmasking is needed.
  -spec websocket_before_unmask(#state{}, Req, any(), binary(),
  	binary(), opcode(), non_neg_integer() | undefined)
  	-> {ok, Req, cowboy_middleware:env()}
  	| {suspend, module(), atom(), [any()]}
  	when Req::cowboy_req:req().
  websocket_before_unmask(State, Req, HandlerState, Data,
  		Rest, Opcode, PayloadLen) ->
  	case PayloadLen of
  		N when N + 4 > byte_size(Rest); N =:= undefined ->
  			%% @todo We probably should allow limiting frame length.
  			handler_before_loop(State, Req, HandlerState, Data);
  		_N ->
  			<< MaskKey:32, Payload:PayloadLen/binary, Rest2/bits >> = Rest,
  			websocket_unmask(State, Req, HandlerState, Rest2,
  				Opcode, Payload, MaskKey)
  	end.
  
  %% Unmasking.
  -spec websocket_unmask(#state{}, Req, any(), binary(),
  	opcode(), binary(), mask_key())
  	-> {ok, Req, cowboy_middleware:env()}
  	| {suspend, module(), atom(), [any()]}
  	when Req::cowboy_req:req().
  websocket_unmask(State, Req, HandlerState, RemainingData,
  		Opcode, Payload, MaskKey) ->
  	websocket_unmask(State, Req, HandlerState, RemainingData,
  		Opcode, Payload, MaskKey, <<>>).
  
  -spec websocket_unmask(#state{}, Req, any(), binary(),
  	opcode(), binary(), mask_key(), binary())
  	-> {ok, Req, cowboy_middleware:env()}
  	| {suspend, module(), atom(), [any()]}
  	when Req::cowboy_req:req().
  websocket_unmask(State, Req, HandlerState, RemainingData,
  		Opcode, << O:32, Rest/bits >>, MaskKey, Acc) ->
  	T = O bxor MaskKey,
  	websocket_unmask(State, Req, HandlerState, RemainingData,
  		Opcode, Rest, MaskKey, << Acc/binary, T:32 >>);
  websocket_unmask(State, Req, HandlerState, RemainingData,
  		Opcode, << O:24 >>, MaskKey, Acc) ->
  	<< MaskKey2:24, _:8 >> = << MaskKey:32 >>,
  	T = O bxor MaskKey2,
  	websocket_dispatch(State, Req, HandlerState, RemainingData,
  		Opcode, << Acc/binary, T:24 >>);
  websocket_unmask(State, Req, HandlerState, RemainingData,
  		Opcode, << O:16 >>, MaskKey, Acc) ->
  	<< MaskKey2:16, _:16 >> = << MaskKey:32 >>,
  	T = O bxor MaskKey2,
  	websocket_dispatch(State, Req, HandlerState, RemainingData,
  		Opcode, << Acc/binary, T:16 >>);
  websocket_unmask(State, Req, HandlerState, RemainingData,
  		Opcode, << O:8 >>, MaskKey, Acc) ->
  	<< MaskKey2:8, _:24 >> = << MaskKey:32 >>,
  	T = O bxor MaskKey2,
  	websocket_dispatch(State, Req, HandlerState, RemainingData,
  		Opcode, << Acc/binary, T:8 >>);
  websocket_unmask(State, Req, HandlerState, RemainingData,
  		Opcode, <<>>, _MaskKey, Acc) ->
  	websocket_dispatch(State, Req, HandlerState, RemainingData,
  		Opcode, Acc).
  
  %% Dispatching.
  -spec websocket_dispatch(#state{}, Req, any(), binary(), opcode(), binary())
  	-> {ok, Req, cowboy_middleware:env()}
  	| {suspend, module(), atom(), [any()]}
  	when Req::cowboy_req:req().
  %% First frame of a fragmented message unmasked. Expect intermediate or last.
  websocket_dispatch(State=#state{frag_state={nofin, Opcode}}, Req, HandlerState,
  		RemainingData, 0, Payload) ->
  	websocket_data(State#state{frag_state={nofin, Opcode, Payload}},
  		Req, HandlerState, RemainingData);
  %% Intermediate frame of a fragmented message unmasked. Add payload to buffer.
  websocket_dispatch(State=#state{frag_state={nofin, Opcode, Payloads}}, Req,
  		HandlerState, RemainingData, 0, Payload) ->
  	websocket_data(State#state{frag_state={nofin, Opcode,
  		<<Payloads/binary, Payload/binary>>}}, Req, HandlerState,
  		RemainingData);
  %% Last frame of a fragmented message unmasked. Dispatch to handler.
  websocket_dispatch(State=#state{frag_state={fin, Opcode, Payloads}}, Req,
  		HandlerState, RemainingData, 0, Payload) ->
  	websocket_dispatch(State#state{frag_state=undefined}, Req, HandlerState,
  		RemainingData, Opcode, <<Payloads/binary, Payload/binary>>);
  %% Text frame.
  websocket_dispatch(State, Req, HandlerState, RemainingData, 1, Payload) ->
  	handler_call(State, Req, HandlerState, RemainingData,
  
negative.code: 	-> {ok, Req, cowboy_middleware:env()}
  	| {suspend, module(), atom(), [any()]}
  	when Req::cowboy_req:req().
  handler_loop(State=#state{socket=Socket, messages={OK, Closed, Error},
  		timeout_ref=TRef}, Req, HandlerState, SoFar) ->
  	receive
  		{OK, Socket, Data} ->
  			State2 = handler_loop_timeout(State),
  