anchor.diff:  unquote([], Acc) -> Acc;
   unquote([[$\\, C]|Tail], Acc) -> unquote(Tail, << Acc/binary, C >>);
   unquote([C|Tail], Acc) -> unquote(Tail, << Acc/binary, C >>).
  +
  +parameter() ->
  +	?SUCHTHAT({K, _, _, _},
  +		{token(), oneof([token(), quoted_string()]), ows(), ows()},
  +		K =/= <<"q">>).
  +
  +weight() ->
  +	frequency([
  +		{90, int(0, 1000)},
  +		{10, undefined}
  +	]).
  +
  +%% Helper function for weight's qvalue formatting.
  +qvalue_to_iodata(0) -> <<"0">>;
  +qvalue_to_iodata(Q) when Q < 10 -> [<<"0.00">>, integer_to_binary(Q)];
  +qvalue_to_iodata(Q) when Q < 100 -> [<<"0.0">>, integer_to_binary(Q)];
  +qvalue_to_iodata(Q) when Q < 1000 -> [<<"0.">>, integer_to_binary(Q)];
  +qvalue_to_iodata(1000) -> <<"1">>.
   -endif.
   
   %% @doc Parse the Accept header.
  
positive.code: 			ExpectedP = [case ?INLINE_LOWERCASE_BC(K) of
  				<<"charset">> -> {<<"charset">>, ?INLINE_LOWERCASE_BC(unquote(V))};
  				LowK -> {LowK, unquote(V)}
  			end || {K, V} <- P],
  			ResT =:= ?INLINE_LOWERCASE_BC(T)
  				andalso ResS =:= ?INLINE_LOWERCASE_BC(S)
  				andalso ResP =:= ExpectedP
  
negative.code: 
  accept_value(<<>>, Acc, T, S, P, Q, E, K, V) -> lists:reverse([{{T, S, lists:reverse(P)}, Q, lists:reverse([{K, V}|E])}|Acc]);
  accept_value(<< $,, R/bits >>, Acc, T, S, P, Q, E, K, V) -> media_range_list(R, [{{T, S, lists:reverse(P)}, Q, lists:reverse([{K, V}|E])}|Acc]);
  accept_value(<< $;, R/bits >>, Acc, T, S, P, Q, E, K, V) -> accept_before_ext(R, Acc, T, S, P, Q, [{K, V}|E]);
  accept_value(<< $\s, R/bits >>, Acc, T, S, P, Q, E, K, V) -> accept_before_semicolon(R, Acc, T, S, P, Q, [{K, V}|E]);
  accept_value(<< $\t, R/bits >>, Acc, T, S, P, Q, E, K, V) -> accept_before_semicolon(R, Acc, T, S, P, Q, [{K, V}|E]);
  accept_value(<< C, R/bits >>, Acc, T, S, P, Q, E, K, V) when ?IS_TOKEN(C) -> accept_value(R, Acc, T, S, P, Q, E, K, << V/binary, C >>).
  
  -ifdef(TEST).
  accept_ext() ->
  	oneof([token(), parameter()]).
  
  accept_params() ->
  	frequency([
  		{90, []},
  		{10, list(accept_ext())}
  	]).
  
  accept() ->
  	?LET({T, S, P, W, E},
  		{token(), token(), list(parameter()), weight(), accept_params()},
  		{T, S, P, W, E, iolist_to_binary([T, $/, S,
  			[[OWS1, $;, OWS2, K, $=, V] || {K, V, OWS1, OWS2} <- P],
  			case W of
  				undefined -> [];
  				_ -> [
  					[<<";q=">>, qvalue_to_iodata(W)],
  					[case Ext of
  						{K, V, OWS1, OWS2} -> [OWS1, $;, OWS2, K, $=, V];
  						K -> [$;, K]
  					end || Ext <- E]]
  			end])}
  	).
  
  prop_parse_accept() ->
  	?FORALL(L,
  		non_empty(list(accept())),
  		begin
  			<< _, Accept/binary >> = iolist_to_binary([[$,, A] || {_, _, _, _, _, A} <- L]),
  			ResL = parse_accept(Accept),
  			CheckedL = [begin
  				ExpectedP = [{?INLINE_LOWERCASE_BC(K), unquote(V)} || {K, V, _, _} <- P],
  				ExpectedE = [case Ext of
  					{K, V, _, _} -> {?INLINE_LOWERCASE_BC(K), unquote(V)};
  					K -> ?INLINE_LOWERCASE_BC(K)
  				end || Ext <- E],
  				ResT =:= ?INLINE_LOWERCASE_BC(T)
  					andalso ResS =:= ?INLINE_LOWERCASE_BC(S)
  					andalso ResP =:= ExpectedP
  					andalso (ResW =:= W orelse (W =:= undefined andalso ResW =:= 1000))
  					andalso ((W =:= undefined andalso ResE =:= []) orelse (W =/= undefined andalso ResE =:= ExpectedE))
  			end || {{T, S, P, W, E, _}, {{ResT, ResS, ResP}, ResW, ResE}} <- lists:zip(L, ResL)],
  			[true] =:= lists:usort(CheckedL)
  		end
  	).
  
  parse_accept_test_() ->
  	Tests = [
  		{<<>>, []},
  		{<<"   ">>, []},
  		{<<"audio/*; q=0.2, audio/basic">>, [
  			{{<<"audio">>, <<"*">>, []}, 200, []},
  			{{<<"audio">>, <<"basic">>, []}, 1000, []}
  