summaryrefslogtreecommitdiff
path: root/community/couchdb/build-fix.patch
diff options
context:
space:
mode:
Diffstat (limited to 'community/couchdb/build-fix.patch')
-rw-r--r--community/couchdb/build-fix.patch5568
1 files changed, 5568 insertions, 0 deletions
diff --git a/community/couchdb/build-fix.patch b/community/couchdb/build-fix.patch
new file mode 100644
index 000000000..d847b3cf2
--- /dev/null
+++ b/community/couchdb/build-fix.patch
@@ -0,0 +1,5568 @@
+diff -wbBur apache-couchdb-1.2.1/src/Makefile.am apache-couchdb-1.2.1.q/src/Makefile.am
+--- apache-couchdb-1.2.1/src/Makefile.am 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/Makefile.am 2013-03-22 15:28:06.836935634 +0400
+@@ -10,4 +10,4 @@
+ ## License for the specific language governing permissions and limitations under
+ ## the License.
+
+-SUBDIRS = couchdb ejson erlang-oauth etap ibrowse mochiweb snappy
++SUBDIRS = couchdb ejson erlang-oauth ibrowse mochiweb snappy
+diff -wbBur apache-couchdb-1.2.1/src/Makefile.in apache-couchdb-1.2.1.q/src/Makefile.in
+--- apache-couchdb-1.2.1/src/Makefile.in 2012-12-21 01:28:49.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/Makefile.in 2013-03-22 15:28:11.563602246 +0400
+@@ -267,7 +267,7 @@
+ version_release = @version_release@
+ version_revision = @version_revision@
+ version_stage = @version_stage@
+-SUBDIRS = couchdb ejson erlang-oauth etap ibrowse mochiweb snappy
++SUBDIRS = couchdb ejson erlang-oauth ibrowse mochiweb snappy
+ all: all-recursive
+
+ .SUFFIXES:
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochifmt.erl apache-couchdb-1.2.1.q/src/mochiweb/mochifmt.erl
+--- apache-couchdb-1.2.1/src/mochiweb/mochifmt.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochifmt.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -369,8 +369,8 @@
+ %%
+ %% Tests
+ %%
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
++-include_lib("eunit/include/eunit.hrl").
+
+ tokenize_test() ->
+ {?MODULE, [{raw, "ABC"}]} = tokenize("ABC"),
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochifmt_records.erl apache-couchdb-1.2.1.q/src/mochiweb/mochifmt_records.erl
+--- apache-couchdb-1.2.1/src/mochiweb/mochifmt_records.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochifmt_records.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -9,11 +9,15 @@
+ %% M:format("{0.bar}", [#rec{bar=foo}]).
+ %% foo
+
+--module(mochifmt_records, [Recs]).
++-module(mochifmt_records).
+ -author('bob@mochimedia.com').
+--export([get_value/2]).
++-export([new/1, get_value/3]).
+
+-get_value(Key, Rec) when is_tuple(Rec) and is_atom(element(1, Rec)) ->
++new([{_Rec, RecFields}]=Recs) when is_list(RecFields) ->
++ {?MODULE, Recs}.
++
++get_value(Key, Rec, {?MODULE, Recs})
++ when is_tuple(Rec) and is_atom(element(1, Rec)) ->
+ try begin
+ Atom = list_to_existing_atom(Key),
+ {_, Fields} = proplists:lookup(element(1, Rec), Recs),
+@@ -21,7 +25,7 @@
+ end
+ catch error:_ -> mochifmt:get_value(Key, Rec)
+ end;
+-get_value(Key, Args) ->
++get_value(Key, Args, {?MODULE, _Recs}) ->
+ mochifmt:get_value(Key, Args).
+
+ get_rec_index(Atom, [Atom | _], Index) ->
+@@ -33,6 +37,6 @@
+ %%
+ %% Tests
+ %%
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
++-include_lib("eunit/include/eunit.hrl").
+ -endif.
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochifmt_std.erl apache-couchdb-1.2.1.q/src/mochiweb/mochifmt_std.erl
+--- apache-couchdb-1.2.1/src/mochiweb/mochifmt_std.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochifmt_std.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -3,28 +3,31 @@
+
+ %% @doc Template module for a mochifmt formatter.
+
+--module(mochifmt_std, []).
++-module(mochifmt_std).
+ -author('bob@mochimedia.com').
+--export([format/2, get_value/2, format_field/2, get_field/2, convert_field/2]).
++-export([new/0, format/3, get_value/3, format_field/3, get_field/3, convert_field/3]).
+
+-format(Format, Args) ->
++new() ->
++ {?MODULE}.
++
++format(Format, Args, {?MODULE}=THIS) ->
+ mochifmt:format(Format, Args, THIS).
+
+-get_field(Key, Args) ->
++get_field(Key, Args, {?MODULE}=THIS) ->
+ mochifmt:get_field(Key, Args, THIS).
+
+-convert_field(Key, Args) ->
++convert_field(Key, Args, {?MODULE}) ->
+ mochifmt:convert_field(Key, Args).
+
+-get_value(Key, Args) ->
++get_value(Key, Args, {?MODULE}) ->
+ mochifmt:get_value(Key, Args).
+
+-format_field(Arg, Format) ->
++format_field(Arg, Format, {?MODULE}=THIS) ->
+ mochifmt:format_field(Arg, Format, THIS).
+
+ %%
+ %% Tests
+ %%
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
++-include_lib("eunit/include/eunit.hrl").
+ -endif.
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochiglobal.erl apache-couchdb-1.2.1.q/src/mochiweb/mochiglobal.erl
+--- apache-couchdb-1.2.1/src/mochiweb/mochiglobal.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochiglobal.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -30,7 +30,7 @@
+ put(_K, V, Mod) ->
+ Bin = compile(Mod, V),
+ code:purge(Mod),
+- code:load_binary(Mod, atom_to_list(Mod) ++ ".erl", Bin),
++ {module, Mod} = code:load_binary(Mod, atom_to_list(Mod) ++ ".erl", Bin),
+ ok.
+
+ -spec delete(atom()) -> boolean().
+@@ -77,8 +77,8 @@
+ %%
+ %% Tests
+ %%
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
++-include_lib("eunit/include/eunit.hrl").
+ get_put_delete_test() ->
+ K = '$$test$$mochiglobal',
+ delete(K),
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochihex.erl apache-couchdb-1.2.1.q/src/mochiweb/mochihex.erl
+--- apache-couchdb-1.2.1/src/mochiweb/mochihex.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochihex.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -8,9 +8,6 @@
+
+ -export([to_hex/1, to_bin/1, to_int/1, dehex/1, hexdigit/1]).
+
+-%% @type iolist() = [char() | binary() | iolist()]
+-%% @type iodata() = iolist() | binary()
+-
+ %% @spec to_hex(integer | iolist()) -> string()
+ %% @doc Convert an iolist to a hexadecimal string.
+ to_hex(0) ->
+@@ -68,8 +65,8 @@
+ %%
+ %% Tests
+ %%
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
++-include_lib("eunit/include/eunit.hrl").
+
+ to_hex_test() ->
+ "ff000ff1" = to_hex([255, 0, 15, 241]),
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochijson2.erl apache-couchdb-1.2.1.q/src/mochiweb/mochijson2.erl
+--- apache-couchdb-1.2.1/src/mochiweb/mochijson2.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochijson2.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -40,9 +40,9 @@
+ -module(mochijson2).
+ -author('bob@mochimedia.com').
+ -export([encoder/1, encode/1]).
+--export([decoder/1, decode/1]).
++-export([decoder/1, decode/1, decode/2]).
+
+-% This is a macro to placate syntax highlighters..
++%% This is a macro to placate syntax highlighters..
+ -define(Q, $\").
+ -define(ADV_COL(S, N), S#decoder{offset=N+S#decoder.offset,
+ column=N+S#decoder.column}).
+@@ -64,15 +64,14 @@
+ -define(IS_WHITESPACE(C),
+ (C =:= $\s orelse C =:= $\t orelse C =:= $\r orelse C =:= $\n)).
+
+-%% @type iolist() = [char() | binary() | iolist()]
+-%% @type iodata() = iolist() | binary()
+ %% @type json_string() = atom | binary()
+ %% @type json_number() = integer() | float()
+ %% @type json_array() = [json_term()]
+ %% @type json_object() = {struct, [{json_string(), json_term()}]}
++%% @type json_eep18_object() = {[{json_string(), json_term()}]}
+ %% @type json_iolist() = {json, iolist()}
+ %% @type json_term() = json_string() | json_number() | json_array() |
+-%% json_object() | json_iolist()
++%% json_object() | json_eep18_object() | json_iolist()
+
+ -record(encoder, {handler=null,
+ utf8=false}).
+@@ -102,6 +101,14 @@
+ State = parse_decoder_options(Options, #decoder{}),
+ fun (O) -> json_decode(O, State) end.
+
++%% @spec decode(iolist(), [{format, proplist | eep18 | struct}]) -> json_term()
++%% @doc Decode the given iolist to Erlang terms using the given object format
++%% for decoding, where proplist returns JSON objects as [{binary(), json_term()}]
++%% proplists, eep18 returns JSON objects as {[binary(), json_term()]}, and struct
++%% returns them as-is.
++decode(S, Options) ->
++ json_decode(S, parse_decoder_options(Options, #decoder{})).
++
+ %% @spec decode(iolist()) -> json_term()
+ %% @doc Decode the given iolist to Erlang terms.
+ decode(S) ->
+@@ -119,7 +126,10 @@
+ parse_decoder_options([], State) ->
+ State;
+ parse_decoder_options([{object_hook, Hook} | Rest], State) ->
+- parse_decoder_options(Rest, State#decoder{object_hook=Hook}).
++ parse_decoder_options(Rest, State#decoder{object_hook=Hook});
++parse_decoder_options([{format, Format} | Rest], State)
++ when Format =:= struct orelse Format =:= eep18 orelse Format =:= proplist ->
++ parse_decoder_options(Rest, State#decoder{object_hook=Format}).
+
+ json_encode(true, _State) ->
+ <<"true">>;
+@@ -139,6 +149,10 @@
+ json_encode_proplist(Props, State);
+ json_encode({struct, Props}, State) when is_list(Props) ->
+ json_encode_proplist(Props, State);
++json_encode({Props}, State) when is_list(Props) ->
++ json_encode_proplist(Props, State);
++json_encode({}, State) ->
++ json_encode_proplist([], State);
+ json_encode(Array, State) when is_list(Array) ->
+ json_encode_array(Array, State);
+ json_encode({array, Array}, State) when is_list(Array) ->
+@@ -318,8 +332,12 @@
+ decode_object(B, S1)
+ end.
+
+-make_object(V, #decoder{object_hook=null}) ->
++make_object(V, #decoder{object_hook=N}) when N =:= null orelse N =:= struct ->
+ V;
++make_object({struct, P}, #decoder{object_hook=eep18}) ->
++ {P};
++make_object({struct, P}, #decoder{object_hook=proplist}) ->
++ P;
+ make_object(V, #decoder{object_hook=Hook}) ->
+ Hook(V).
+
+@@ -559,8 +577,8 @@
+ %%
+ %% Tests
+ %%
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
++-include_lib("eunit/include/eunit.hrl").
+
+
+ %% testing constructs borrowed from the Yaws JSON implementation.
+@@ -838,12 +856,34 @@
+
+ handler_test() ->
+ ?assertEqual(
+- {'EXIT',{json_encode,{bad_term,{}}}},
+- catch encode({})),
+- F = fun ({}) -> [] end,
++ {'EXIT',{json_encode,{bad_term,{x,y}}}},
++ catch encode({x,y})),
++ F = fun ({x,y}) -> [] end,
+ ?assertEqual(
+ <<"[]">>,
+- iolist_to_binary((encoder([{handler, F}]))({}))),
++ iolist_to_binary((encoder([{handler, F}]))({x, y}))),
+ ok.
+
++encode_empty_test_() ->
++ [{A, ?_assertEqual(<<"{}">>, iolist_to_binary(encode(B)))}
++ || {A, B} <- [{"eep18 {}", {}},
++ {"eep18 {[]}", {[]}},
++ {"{struct, []}", {struct, []}}]].
++
++encode_test_() ->
++ P = [{<<"k">>, <<"v">>}],
++ JSON = iolist_to_binary(encode({struct, P})),
++ [{atom_to_list(F),
++ ?_assertEqual(JSON, iolist_to_binary(encode(decode(JSON, [{format, F}]))))}
++ || F <- [struct, eep18, proplist]].
++
++format_test_() ->
++ P = [{<<"k">>, <<"v">>}],
++ JSON = iolist_to_binary(encode({struct, P})),
++ [{atom_to_list(F),
++ ?_assertEqual(A, decode(JSON, [{format, F}]))}
++ || {F, A} <- [{struct, {struct, P}},
++ {eep18, {P}},
++ {proplist, P}]].
++
+ -endif.
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochijson.erl apache-couchdb-1.2.1.q/src/mochiweb/mochijson.erl
+--- apache-couchdb-1.2.1/src/mochiweb/mochijson.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochijson.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -15,8 +15,6 @@
+ -define(INC_COL(S), S#decoder{column=1+S#decoder.column}).
+ -define(INC_LINE(S), S#decoder{column=1, line=1+S#decoder.line}).
+
+-%% @type iolist() = [char() | binary() | iolist()]
+-%% @type iodata() = iolist() | binary()
+ %% @type json_string() = atom | string() | binary()
+ %% @type json_number() = integer() | float()
+ %% @type json_array() = {array, [json_term()]}
+@@ -406,8 +404,8 @@
+ %%
+ %% Tests
+ %%
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
++-include_lib("eunit/include/eunit.hrl").
+
+ %% testing constructs borrowed from the Yaws JSON implementation.
+
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochilists.erl apache-couchdb-1.2.1.q/src/mochiweb/mochilists.erl
+--- apache-couchdb-1.2.1/src/mochiweb/mochilists.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochilists.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -55,8 +55,8 @@
+ %%
+ %% Tests
+ %%
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
++-include_lib("eunit/include/eunit.hrl").
+
+ set_defaults_test() ->
+ ?assertEqual(
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochilogfile2.erl apache-couchdb-1.2.1.q/src/mochiweb/mochilogfile2.erl
+--- apache-couchdb-1.2.1/src/mochiweb/mochilogfile2.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochilogfile2.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -57,8 +57,8 @@
+ %%
+ %% Tests
+ %%
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
++-include_lib("eunit/include/eunit.hrl").
+ name_test() ->
+ D = mochitemp:mkdtemp(),
+ FileName = filename:join(D, "open_close_test.log"),
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochinum.erl apache-couchdb-1.2.1.q/src/mochiweb/mochinum.erl
+--- apache-couchdb-1.2.1/src/mochiweb/mochinum.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochinum.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -243,8 +243,8 @@
+ %%
+ %% Tests
+ %%
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
++-include_lib("eunit/include/eunit.hrl").
+
+ int_ceil_test() ->
+ ?assertEqual(1, int_ceil(0.0001)),
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochitemp.erl apache-couchdb-1.2.1.q/src/mochiweb/mochitemp.erl
+--- apache-couchdb-1.2.1/src/mochiweb/mochitemp.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochitemp.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -135,8 +135,9 @@
+ %%
+ %% Tests
+ %%
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
++-include_lib("eunit/include/eunit.hrl").
++
+ pushenv(L) ->
+ [{K, os:getenv(K)} || K <- L].
+ popenv(L) ->
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochiutf8.erl apache-couchdb-1.2.1.q/src/mochiweb/mochiutf8.erl
+--- apache-couchdb-1.2.1/src/mochiweb/mochiutf8.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochiutf8.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -5,8 +5,9 @@
+ %% invalid bytes.
+
+ -module(mochiutf8).
+--export([valid_utf8_bytes/1, codepoint_to_bytes/1, bytes_to_codepoints/1]).
+--export([bytes_foldl/3, codepoint_foldl/3, read_codepoint/1, len/1]).
++-export([valid_utf8_bytes/1, codepoint_to_bytes/1, codepoints_to_bytes/1]).
++-export([bytes_to_codepoints/1, bytes_foldl/3, codepoint_foldl/3]).
++-export([read_codepoint/1, len/1]).
+
+ %% External API
+
+@@ -192,8 +193,8 @@
+ %%
+ %% Tests
+ %%
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
++-include_lib("eunit/include/eunit.hrl").
+
+ binary_skip_bytes_test() ->
+ ?assertEqual(<<"foo">>,
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochiweb_acceptor.erl apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_acceptor.erl
+--- apache-couchdb-1.2.1/src/mochiweb/mochiweb_acceptor.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_acceptor.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -14,10 +14,10 @@
+ proc_lib:spawn_link(?MODULE, init, [Server, Listen, Loop]).
+
+ init(Server, Listen, Loop) ->
+- T1 = now(),
++ T1 = os:timestamp(),
+ case catch mochiweb_socket:accept(Listen) of
+ {ok, Socket} ->
+- gen_server:cast(Server, {accepted, self(), timer:now_diff(now(), T1)}),
++ gen_server:cast(Server, {accepted, self(), timer:now_diff(os:timestamp(), T1)}),
+ call_loop(Loop, Socket);
+ {error, closed} ->
+ exit(normal);
+@@ -35,6 +35,8 @@
+
+ call_loop({M, F}, Socket) ->
+ M:F(Socket);
++call_loop({M, F, [A1]}, Socket) ->
++ M:F(Socket, A1);
+ call_loop({M, F, A}, Socket) ->
+ erlang:apply(M, F, [Socket | A]);
+ call_loop(Loop, Socket) ->
+@@ -43,6 +45,6 @@
+ %%
+ %% Tests
+ %%
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
++-include_lib("eunit/include/eunit.hrl").
+ -endif.
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochiweb.app.src apache-couchdb-1.2.1.q/src/mochiweb/mochiweb.app.src
+--- apache-couchdb-1.2.1/src/mochiweb/mochiweb.app.src 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochiweb.app.src 2013-03-22 15:26:58.000000000 +0400
+@@ -1,9 +1,9 @@
+ %% This is generated from src/mochiweb.app.src
+ {application, mochiweb,
+ [{description, "MochiMedia Web Server"},
+- {vsn, "1.4.1"},
++ {vsn, "2.5.0"},
+ {modules, []},
+ {registered, []},
+- {mod, {mochiweb_app, []}},
+ {env, []},
+- {applications, [kernel, stdlib, crypto, inets]}]}.
++ {applications, [kernel, stdlib, crypto, inets, ssl, xmerl,
++ compiler, syntax_tools]}]}.
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochiweb_charref.erl apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_charref.erl
+--- apache-couchdb-1.2.1/src/mochiweb/mochiweb_charref.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_charref.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -1,17 +1,17 @@
+ %% @author Bob Ippolito <bob@mochimedia.com>
+ %% @copyright 2007 Mochi Media, Inc.
+
+-%% @doc Converts HTML 4 charrefs and entities to codepoints.
++%% @doc Converts HTML 5 charrefs and entities to codepoints (or lists of code points).
+ -module(mochiweb_charref).
+ -export([charref/1]).
+
+ %% External API.
+
+-%% @spec charref(S) -> integer() | undefined
+ %% @doc Convert a decimal charref, hex charref, or html entity to a unicode
+ %% codepoint, or return undefined on failure.
+ %% The input should not include an ampersand or semicolon.
+ %% charref("#38") = 38, charref("#x26") = 38, charref("amp") = 38.
++-spec charref(binary() | string()) -> integer() | [integer()] | undefined.
+ charref(B) when is_binary(B) ->
+ charref(binary_to_list(B));
+ charref([$#, C | L]) when C =:= $x orelse C =:= $X ->
+@@ -29,266 +29,2141 @@
+
+ %% Internal API.
+
+-entity("nbsp") -> 160;
+-entity("iexcl") -> 161;
+-entity("cent") -> 162;
+-entity("pound") -> 163;
+-entity("curren") -> 164;
+-entity("yen") -> 165;
+-entity("brvbar") -> 166;
+-entity("sect") -> 167;
+-entity("uml") -> 168;
+-entity("copy") -> 169;
+-entity("ordf") -> 170;
+-entity("laquo") -> 171;
+-entity("not") -> 172;
+-entity("shy") -> 173;
+-entity("reg") -> 174;
+-entity("macr") -> 175;
+-entity("deg") -> 176;
+-entity("plusmn") -> 177;
+-entity("sup2") -> 178;
+-entity("sup3") -> 179;
+-entity("acute") -> 180;
+-entity("micro") -> 181;
+-entity("para") -> 182;
+-entity("middot") -> 183;
+-entity("cedil") -> 184;
+-entity("sup1") -> 185;
+-entity("ordm") -> 186;
+-entity("raquo") -> 187;
+-entity("frac14") -> 188;
+-entity("frac12") -> 189;
+-entity("frac34") -> 190;
+-entity("iquest") -> 191;
+-entity("Agrave") -> 192;
+-entity("Aacute") -> 193;
+-entity("Acirc") -> 194;
+-entity("Atilde") -> 195;
+-entity("Auml") -> 196;
+-entity("Aring") -> 197;
+-entity("AElig") -> 198;
+-entity("Ccedil") -> 199;
+-entity("Egrave") -> 200;
+-entity("Eacute") -> 201;
+-entity("Ecirc") -> 202;
+-entity("Euml") -> 203;
+-entity("Igrave") -> 204;
+-entity("Iacute") -> 205;
+-entity("Icirc") -> 206;
+-entity("Iuml") -> 207;
+-entity("ETH") -> 208;
+-entity("Ntilde") -> 209;
+-entity("Ograve") -> 210;
+-entity("Oacute") -> 211;
+-entity("Ocirc") -> 212;
+-entity("Otilde") -> 213;
+-entity("Ouml") -> 214;
+-entity("times") -> 215;
+-entity("Oslash") -> 216;
+-entity("Ugrave") -> 217;
+-entity("Uacute") -> 218;
+-entity("Ucirc") -> 219;
+-entity("Uuml") -> 220;
+-entity("Yacute") -> 221;
+-entity("THORN") -> 222;
+-entity("szlig") -> 223;
+-entity("agrave") -> 224;
+-entity("aacute") -> 225;
+-entity("acirc") -> 226;
+-entity("atilde") -> 227;
+-entity("auml") -> 228;
+-entity("aring") -> 229;
+-entity("aelig") -> 230;
+-entity("ccedil") -> 231;
+-entity("egrave") -> 232;
+-entity("eacute") -> 233;
+-entity("ecirc") -> 234;
+-entity("euml") -> 235;
+-entity("igrave") -> 236;
+-entity("iacute") -> 237;
+-entity("icirc") -> 238;
+-entity("iuml") -> 239;
+-entity("eth") -> 240;
+-entity("ntilde") -> 241;
+-entity("ograve") -> 242;
+-entity("oacute") -> 243;
+-entity("ocirc") -> 244;
+-entity("otilde") -> 245;
+-entity("ouml") -> 246;
+-entity("divide") -> 247;
+-entity("oslash") -> 248;
+-entity("ugrave") -> 249;
+-entity("uacute") -> 250;
+-entity("ucirc") -> 251;
+-entity("uuml") -> 252;
+-entity("yacute") -> 253;
+-entity("thorn") -> 254;
+-entity("yuml") -> 255;
+-entity("fnof") -> 402;
+-entity("Alpha") -> 913;
+-entity("Beta") -> 914;
+-entity("Gamma") -> 915;
+-entity("Delta") -> 916;
+-entity("Epsilon") -> 917;
+-entity("Zeta") -> 918;
+-entity("Eta") -> 919;
+-entity("Theta") -> 920;
+-entity("Iota") -> 921;
+-entity("Kappa") -> 922;
+-entity("Lambda") -> 923;
+-entity("Mu") -> 924;
+-entity("Nu") -> 925;
+-entity("Xi") -> 926;
+-entity("Omicron") -> 927;
+-entity("Pi") -> 928;
+-entity("Rho") -> 929;
+-entity("Sigma") -> 931;
+-entity("Tau") -> 932;
+-entity("Upsilon") -> 933;
+-entity("Phi") -> 934;
+-entity("Chi") -> 935;
+-entity("Psi") -> 936;
+-entity("Omega") -> 937;
+-entity("alpha") -> 945;
+-entity("beta") -> 946;
+-entity("gamma") -> 947;
+-entity("delta") -> 948;
+-entity("epsilon") -> 949;
+-entity("zeta") -> 950;
+-entity("eta") -> 951;
+-entity("theta") -> 952;
+-entity("iota") -> 953;
+-entity("kappa") -> 954;
+-entity("lambda") -> 955;
+-entity("mu") -> 956;
+-entity("nu") -> 957;
+-entity("xi") -> 958;
+-entity("omicron") -> 959;
+-entity("pi") -> 960;
+-entity("rho") -> 961;
+-entity("sigmaf") -> 962;
+-entity("sigma") -> 963;
+-entity("tau") -> 964;
+-entity("upsilon") -> 965;
+-entity("phi") -> 966;
+-entity("chi") -> 967;
+-entity("psi") -> 968;
+-entity("omega") -> 969;
+-entity("thetasym") -> 977;
+-entity("upsih") -> 978;
+-entity("piv") -> 982;
+-entity("bull") -> 8226;
+-entity("hellip") -> 8230;
+-entity("prime") -> 8242;
+-entity("Prime") -> 8243;
+-entity("oline") -> 8254;
+-entity("frasl") -> 8260;
+-entity("weierp") -> 8472;
+-entity("image") -> 8465;
+-entity("real") -> 8476;
+-entity("trade") -> 8482;
+-entity("alefsym") -> 8501;
+-entity("larr") -> 8592;
+-entity("uarr") -> 8593;
+-entity("rarr") -> 8594;
+-entity("darr") -> 8595;
+-entity("harr") -> 8596;
+-entity("crarr") -> 8629;
+-entity("lArr") -> 8656;
+-entity("uArr") -> 8657;
+-entity("rArr") -> 8658;
+-entity("dArr") -> 8659;
+-entity("hArr") -> 8660;
+-entity("forall") -> 8704;
+-entity("part") -> 8706;
+-entity("exist") -> 8707;
+-entity("empty") -> 8709;
+-entity("nabla") -> 8711;
+-entity("isin") -> 8712;
+-entity("notin") -> 8713;
+-entity("ni") -> 8715;
+-entity("prod") -> 8719;
+-entity("sum") -> 8721;
+-entity("minus") -> 8722;
+-entity("lowast") -> 8727;
+-entity("radic") -> 8730;
+-entity("prop") -> 8733;
+-entity("infin") -> 8734;
+-entity("ang") -> 8736;
+-entity("and") -> 8743;
+-entity("or") -> 8744;
+-entity("cap") -> 8745;
+-entity("cup") -> 8746;
+-entity("int") -> 8747;
+-entity("there4") -> 8756;
+-entity("sim") -> 8764;
+-entity("cong") -> 8773;
+-entity("asymp") -> 8776;
+-entity("ne") -> 8800;
+-entity("equiv") -> 8801;
+-entity("le") -> 8804;
+-entity("ge") -> 8805;
+-entity("sub") -> 8834;
+-entity("sup") -> 8835;
+-entity("nsub") -> 8836;
+-entity("sube") -> 8838;
+-entity("supe") -> 8839;
+-entity("oplus") -> 8853;
+-entity("otimes") -> 8855;
+-entity("perp") -> 8869;
+-entity("sdot") -> 8901;
+-entity("lceil") -> 8968;
+-entity("rceil") -> 8969;
+-entity("lfloor") -> 8970;
+-entity("rfloor") -> 8971;
+-entity("lang") -> 9001;
+-entity("rang") -> 9002;
+-entity("loz") -> 9674;
+-entity("spades") -> 9824;
+-entity("clubs") -> 9827;
+-entity("hearts") -> 9829;
+-entity("diams") -> 9830;
+-entity("quot") -> 34;
+-entity("amp") -> 38;
+-entity("lt") -> 60;
+-entity("gt") -> 62;
+-entity("OElig") -> 338;
+-entity("oelig") -> 339;
+-entity("Scaron") -> 352;
+-entity("scaron") -> 353;
+-entity("Yuml") -> 376;
+-entity("circ") -> 710;
+-entity("tilde") -> 732;
+-entity("ensp") -> 8194;
+-entity("emsp") -> 8195;
+-entity("thinsp") -> 8201;
+-entity("zwnj") -> 8204;
+-entity("zwj") -> 8205;
+-entity("lrm") -> 8206;
+-entity("rlm") -> 8207;
+-entity("ndash") -> 8211;
+-entity("mdash") -> 8212;
+-entity("lsquo") -> 8216;
+-entity("rsquo") -> 8217;
+-entity("sbquo") -> 8218;
+-entity("ldquo") -> 8220;
+-entity("rdquo") -> 8221;
+-entity("bdquo") -> 8222;
+-entity("dagger") -> 8224;
+-entity("Dagger") -> 8225;
+-entity("permil") -> 8240;
+-entity("lsaquo") -> 8249;
+-entity("rsaquo") -> 8250;
+-entity("euro") -> 8364;
+-entity(_) -> undefined.
++%% [2011-10-14] Generated from:
++%% http://www.w3.org/TR/html5/named-character-references.html
+
++entity("AElig") -> 16#000C6;
++entity("AMP") -> 16#00026;
++entity("Aacute") -> 16#000C1;
++entity("Abreve") -> 16#00102;
++entity("Acirc") -> 16#000C2;
++entity("Acy") -> 16#00410;
++entity("Afr") -> 16#1D504;
++entity("Agrave") -> 16#000C0;
++entity("Alpha") -> 16#00391;
++entity("Amacr") -> 16#00100;
++entity("And") -> 16#02A53;
++entity("Aogon") -> 16#00104;
++entity("Aopf") -> 16#1D538;
++entity("ApplyFunction") -> 16#02061;
++entity("Aring") -> 16#000C5;
++entity("Ascr") -> 16#1D49C;
++entity("Assign") -> 16#02254;
++entity("Atilde") -> 16#000C3;
++entity("Auml") -> 16#000C4;
++entity("Backslash") -> 16#02216;
++entity("Barv") -> 16#02AE7;
++entity("Barwed") -> 16#02306;
++entity("Bcy") -> 16#00411;
++entity("Because") -> 16#02235;
++entity("Bernoullis") -> 16#0212C;
++entity("Beta") -> 16#00392;
++entity("Bfr") -> 16#1D505;
++entity("Bopf") -> 16#1D539;
++entity("Breve") -> 16#002D8;
++entity("Bscr") -> 16#0212C;
++entity("Bumpeq") -> 16#0224E;
++entity("CHcy") -> 16#00427;
++entity("COPY") -> 16#000A9;
++entity("Cacute") -> 16#00106;
++entity("Cap") -> 16#022D2;
++entity("CapitalDifferentialD") -> 16#02145;
++entity("Cayleys") -> 16#0212D;
++entity("Ccaron") -> 16#0010C;
++entity("Ccedil") -> 16#000C7;
++entity("Ccirc") -> 16#00108;
++entity("Cconint") -> 16#02230;
++entity("Cdot") -> 16#0010A;
++entity("Cedilla") -> 16#000B8;
++entity("CenterDot") -> 16#000B7;
++entity("Cfr") -> 16#0212D;
++entity("Chi") -> 16#003A7;
++entity("CircleDot") -> 16#02299;
++entity("CircleMinus") -> 16#02296;
++entity("CirclePlus") -> 16#02295;
++entity("CircleTimes") -> 16#02297;
++entity("ClockwiseContourIntegral") -> 16#02232;
++entity("CloseCurlyDoubleQuote") -> 16#0201D;
++entity("CloseCurlyQuote") -> 16#02019;
++entity("Colon") -> 16#02237;
++entity("Colone") -> 16#02A74;
++entity("Congruent") -> 16#02261;
++entity("Conint") -> 16#0222F;
++entity("ContourIntegral") -> 16#0222E;
++entity("Copf") -> 16#02102;
++entity("Coproduct") -> 16#02210;
++entity("CounterClockwiseContourIntegral") -> 16#02233;
++entity("Cross") -> 16#02A2F;
++entity("Cscr") -> 16#1D49E;
++entity("Cup") -> 16#022D3;
++entity("CupCap") -> 16#0224D;
++entity("DD") -> 16#02145;
++entity("DDotrahd") -> 16#02911;
++entity("DJcy") -> 16#00402;
++entity("DScy") -> 16#00405;
++entity("DZcy") -> 16#0040F;
++entity("Dagger") -> 16#02021;
++entity("Darr") -> 16#021A1;
++entity("Dashv") -> 16#02AE4;
++entity("Dcaron") -> 16#0010E;
++entity("Dcy") -> 16#00414;
++entity("Del") -> 16#02207;
++entity("Delta") -> 16#00394;
++entity("Dfr") -> 16#1D507;
++entity("DiacriticalAcute") -> 16#000B4;
++entity("DiacriticalDot") -> 16#002D9;
++entity("DiacriticalDoubleAcute") -> 16#002DD;
++entity("DiacriticalGrave") -> 16#00060;
++entity("DiacriticalTilde") -> 16#002DC;
++entity("Diamond") -> 16#022C4;
++entity("DifferentialD") -> 16#02146;
++entity("Dopf") -> 16#1D53B;
++entity("Dot") -> 16#000A8;
++entity("DotDot") -> 16#020DC;
++entity("DotEqual") -> 16#02250;
++entity("DoubleContourIntegral") -> 16#0222F;
++entity("DoubleDot") -> 16#000A8;
++entity("DoubleDownArrow") -> 16#021D3;
++entity("DoubleLeftArrow") -> 16#021D0;
++entity("DoubleLeftRightArrow") -> 16#021D4;
++entity("DoubleLeftTee") -> 16#02AE4;
++entity("DoubleLongLeftArrow") -> 16#027F8;
++entity("DoubleLongLeftRightArrow") -> 16#027FA;
++entity("DoubleLongRightArrow") -> 16#027F9;
++entity("DoubleRightArrow") -> 16#021D2;
++entity("DoubleRightTee") -> 16#022A8;
++entity("DoubleUpArrow") -> 16#021D1;
++entity("DoubleUpDownArrow") -> 16#021D5;
++entity("DoubleVerticalBar") -> 16#02225;
++entity("DownArrow") -> 16#02193;
++entity("DownArrowBar") -> 16#02913;
++entity("DownArrowUpArrow") -> 16#021F5;
++entity("DownBreve") -> 16#00311;
++entity("DownLeftRightVector") -> 16#02950;
++entity("DownLeftTeeVector") -> 16#0295E;
++entity("DownLeftVector") -> 16#021BD;
++entity("DownLeftVectorBar") -> 16#02956;
++entity("DownRightTeeVector") -> 16#0295F;
++entity("DownRightVector") -> 16#021C1;
++entity("DownRightVectorBar") -> 16#02957;
++entity("DownTee") -> 16#022A4;
++entity("DownTeeArrow") -> 16#021A7;
++entity("Downarrow") -> 16#021D3;
++entity("Dscr") -> 16#1D49F;
++entity("Dstrok") -> 16#00110;
++entity("ENG") -> 16#0014A;
++entity("ETH") -> 16#000D0;
++entity("Eacute") -> 16#000C9;
++entity("Ecaron") -> 16#0011A;
++entity("Ecirc") -> 16#000CA;
++entity("Ecy") -> 16#0042D;
++entity("Edot") -> 16#00116;
++entity("Efr") -> 16#1D508;
++entity("Egrave") -> 16#000C8;
++entity("Element") -> 16#02208;
++entity("Emacr") -> 16#00112;
++entity("EmptySmallSquare") -> 16#025FB;
++entity("EmptyVerySmallSquare") -> 16#025AB;
++entity("Eogon") -> 16#00118;
++entity("Eopf") -> 16#1D53C;
++entity("Epsilon") -> 16#00395;
++entity("Equal") -> 16#02A75;
++entity("EqualTilde") -> 16#02242;
++entity("Equilibrium") -> 16#021CC;
++entity("Escr") -> 16#02130;
++entity("Esim") -> 16#02A73;
++entity("Eta") -> 16#00397;
++entity("Euml") -> 16#000CB;
++entity("Exists") -> 16#02203;
++entity("ExponentialE") -> 16#02147;
++entity("Fcy") -> 16#00424;
++entity("Ffr") -> 16#1D509;
++entity("FilledSmallSquare") -> 16#025FC;
++entity("FilledVerySmallSquare") -> 16#025AA;
++entity("Fopf") -> 16#1D53D;
++entity("ForAll") -> 16#02200;
++entity("Fouriertrf") -> 16#02131;
++entity("Fscr") -> 16#02131;
++entity("GJcy") -> 16#00403;
++entity("GT") -> 16#0003E;
++entity("Gamma") -> 16#00393;
++entity("Gammad") -> 16#003DC;
++entity("Gbreve") -> 16#0011E;
++entity("Gcedil") -> 16#00122;
++entity("Gcirc") -> 16#0011C;
++entity("Gcy") -> 16#00413;
++entity("Gdot") -> 16#00120;
++entity("Gfr") -> 16#1D50A;
++entity("Gg") -> 16#022D9;
++entity("Gopf") -> 16#1D53E;
++entity("GreaterEqual") -> 16#02265;
++entity("GreaterEqualLess") -> 16#022DB;
++entity("GreaterFullEqual") -> 16#02267;
++entity("GreaterGreater") -> 16#02AA2;
++entity("GreaterLess") -> 16#02277;
++entity("GreaterSlantEqual") -> 16#02A7E;
++entity("GreaterTilde") -> 16#02273;
++entity("Gscr") -> 16#1D4A2;
++entity("Gt") -> 16#0226B;
++entity("HARDcy") -> 16#0042A;
++entity("Hacek") -> 16#002C7;
++entity("Hat") -> 16#0005E;
++entity("Hcirc") -> 16#00124;
++entity("Hfr") -> 16#0210C;
++entity("HilbertSpace") -> 16#0210B;
++entity("Hopf") -> 16#0210D;
++entity("HorizontalLine") -> 16#02500;
++entity("Hscr") -> 16#0210B;
++entity("Hstrok") -> 16#00126;
++entity("HumpDownHump") -> 16#0224E;
++entity("HumpEqual") -> 16#0224F;
++entity("IEcy") -> 16#00415;
++entity("IJlig") -> 16#00132;
++entity("IOcy") -> 16#00401;
++entity("Iacute") -> 16#000CD;
++entity("Icirc") -> 16#000CE;
++entity("Icy") -> 16#00418;
++entity("Idot") -> 16#00130;
++entity("Ifr") -> 16#02111;
++entity("Igrave") -> 16#000CC;
++entity("Im") -> 16#02111;
++entity("Imacr") -> 16#0012A;
++entity("ImaginaryI") -> 16#02148;
++entity("Implies") -> 16#021D2;
++entity("Int") -> 16#0222C;
++entity("Integral") -> 16#0222B;
++entity("Intersection") -> 16#022C2;
++entity("InvisibleComma") -> 16#02063;
++entity("InvisibleTimes") -> 16#02062;
++entity("Iogon") -> 16#0012E;
++entity("Iopf") -> 16#1D540;
++entity("Iota") -> 16#00399;
++entity("Iscr") -> 16#02110;
++entity("Itilde") -> 16#00128;
++entity("Iukcy") -> 16#00406;
++entity("Iuml") -> 16#000CF;
++entity("Jcirc") -> 16#00134;
++entity("Jcy") -> 16#00419;
++entity("Jfr") -> 16#1D50D;
++entity("Jopf") -> 16#1D541;
++entity("Jscr") -> 16#1D4A5;
++entity("Jsercy") -> 16#00408;
++entity("Jukcy") -> 16#00404;
++entity("KHcy") -> 16#00425;
++entity("KJcy") -> 16#0040C;
++entity("Kappa") -> 16#0039A;
++entity("Kcedil") -> 16#00136;
++entity("Kcy") -> 16#0041A;
++entity("Kfr") -> 16#1D50E;
++entity("Kopf") -> 16#1D542;
++entity("Kscr") -> 16#1D4A6;
++entity("LJcy") -> 16#00409;
++entity("LT") -> 16#0003C;
++entity("Lacute") -> 16#00139;
++entity("Lambda") -> 16#0039B;
++entity("Lang") -> 16#027EA;
++entity("Laplacetrf") -> 16#02112;
++entity("Larr") -> 16#0219E;
++entity("Lcaron") -> 16#0013D;
++entity("Lcedil") -> 16#0013B;
++entity("Lcy") -> 16#0041B;
++entity("LeftAngleBracket") -> 16#027E8;
++entity("LeftArrow") -> 16#02190;
++entity("LeftArrowBar") -> 16#021E4;
++entity("LeftArrowRightArrow") -> 16#021C6;
++entity("LeftCeiling") -> 16#02308;
++entity("LeftDoubleBracket") -> 16#027E6;
++entity("LeftDownTeeVector") -> 16#02961;
++entity("LeftDownVector") -> 16#021C3;
++entity("LeftDownVectorBar") -> 16#02959;
++entity("LeftFloor") -> 16#0230A;
++entity("LeftRightArrow") -> 16#02194;
++entity("LeftRightVector") -> 16#0294E;
++entity("LeftTee") -> 16#022A3;
++entity("LeftTeeArrow") -> 16#021A4;
++entity("LeftTeeVector") -> 16#0295A;
++entity("LeftTriangle") -> 16#022B2;
++entity("LeftTriangleBar") -> 16#029CF;
++entity("LeftTriangleEqual") -> 16#022B4;
++entity("LeftUpDownVector") -> 16#02951;
++entity("LeftUpTeeVector") -> 16#02960;
++entity("LeftUpVector") -> 16#021BF;
++entity("LeftUpVectorBar") -> 16#02958;
++entity("LeftVector") -> 16#021BC;
++entity("LeftVectorBar") -> 16#02952;
++entity("Leftarrow") -> 16#021D0;
++entity("Leftrightarrow") -> 16#021D4;
++entity("LessEqualGreater") -> 16#022DA;
++entity("LessFullEqual") -> 16#02266;
++entity("LessGreater") -> 16#02276;
++entity("LessLess") -> 16#02AA1;
++entity("LessSlantEqual") -> 16#02A7D;
++entity("LessTilde") -> 16#02272;
++entity("Lfr") -> 16#1D50F;
++entity("Ll") -> 16#022D8;
++entity("Lleftarrow") -> 16#021DA;
++entity("Lmidot") -> 16#0013F;
++entity("LongLeftArrow") -> 16#027F5;
++entity("LongLeftRightArrow") -> 16#027F7;
++entity("LongRightArrow") -> 16#027F6;
++entity("Longleftarrow") -> 16#027F8;
++entity("Longleftrightarrow") -> 16#027FA;
++entity("Longrightarrow") -> 16#027F9;
++entity("Lopf") -> 16#1D543;
++entity("LowerLeftArrow") -> 16#02199;
++entity("LowerRightArrow") -> 16#02198;
++entity("Lscr") -> 16#02112;
++entity("Lsh") -> 16#021B0;
++entity("Lstrok") -> 16#00141;
++entity("Lt") -> 16#0226A;
++entity("Map") -> 16#02905;
++entity("Mcy") -> 16#0041C;
++entity("MediumSpace") -> 16#0205F;
++entity("Mellintrf") -> 16#02133;
++entity("Mfr") -> 16#1D510;
++entity("MinusPlus") -> 16#02213;
++entity("Mopf") -> 16#1D544;
++entity("Mscr") -> 16#02133;
++entity("Mu") -> 16#0039C;
++entity("NJcy") -> 16#0040A;
++entity("Nacute") -> 16#00143;
++entity("Ncaron") -> 16#00147;
++entity("Ncedil") -> 16#00145;
++entity("Ncy") -> 16#0041D;
++entity("NegativeMediumSpace") -> 16#0200B;
++entity("NegativeThickSpace") -> 16#0200B;
++entity("NegativeThinSpace") -> 16#0200B;
++entity("NegativeVeryThinSpace") -> 16#0200B;
++entity("NestedGreaterGreater") -> 16#0226B;
++entity("NestedLessLess") -> 16#0226A;
++entity("NewLine") -> 16#0000A;
++entity("Nfr") -> 16#1D511;
++entity("NoBreak") -> 16#02060;
++entity("NonBreakingSpace") -> 16#000A0;
++entity("Nopf") -> 16#02115;
++entity("Not") -> 16#02AEC;
++entity("NotCongruent") -> 16#02262;
++entity("NotCupCap") -> 16#0226D;
++entity("NotDoubleVerticalBar") -> 16#02226;
++entity("NotElement") -> 16#02209;
++entity("NotEqual") -> 16#02260;
++entity("NotEqualTilde") -> [16#02242, 16#00338];
++entity("NotExists") -> 16#02204;
++entity("NotGreater") -> 16#0226F;
++entity("NotGreaterEqual") -> 16#02271;
++entity("NotGreaterFullEqual") -> [16#02267, 16#00338];
++entity("NotGreaterGreater") -> [16#0226B, 16#00338];
++entity("NotGreaterLess") -> 16#02279;
++entity("NotGreaterSlantEqual") -> [16#02A7E, 16#00338];
++entity("NotGreaterTilde") -> 16#02275;
++entity("NotHumpDownHump") -> [16#0224E, 16#00338];
++entity("NotHumpEqual") -> [16#0224F, 16#00338];
++entity("NotLeftTriangle") -> 16#022EA;
++entity("NotLeftTriangleBar") -> [16#029CF, 16#00338];
++entity("NotLeftTriangleEqual") -> 16#022EC;
++entity("NotLess") -> 16#0226E;
++entity("NotLessEqual") -> 16#02270;
++entity("NotLessGreater") -> 16#02278;
++entity("NotLessLess") -> [16#0226A, 16#00338];
++entity("NotLessSlantEqual") -> [16#02A7D, 16#00338];
++entity("NotLessTilde") -> 16#02274;
++entity("NotNestedGreaterGreater") -> [16#02AA2, 16#00338];
++entity("NotNestedLessLess") -> [16#02AA1, 16#00338];
++entity("NotPrecedes") -> 16#02280;
++entity("NotPrecedesEqual") -> [16#02AAF, 16#00338];
++entity("NotPrecedesSlantEqual") -> 16#022E0;
++entity("NotReverseElement") -> 16#0220C;
++entity("NotRightTriangle") -> 16#022EB;
++entity("NotRightTriangleBar") -> [16#029D0, 16#00338];
++entity("NotRightTriangleEqual") -> 16#022ED;
++entity("NotSquareSubset") -> [16#0228F, 16#00338];
++entity("NotSquareSubsetEqual") -> 16#022E2;
++entity("NotSquareSuperset") -> [16#02290, 16#00338];
++entity("NotSquareSupersetEqual") -> 16#022E3;
++entity("NotSubset") -> [16#02282, 16#020D2];
++entity("NotSubsetEqual") -> 16#02288;
++entity("NotSucceeds") -> 16#02281;
++entity("NotSucceedsEqual") -> [16#02AB0, 16#00338];
++entity("NotSucceedsSlantEqual") -> 16#022E1;
++entity("NotSucceedsTilde") -> [16#0227F, 16#00338];
++entity("NotSuperset") -> [16#02283, 16#020D2];
++entity("NotSupersetEqual") -> 16#02289;
++entity("NotTilde") -> 16#02241;
++entity("NotTildeEqual") -> 16#02244;
++entity("NotTildeFullEqual") -> 16#02247;
++entity("NotTildeTilde") -> 16#02249;
++entity("NotVerticalBar") -> 16#02224;
++entity("Nscr") -> 16#1D4A9;
++entity("Ntilde") -> 16#000D1;
++entity("Nu") -> 16#0039D;
++entity("OElig") -> 16#00152;
++entity("Oacute") -> 16#000D3;
++entity("Ocirc") -> 16#000D4;
++entity("Ocy") -> 16#0041E;
++entity("Odblac") -> 16#00150;
++entity("Ofr") -> 16#1D512;
++entity("Ograve") -> 16#000D2;
++entity("Omacr") -> 16#0014C;
++entity("Omega") -> 16#003A9;
++entity("Omicron") -> 16#0039F;
++entity("Oopf") -> 16#1D546;
++entity("OpenCurlyDoubleQuote") -> 16#0201C;
++entity("OpenCurlyQuote") -> 16#02018;
++entity("Or") -> 16#02A54;
++entity("Oscr") -> 16#1D4AA;
++entity("Oslash") -> 16#000D8;
++entity("Otilde") -> 16#000D5;
++entity("Otimes") -> 16#02A37;
++entity("Ouml") -> 16#000D6;
++entity("OverBar") -> 16#0203E;
++entity("OverBrace") -> 16#023DE;
++entity("OverBracket") -> 16#023B4;
++entity("OverParenthesis") -> 16#023DC;
++entity("PartialD") -> 16#02202;
++entity("Pcy") -> 16#0041F;
++entity("Pfr") -> 16#1D513;
++entity("Phi") -> 16#003A6;
++entity("Pi") -> 16#003A0;
++entity("PlusMinus") -> 16#000B1;
++entity("Poincareplane") -> 16#0210C;
++entity("Popf") -> 16#02119;
++entity("Pr") -> 16#02ABB;
++entity("Precedes") -> 16#0227A;
++entity("PrecedesEqual") -> 16#02AAF;
++entity("PrecedesSlantEqual") -> 16#0227C;
++entity("PrecedesTilde") -> 16#0227E;
++entity("Prime") -> 16#02033;
++entity("Product") -> 16#0220F;
++entity("Proportion") -> 16#02237;
++entity("Proportional") -> 16#0221D;
++entity("Pscr") -> 16#1D4AB;
++entity("Psi") -> 16#003A8;
++entity("QUOT") -> 16#00022;
++entity("Qfr") -> 16#1D514;
++entity("Qopf") -> 16#0211A;
++entity("Qscr") -> 16#1D4AC;
++entity("RBarr") -> 16#02910;
++entity("REG") -> 16#000AE;
++entity("Racute") -> 16#00154;
++entity("Rang") -> 16#027EB;
++entity("Rarr") -> 16#021A0;
++entity("Rarrtl") -> 16#02916;
++entity("Rcaron") -> 16#00158;
++entity("Rcedil") -> 16#00156;
++entity("Rcy") -> 16#00420;
++entity("Re") -> 16#0211C;
++entity("ReverseElement") -> 16#0220B;
++entity("ReverseEquilibrium") -> 16#021CB;
++entity("ReverseUpEquilibrium") -> 16#0296F;
++entity("Rfr") -> 16#0211C;
++entity("Rho") -> 16#003A1;
++entity("RightAngleBracket") -> 16#027E9;
++entity("RightArrow") -> 16#02192;
++entity("RightArrowBar") -> 16#021E5;
++entity("RightArrowLeftArrow") -> 16#021C4;
++entity("RightCeiling") -> 16#02309;
++entity("RightDoubleBracket") -> 16#027E7;
++entity("RightDownTeeVector") -> 16#0295D;
++entity("RightDownVector") -> 16#021C2;
++entity("RightDownVectorBar") -> 16#02955;
++entity("RightFloor") -> 16#0230B;
++entity("RightTee") -> 16#022A2;
++entity("RightTeeArrow") -> 16#021A6;
++entity("RightTeeVector") -> 16#0295B;
++entity("RightTriangle") -> 16#022B3;
++entity("RightTriangleBar") -> 16#029D0;
++entity("RightTriangleEqual") -> 16#022B5;
++entity("RightUpDownVector") -> 16#0294F;
++entity("RightUpTeeVector") -> 16#0295C;
++entity("RightUpVector") -> 16#021BE;
++entity("RightUpVectorBar") -> 16#02954;
++entity("RightVector") -> 16#021C0;
++entity("RightVectorBar") -> 16#02953;
++entity("Rightarrow") -> 16#021D2;
++entity("Ropf") -> 16#0211D;
++entity("RoundImplies") -> 16#02970;
++entity("Rrightarrow") -> 16#021DB;
++entity("Rscr") -> 16#0211B;
++entity("Rsh") -> 16#021B1;
++entity("RuleDelayed") -> 16#029F4;
++entity("SHCHcy") -> 16#00429;
++entity("SHcy") -> 16#00428;
++entity("SOFTcy") -> 16#0042C;
++entity("Sacute") -> 16#0015A;
++entity("Sc") -> 16#02ABC;
++entity("Scaron") -> 16#00160;
++entity("Scedil") -> 16#0015E;
++entity("Scirc") -> 16#0015C;
++entity("Scy") -> 16#00421;
++entity("Sfr") -> 16#1D516;
++entity("ShortDownArrow") -> 16#02193;
++entity("ShortLeftArrow") -> 16#02190;
++entity("ShortRightArrow") -> 16#02192;
++entity("ShortUpArrow") -> 16#02191;
++entity("Sigma") -> 16#003A3;
++entity("SmallCircle") -> 16#02218;
++entity("Sopf") -> 16#1D54A;
++entity("Sqrt") -> 16#0221A;
++entity("Square") -> 16#025A1;
++entity("SquareIntersection") -> 16#02293;
++entity("SquareSubset") -> 16#0228F;
++entity("SquareSubsetEqual") -> 16#02291;
++entity("SquareSuperset") -> 16#02290;
++entity("SquareSupersetEqual") -> 16#02292;
++entity("SquareUnion") -> 16#02294;
++entity("Sscr") -> 16#1D4AE;
++entity("Star") -> 16#022C6;
++entity("Sub") -> 16#022D0;
++entity("Subset") -> 16#022D0;
++entity("SubsetEqual") -> 16#02286;
++entity("Succeeds") -> 16#0227B;
++entity("SucceedsEqual") -> 16#02AB0;
++entity("SucceedsSlantEqual") -> 16#0227D;
++entity("SucceedsTilde") -> 16#0227F;
++entity("SuchThat") -> 16#0220B;
++entity("Sum") -> 16#02211;
++entity("Sup") -> 16#022D1;
++entity("Superset") -> 16#02283;
++entity("SupersetEqual") -> 16#02287;
++entity("Supset") -> 16#022D1;
++entity("THORN") -> 16#000DE;
++entity("TRADE") -> 16#02122;
++entity("TSHcy") -> 16#0040B;
++entity("TScy") -> 16#00426;
++entity("Tab") -> 16#00009;
++entity("Tau") -> 16#003A4;
++entity("Tcaron") -> 16#00164;
++entity("Tcedil") -> 16#00162;
++entity("Tcy") -> 16#00422;
++entity("Tfr") -> 16#1D517;
++entity("Therefore") -> 16#02234;
++entity("Theta") -> 16#00398;
++entity("ThickSpace") -> [16#0205F, 16#0200A];
++entity("ThinSpace") -> 16#02009;
++entity("Tilde") -> 16#0223C;
++entity("TildeEqual") -> 16#02243;
++entity("TildeFullEqual") -> 16#02245;
++entity("TildeTilde") -> 16#02248;
++entity("Topf") -> 16#1D54B;
++entity("TripleDot") -> 16#020DB;
++entity("Tscr") -> 16#1D4AF;
++entity("Tstrok") -> 16#00166;
++entity("Uacute") -> 16#000DA;
++entity("Uarr") -> 16#0219F;
++entity("Uarrocir") -> 16#02949;
++entity("Ubrcy") -> 16#0040E;
++entity("Ubreve") -> 16#0016C;
++entity("Ucirc") -> 16#000DB;
++entity("Ucy") -> 16#00423;
++entity("Udblac") -> 16#00170;
++entity("Ufr") -> 16#1D518;
++entity("Ugrave") -> 16#000D9;
++entity("Umacr") -> 16#0016A;
++entity("UnderBar") -> 16#0005F;
++entity("UnderBrace") -> 16#023DF;
++entity("UnderBracket") -> 16#023B5;
++entity("UnderParenthesis") -> 16#023DD;
++entity("Union") -> 16#022C3;
++entity("UnionPlus") -> 16#0228E;
++entity("Uogon") -> 16#00172;
++entity("Uopf") -> 16#1D54C;
++entity("UpArrow") -> 16#02191;
++entity("UpArrowBar") -> 16#02912;
++entity("UpArrowDownArrow") -> 16#021C5;
++entity("UpDownArrow") -> 16#02195;
++entity("UpEquilibrium") -> 16#0296E;
++entity("UpTee") -> 16#022A5;
++entity("UpTeeArrow") -> 16#021A5;
++entity("Uparrow") -> 16#021D1;
++entity("Updownarrow") -> 16#021D5;
++entity("UpperLeftArrow") -> 16#02196;
++entity("UpperRightArrow") -> 16#02197;
++entity("Upsi") -> 16#003D2;
++entity("Upsilon") -> 16#003A5;
++entity("Uring") -> 16#0016E;
++entity("Uscr") -> 16#1D4B0;
++entity("Utilde") -> 16#00168;
++entity("Uuml") -> 16#000DC;
++entity("VDash") -> 16#022AB;
++entity("Vbar") -> 16#02AEB;
++entity("Vcy") -> 16#00412;
++entity("Vdash") -> 16#022A9;
++entity("Vdashl") -> 16#02AE6;
++entity("Vee") -> 16#022C1;
++entity("Verbar") -> 16#02016;
++entity("Vert") -> 16#02016;
++entity("VerticalBar") -> 16#02223;
++entity("VerticalLine") -> 16#0007C;
++entity("VerticalSeparator") -> 16#02758;
++entity("VerticalTilde") -> 16#02240;
++entity("VeryThinSpace") -> 16#0200A;
++entity("Vfr") -> 16#1D519;
++entity("Vopf") -> 16#1D54D;
++entity("Vscr") -> 16#1D4B1;
++entity("Vvdash") -> 16#022AA;
++entity("Wcirc") -> 16#00174;
++entity("Wedge") -> 16#022C0;
++entity("Wfr") -> 16#1D51A;
++entity("Wopf") -> 16#1D54E;
++entity("Wscr") -> 16#1D4B2;
++entity("Xfr") -> 16#1D51B;
++entity("Xi") -> 16#0039E;
++entity("Xopf") -> 16#1D54F;
++entity("Xscr") -> 16#1D4B3;
++entity("YAcy") -> 16#0042F;
++entity("YIcy") -> 16#00407;
++entity("YUcy") -> 16#0042E;
++entity("Yacute") -> 16#000DD;
++entity("Ycirc") -> 16#00176;
++entity("Ycy") -> 16#0042B;
++entity("Yfr") -> 16#1D51C;
++entity("Yopf") -> 16#1D550;
++entity("Yscr") -> 16#1D4B4;
++entity("Yuml") -> 16#00178;
++entity("ZHcy") -> 16#00416;
++entity("Zacute") -> 16#00179;
++entity("Zcaron") -> 16#0017D;
++entity("Zcy") -> 16#00417;
++entity("Zdot") -> 16#0017B;
++entity("ZeroWidthSpace") -> 16#0200B;
++entity("Zeta") -> 16#00396;
++entity("Zfr") -> 16#02128;
++entity("Zopf") -> 16#02124;
++entity("Zscr") -> 16#1D4B5;
++entity("aacute") -> 16#000E1;
++entity("abreve") -> 16#00103;
++entity("ac") -> 16#0223E;
++entity("acE") -> [16#0223E, 16#00333];
++entity("acd") -> 16#0223F;
++entity("acirc") -> 16#000E2;
++entity("acute") -> 16#000B4;
++entity("acy") -> 16#00430;
++entity("aelig") -> 16#000E6;
++entity("af") -> 16#02061;
++entity("afr") -> 16#1D51E;
++entity("agrave") -> 16#000E0;
++entity("alefsym") -> 16#02135;
++entity("aleph") -> 16#02135;
++entity("alpha") -> 16#003B1;
++entity("amacr") -> 16#00101;
++entity("amalg") -> 16#02A3F;
++entity("amp") -> 16#00026;
++entity("and") -> 16#02227;
++entity("andand") -> 16#02A55;
++entity("andd") -> 16#02A5C;
++entity("andslope") -> 16#02A58;
++entity("andv") -> 16#02A5A;
++entity("ang") -> 16#02220;
++entity("ange") -> 16#029A4;
++entity("angle") -> 16#02220;
++entity("angmsd") -> 16#02221;
++entity("angmsdaa") -> 16#029A8;
++entity("angmsdab") -> 16#029A9;
++entity("angmsdac") -> 16#029AA;
++entity("angmsdad") -> 16#029AB;
++entity("angmsdae") -> 16#029AC;
++entity("angmsdaf") -> 16#029AD;
++entity("angmsdag") -> 16#029AE;
++entity("angmsdah") -> 16#029AF;
++entity("angrt") -> 16#0221F;
++entity("angrtvb") -> 16#022BE;
++entity("angrtvbd") -> 16#0299D;
++entity("angsph") -> 16#02222;
++entity("angst") -> 16#000C5;
++entity("angzarr") -> 16#0237C;
++entity("aogon") -> 16#00105;
++entity("aopf") -> 16#1D552;
++entity("ap") -> 16#02248;
++entity("apE") -> 16#02A70;
++entity("apacir") -> 16#02A6F;
++entity("ape") -> 16#0224A;
++entity("apid") -> 16#0224B;
++entity("apos") -> 16#00027;
++entity("approx") -> 16#02248;
++entity("approxeq") -> 16#0224A;
++entity("aring") -> 16#000E5;
++entity("ascr") -> 16#1D4B6;
++entity("ast") -> 16#0002A;
++entity("asymp") -> 16#02248;
++entity("asympeq") -> 16#0224D;
++entity("atilde") -> 16#000E3;
++entity("auml") -> 16#000E4;
++entity("awconint") -> 16#02233;
++entity("awint") -> 16#02A11;
++entity("bNot") -> 16#02AED;
++entity("backcong") -> 16#0224C;
++entity("backepsilon") -> 16#003F6;
++entity("backprime") -> 16#02035;
++entity("backsim") -> 16#0223D;
++entity("backsimeq") -> 16#022CD;
++entity("barvee") -> 16#022BD;
++entity("barwed") -> 16#02305;
++entity("barwedge") -> 16#02305;
++entity("bbrk") -> 16#023B5;
++entity("bbrktbrk") -> 16#023B6;
++entity("bcong") -> 16#0224C;
++entity("bcy") -> 16#00431;
++entity("bdquo") -> 16#0201E;
++entity("becaus") -> 16#02235;
++entity("because") -> 16#02235;
++entity("bemptyv") -> 16#029B0;
++entity("bepsi") -> 16#003F6;
++entity("bernou") -> 16#0212C;
++entity("beta") -> 16#003B2;
++entity("beth") -> 16#02136;
++entity("between") -> 16#0226C;
++entity("bfr") -> 16#1D51F;
++entity("bigcap") -> 16#022C2;
++entity("bigcirc") -> 16#025EF;
++entity("bigcup") -> 16#022C3;
++entity("bigodot") -> 16#02A00;
++entity("bigoplus") -> 16#02A01;
++entity("bigotimes") -> 16#02A02;
++entity("bigsqcup") -> 16#02A06;
++entity("bigstar") -> 16#02605;
++entity("bigtriangledown") -> 16#025BD;
++entity("bigtriangleup") -> 16#025B3;
++entity("biguplus") -> 16#02A04;
++entity("bigvee") -> 16#022C1;
++entity("bigwedge") -> 16#022C0;
++entity("bkarow") -> 16#0290D;
++entity("blacklozenge") -> 16#029EB;
++entity("blacksquare") -> 16#025AA;
++entity("blacktriangle") -> 16#025B4;
++entity("blacktriangledown") -> 16#025BE;
++entity("blacktriangleleft") -> 16#025C2;
++entity("blacktriangleright") -> 16#025B8;
++entity("blank") -> 16#02423;
++entity("blk12") -> 16#02592;
++entity("blk14") -> 16#02591;
++entity("blk34") -> 16#02593;
++entity("block") -> 16#02588;
++entity("bne") -> [16#0003D, 16#020E5];
++entity("bnequiv") -> [16#02261, 16#020E5];
++entity("bnot") -> 16#02310;
++entity("bopf") -> 16#1D553;
++entity("bot") -> 16#022A5;
++entity("bottom") -> 16#022A5;
++entity("bowtie") -> 16#022C8;
++entity("boxDL") -> 16#02557;
++entity("boxDR") -> 16#02554;
++entity("boxDl") -> 16#02556;
++entity("boxDr") -> 16#02553;
++entity("boxH") -> 16#02550;
++entity("boxHD") -> 16#02566;
++entity("boxHU") -> 16#02569;
++entity("boxHd") -> 16#02564;
++entity("boxHu") -> 16#02567;
++entity("boxUL") -> 16#0255D;
++entity("boxUR") -> 16#0255A;
++entity("boxUl") -> 16#0255C;
++entity("boxUr") -> 16#02559;
++entity("boxV") -> 16#02551;
++entity("boxVH") -> 16#0256C;
++entity("boxVL") -> 16#02563;
++entity("boxVR") -> 16#02560;
++entity("boxVh") -> 16#0256B;
++entity("boxVl") -> 16#02562;
++entity("boxVr") -> 16#0255F;
++entity("boxbox") -> 16#029C9;
++entity("boxdL") -> 16#02555;
++entity("boxdR") -> 16#02552;
++entity("boxdl") -> 16#02510;
++entity("boxdr") -> 16#0250C;
++entity("boxh") -> 16#02500;
++entity("boxhD") -> 16#02565;
++entity("boxhU") -> 16#02568;
++entity("boxhd") -> 16#0252C;
++entity("boxhu") -> 16#02534;
++entity("boxminus") -> 16#0229F;
++entity("boxplus") -> 16#0229E;
++entity("boxtimes") -> 16#022A0;
++entity("boxuL") -> 16#0255B;
++entity("boxuR") -> 16#02558;
++entity("boxul") -> 16#02518;
++entity("boxur") -> 16#02514;
++entity("boxv") -> 16#02502;
++entity("boxvH") -> 16#0256A;
++entity("boxvL") -> 16#02561;
++entity("boxvR") -> 16#0255E;
++entity("boxvh") -> 16#0253C;
++entity("boxvl") -> 16#02524;
++entity("boxvr") -> 16#0251C;
++entity("bprime") -> 16#02035;
++entity("breve") -> 16#002D8;
++entity("brvbar") -> 16#000A6;
++entity("bscr") -> 16#1D4B7;
++entity("bsemi") -> 16#0204F;
++entity("bsim") -> 16#0223D;
++entity("bsime") -> 16#022CD;
++entity("bsol") -> 16#0005C;
++entity("bsolb") -> 16#029C5;
++entity("bsolhsub") -> 16#027C8;
++entity("bull") -> 16#02022;
++entity("bullet") -> 16#02022;
++entity("bump") -> 16#0224E;
++entity("bumpE") -> 16#02AAE;
++entity("bumpe") -> 16#0224F;
++entity("bumpeq") -> 16#0224F;
++entity("cacute") -> 16#00107;
++entity("cap") -> 16#02229;
++entity("capand") -> 16#02A44;
++entity("capbrcup") -> 16#02A49;
++entity("capcap") -> 16#02A4B;
++entity("capcup") -> 16#02A47;
++entity("capdot") -> 16#02A40;
++entity("caps") -> [16#02229, 16#0FE00];
++entity("caret") -> 16#02041;
++entity("caron") -> 16#002C7;
++entity("ccaps") -> 16#02A4D;
++entity("ccaron") -> 16#0010D;
++entity("ccedil") -> 16#000E7;
++entity("ccirc") -> 16#00109;
++entity("ccups") -> 16#02A4C;
++entity("ccupssm") -> 16#02A50;
++entity("cdot") -> 16#0010B;
++entity("cedil") -> 16#000B8;
++entity("cemptyv") -> 16#029B2;
++entity("cent") -> 16#000A2;
++entity("centerdot") -> 16#000B7;
++entity("cfr") -> 16#1D520;
++entity("chcy") -> 16#00447;
++entity("check") -> 16#02713;
++entity("checkmark") -> 16#02713;
++entity("chi") -> 16#003C7;
++entity("cir") -> 16#025CB;
++entity("cirE") -> 16#029C3;
++entity("circ") -> 16#002C6;
++entity("circeq") -> 16#02257;
++entity("circlearrowleft") -> 16#021BA;
++entity("circlearrowright") -> 16#021BB;
++entity("circledR") -> 16#000AE;
++entity("circledS") -> 16#024C8;
++entity("circledast") -> 16#0229B;
++entity("circledcirc") -> 16#0229A;
++entity("circleddash") -> 16#0229D;
++entity("cire") -> 16#02257;
++entity("cirfnint") -> 16#02A10;
++entity("cirmid") -> 16#02AEF;
++entity("cirscir") -> 16#029C2;
++entity("clubs") -> 16#02663;
++entity("clubsuit") -> 16#02663;
++entity("colon") -> 16#0003A;
++entity("colone") -> 16#02254;
++entity("coloneq") -> 16#02254;
++entity("comma") -> 16#0002C;
++entity("commat") -> 16#00040;
++entity("comp") -> 16#02201;
++entity("compfn") -> 16#02218;
++entity("complement") -> 16#02201;
++entity("complexes") -> 16#02102;
++entity("cong") -> 16#02245;
++entity("congdot") -> 16#02A6D;
++entity("conint") -> 16#0222E;
++entity("copf") -> 16#1D554;
++entity("coprod") -> 16#02210;
++entity("copy") -> 16#000A9;
++entity("copysr") -> 16#02117;
++entity("crarr") -> 16#021B5;
++entity("cross") -> 16#02717;
++entity("cscr") -> 16#1D4B8;
++entity("csub") -> 16#02ACF;
++entity("csube") -> 16#02AD1;
++entity("csup") -> 16#02AD0;
++entity("csupe") -> 16#02AD2;
++entity("ctdot") -> 16#022EF;
++entity("cudarrl") -> 16#02938;
++entity("cudarrr") -> 16#02935;
++entity("cuepr") -> 16#022DE;
++entity("cuesc") -> 16#022DF;
++entity("cularr") -> 16#021B6;
++entity("cularrp") -> 16#0293D;
++entity("cup") -> 16#0222A;
++entity("cupbrcap") -> 16#02A48;
++entity("cupcap") -> 16#02A46;
++entity("cupcup") -> 16#02A4A;
++entity("cupdot") -> 16#0228D;
++entity("cupor") -> 16#02A45;
++entity("cups") -> [16#0222A, 16#0FE00];
++entity("curarr") -> 16#021B7;
++entity("curarrm") -> 16#0293C;
++entity("curlyeqprec") -> 16#022DE;
++entity("curlyeqsucc") -> 16#022DF;
++entity("curlyvee") -> 16#022CE;
++entity("curlywedge") -> 16#022CF;
++entity("curren") -> 16#000A4;
++entity("curvearrowleft") -> 16#021B6;
++entity("curvearrowright") -> 16#021B7;
++entity("cuvee") -> 16#022CE;
++entity("cuwed") -> 16#022CF;
++entity("cwconint") -> 16#02232;
++entity("cwint") -> 16#02231;
++entity("cylcty") -> 16#0232D;
++entity("dArr") -> 16#021D3;
++entity("dHar") -> 16#02965;
++entity("dagger") -> 16#02020;
++entity("daleth") -> 16#02138;
++entity("darr") -> 16#02193;
++entity("dash") -> 16#02010;
++entity("dashv") -> 16#022A3;
++entity("dbkarow") -> 16#0290F;
++entity("dblac") -> 16#002DD;
++entity("dcaron") -> 16#0010F;
++entity("dcy") -> 16#00434;
++entity("dd") -> 16#02146;
++entity("ddagger") -> 16#02021;
++entity("ddarr") -> 16#021CA;
++entity("ddotseq") -> 16#02A77;
++entity("deg") -> 16#000B0;
++entity("delta") -> 16#003B4;
++entity("demptyv") -> 16#029B1;
++entity("dfisht") -> 16#0297F;
++entity("dfr") -> 16#1D521;
++entity("dharl") -> 16#021C3;
++entity("dharr") -> 16#021C2;
++entity("diam") -> 16#022C4;
++entity("diamond") -> 16#022C4;
++entity("diamondsuit") -> 16#02666;
++entity("diams") -> 16#02666;
++entity("die") -> 16#000A8;
++entity("digamma") -> 16#003DD;
++entity("disin") -> 16#022F2;
++entity("div") -> 16#000F7;
++entity("divide") -> 16#000F7;
++entity("divideontimes") -> 16#022C7;
++entity("divonx") -> 16#022C7;
++entity("djcy") -> 16#00452;
++entity("dlcorn") -> 16#0231E;
++entity("dlcrop") -> 16#0230D;
++entity("dollar") -> 16#00024;
++entity("dopf") -> 16#1D555;
++entity("dot") -> 16#002D9;
++entity("doteq") -> 16#02250;
++entity("doteqdot") -> 16#02251;
++entity("dotminus") -> 16#02238;
++entity("dotplus") -> 16#02214;
++entity("dotsquare") -> 16#022A1;
++entity("doublebarwedge") -> 16#02306;
++entity("downarrow") -> 16#02193;
++entity("downdownarrows") -> 16#021CA;
++entity("downharpoonleft") -> 16#021C3;
++entity("downharpoonright") -> 16#021C2;
++entity("drbkarow") -> 16#02910;
++entity("drcorn") -> 16#0231F;
++entity("drcrop") -> 16#0230C;
++entity("dscr") -> 16#1D4B9;
++entity("dscy") -> 16#00455;
++entity("dsol") -> 16#029F6;
++entity("dstrok") -> 16#00111;
++entity("dtdot") -> 16#022F1;
++entity("dtri") -> 16#025BF;
++entity("dtrif") -> 16#025BE;
++entity("duarr") -> 16#021F5;
++entity("duhar") -> 16#0296F;
++entity("dwangle") -> 16#029A6;
++entity("dzcy") -> 16#0045F;
++entity("dzigrarr") -> 16#027FF;
++entity("eDDot") -> 16#02A77;
++entity("eDot") -> 16#02251;
++entity("eacute") -> 16#000E9;
++entity("easter") -> 16#02A6E;
++entity("ecaron") -> 16#0011B;
++entity("ecir") -> 16#02256;
++entity("ecirc") -> 16#000EA;
++entity("ecolon") -> 16#02255;
++entity("ecy") -> 16#0044D;
++entity("edot") -> 16#00117;
++entity("ee") -> 16#02147;
++entity("efDot") -> 16#02252;
++entity("efr") -> 16#1D522;
++entity("eg") -> 16#02A9A;
++entity("egrave") -> 16#000E8;
++entity("egs") -> 16#02A96;
++entity("egsdot") -> 16#02A98;
++entity("el") -> 16#02A99;
++entity("elinters") -> 16#023E7;
++entity("ell") -> 16#02113;
++entity("els") -> 16#02A95;
++entity("elsdot") -> 16#02A97;
++entity("emacr") -> 16#00113;
++entity("empty") -> 16#02205;
++entity("emptyset") -> 16#02205;
++entity("emptyv") -> 16#02205;
++entity("emsp") -> 16#02003;
++entity("emsp13") -> 16#02004;
++entity("emsp14") -> 16#02005;
++entity("eng") -> 16#0014B;
++entity("ensp") -> 16#02002;
++entity("eogon") -> 16#00119;
++entity("eopf") -> 16#1D556;
++entity("epar") -> 16#022D5;
++entity("eparsl") -> 16#029E3;
++entity("eplus") -> 16#02A71;
++entity("epsi") -> 16#003B5;
++entity("epsilon") -> 16#003B5;
++entity("epsiv") -> 16#003F5;
++entity("eqcirc") -> 16#02256;
++entity("eqcolon") -> 16#02255;
++entity("eqsim") -> 16#02242;
++entity("eqslantgtr") -> 16#02A96;
++entity("eqslantless") -> 16#02A95;
++entity("equals") -> 16#0003D;
++entity("equest") -> 16#0225F;
++entity("equiv") -> 16#02261;
++entity("equivDD") -> 16#02A78;
++entity("eqvparsl") -> 16#029E5;
++entity("erDot") -> 16#02253;
++entity("erarr") -> 16#02971;
++entity("escr") -> 16#0212F;
++entity("esdot") -> 16#02250;
++entity("esim") -> 16#02242;
++entity("eta") -> 16#003B7;
++entity("eth") -> 16#000F0;
++entity("euml") -> 16#000EB;
++entity("euro") -> 16#020AC;
++entity("excl") -> 16#00021;
++entity("exist") -> 16#02203;
++entity("expectation") -> 16#02130;
++entity("exponentiale") -> 16#02147;
++entity("fallingdotseq") -> 16#02252;
++entity("fcy") -> 16#00444;
++entity("female") -> 16#02640;
++entity("ffilig") -> 16#0FB03;
++entity("fflig") -> 16#0FB00;
++entity("ffllig") -> 16#0FB04;
++entity("ffr") -> 16#1D523;
++entity("filig") -> 16#0FB01;
++entity("fjlig") -> [16#00066, 16#0006A];
++entity("flat") -> 16#0266D;
++entity("fllig") -> 16#0FB02;
++entity("fltns") -> 16#025B1;
++entity("fnof") -> 16#00192;
++entity("fopf") -> 16#1D557;
++entity("forall") -> 16#02200;
++entity("fork") -> 16#022D4;
++entity("forkv") -> 16#02AD9;
++entity("fpartint") -> 16#02A0D;
++entity("frac12") -> 16#000BD;
++entity("frac13") -> 16#02153;
++entity("frac14") -> 16#000BC;
++entity("frac15") -> 16#02155;
++entity("frac16") -> 16#02159;
++entity("frac18") -> 16#0215B;
++entity("frac23") -> 16#02154;
++entity("frac25") -> 16#02156;
++entity("frac34") -> 16#000BE;
++entity("frac35") -> 16#02157;
++entity("frac38") -> 16#0215C;
++entity("frac45") -> 16#02158;
++entity("frac56") -> 16#0215A;
++entity("frac58") -> 16#0215D;
++entity("frac78") -> 16#0215E;
++entity("frasl") -> 16#02044;
++entity("frown") -> 16#02322;
++entity("fscr") -> 16#1D4BB;
++entity("gE") -> 16#02267;
++entity("gEl") -> 16#02A8C;
++entity("gacute") -> 16#001F5;
++entity("gamma") -> 16#003B3;
++entity("gammad") -> 16#003DD;
++entity("gap") -> 16#02A86;
++entity("gbreve") -> 16#0011F;
++entity("gcirc") -> 16#0011D;
++entity("gcy") -> 16#00433;
++entity("gdot") -> 16#00121;
++entity("ge") -> 16#02265;
++entity("gel") -> 16#022DB;
++entity("geq") -> 16#02265;
++entity("geqq") -> 16#02267;
++entity("geqslant") -> 16#02A7E;
++entity("ges") -> 16#02A7E;
++entity("gescc") -> 16#02AA9;
++entity("gesdot") -> 16#02A80;
++entity("gesdoto") -> 16#02A82;
++entity("gesdotol") -> 16#02A84;
++entity("gesl") -> [16#022DB, 16#0FE00];
++entity("gesles") -> 16#02A94;
++entity("gfr") -> 16#1D524;
++entity("gg") -> 16#0226B;
++entity("ggg") -> 16#022D9;
++entity("gimel") -> 16#02137;
++entity("gjcy") -> 16#00453;
++entity("gl") -> 16#02277;
++entity("glE") -> 16#02A92;
++entity("gla") -> 16#02AA5;
++entity("glj") -> 16#02AA4;
++entity("gnE") -> 16#02269;
++entity("gnap") -> 16#02A8A;
++entity("gnapprox") -> 16#02A8A;
++entity("gne") -> 16#02A88;
++entity("gneq") -> 16#02A88;
++entity("gneqq") -> 16#02269;
++entity("gnsim") -> 16#022E7;
++entity("gopf") -> 16#1D558;
++entity("grave") -> 16#00060;
++entity("gscr") -> 16#0210A;
++entity("gsim") -> 16#02273;
++entity("gsime") -> 16#02A8E;
++entity("gsiml") -> 16#02A90;
++entity("gt") -> 16#0003E;
++entity("gtcc") -> 16#02AA7;
++entity("gtcir") -> 16#02A7A;
++entity("gtdot") -> 16#022D7;
++entity("gtlPar") -> 16#02995;
++entity("gtquest") -> 16#02A7C;
++entity("gtrapprox") -> 16#02A86;
++entity("gtrarr") -> 16#02978;
++entity("gtrdot") -> 16#022D7;
++entity("gtreqless") -> 16#022DB;
++entity("gtreqqless") -> 16#02A8C;
++entity("gtrless") -> 16#02277;
++entity("gtrsim") -> 16#02273;
++entity("gvertneqq") -> [16#02269, 16#0FE00];
++entity("gvnE") -> [16#02269, 16#0FE00];
++entity("hArr") -> 16#021D4;
++entity("hairsp") -> 16#0200A;
++entity("half") -> 16#000BD;
++entity("hamilt") -> 16#0210B;
++entity("hardcy") -> 16#0044A;
++entity("harr") -> 16#02194;
++entity("harrcir") -> 16#02948;
++entity("harrw") -> 16#021AD;
++entity("hbar") -> 16#0210F;
++entity("hcirc") -> 16#00125;
++entity("hearts") -> 16#02665;
++entity("heartsuit") -> 16#02665;
++entity("hellip") -> 16#02026;
++entity("hercon") -> 16#022B9;
++entity("hfr") -> 16#1D525;
++entity("hksearow") -> 16#02925;
++entity("hkswarow") -> 16#02926;
++entity("hoarr") -> 16#021FF;
++entity("homtht") -> 16#0223B;
++entity("hookleftarrow") -> 16#021A9;
++entity("hookrightarrow") -> 16#021AA;
++entity("hopf") -> 16#1D559;
++entity("horbar") -> 16#02015;
++entity("hscr") -> 16#1D4BD;
++entity("hslash") -> 16#0210F;
++entity("hstrok") -> 16#00127;
++entity("hybull") -> 16#02043;
++entity("hyphen") -> 16#02010;
++entity("iacute") -> 16#000ED;
++entity("ic") -> 16#02063;
++entity("icirc") -> 16#000EE;
++entity("icy") -> 16#00438;
++entity("iecy") -> 16#00435;
++entity("iexcl") -> 16#000A1;
++entity("iff") -> 16#021D4;
++entity("ifr") -> 16#1D526;
++entity("igrave") -> 16#000EC;
++entity("ii") -> 16#02148;
++entity("iiiint") -> 16#02A0C;
++entity("iiint") -> 16#0222D;
++entity("iinfin") -> 16#029DC;
++entity("iiota") -> 16#02129;
++entity("ijlig") -> 16#00133;
++entity("imacr") -> 16#0012B;
++entity("image") -> 16#02111;
++entity("imagline") -> 16#02110;
++entity("imagpart") -> 16#02111;
++entity("imath") -> 16#00131;
++entity("imof") -> 16#022B7;
++entity("imped") -> 16#001B5;
++entity("in") -> 16#02208;
++entity("incare") -> 16#02105;
++entity("infin") -> 16#0221E;
++entity("infintie") -> 16#029DD;
++entity("inodot") -> 16#00131;
++entity("int") -> 16#0222B;
++entity("intcal") -> 16#022BA;
++entity("integers") -> 16#02124;
++entity("intercal") -> 16#022BA;
++entity("intlarhk") -> 16#02A17;
++entity("intprod") -> 16#02A3C;
++entity("iocy") -> 16#00451;
++entity("iogon") -> 16#0012F;
++entity("iopf") -> 16#1D55A;
++entity("iota") -> 16#003B9;
++entity("iprod") -> 16#02A3C;
++entity("iquest") -> 16#000BF;
++entity("iscr") -> 16#1D4BE;
++entity("isin") -> 16#02208;
++entity("isinE") -> 16#022F9;
++entity("isindot") -> 16#022F5;
++entity("isins") -> 16#022F4;
++entity("isinsv") -> 16#022F3;
++entity("isinv") -> 16#02208;
++entity("it") -> 16#02062;
++entity("itilde") -> 16#00129;
++entity("iukcy") -> 16#00456;
++entity("iuml") -> 16#000EF;
++entity("jcirc") -> 16#00135;
++entity("jcy") -> 16#00439;
++entity("jfr") -> 16#1D527;
++entity("jmath") -> 16#00237;
++entity("jopf") -> 16#1D55B;
++entity("jscr") -> 16#1D4BF;
++entity("jsercy") -> 16#00458;
++entity("jukcy") -> 16#00454;
++entity("kappa") -> 16#003BA;
++entity("kappav") -> 16#003F0;
++entity("kcedil") -> 16#00137;
++entity("kcy") -> 16#0043A;
++entity("kfr") -> 16#1D528;
++entity("kgreen") -> 16#00138;
++entity("khcy") -> 16#00445;
++entity("kjcy") -> 16#0045C;
++entity("kopf") -> 16#1D55C;
++entity("kscr") -> 16#1D4C0;
++entity("lAarr") -> 16#021DA;
++entity("lArr") -> 16#021D0;
++entity("lAtail") -> 16#0291B;
++entity("lBarr") -> 16#0290E;
++entity("lE") -> 16#02266;
++entity("lEg") -> 16#02A8B;
++entity("lHar") -> 16#02962;
++entity("lacute") -> 16#0013A;
++entity("laemptyv") -> 16#029B4;
++entity("lagran") -> 16#02112;
++entity("lambda") -> 16#003BB;
++entity("lang") -> 16#027E8;
++entity("langd") -> 16#02991;
++entity("langle") -> 16#027E8;
++entity("lap") -> 16#02A85;
++entity("laquo") -> 16#000AB;
++entity("larr") -> 16#02190;
++entity("larrb") -> 16#021E4;
++entity("larrbfs") -> 16#0291F;
++entity("larrfs") -> 16#0291D;
++entity("larrhk") -> 16#021A9;
++entity("larrlp") -> 16#021AB;
++entity("larrpl") -> 16#02939;
++entity("larrsim") -> 16#02973;
++entity("larrtl") -> 16#021A2;
++entity("lat") -> 16#02AAB;
++entity("latail") -> 16#02919;
++entity("late") -> 16#02AAD;
++entity("lates") -> [16#02AAD, 16#0FE00];
++entity("lbarr") -> 16#0290C;
++entity("lbbrk") -> 16#02772;
++entity("lbrace") -> 16#0007B;
++entity("lbrack") -> 16#0005B;
++entity("lbrke") -> 16#0298B;
++entity("lbrksld") -> 16#0298F;
++entity("lbrkslu") -> 16#0298D;
++entity("lcaron") -> 16#0013E;
++entity("lcedil") -> 16#0013C;
++entity("lceil") -> 16#02308;
++entity("lcub") -> 16#0007B;
++entity("lcy") -> 16#0043B;
++entity("ldca") -> 16#02936;
++entity("ldquo") -> 16#0201C;
++entity("ldquor") -> 16#0201E;
++entity("ldrdhar") -> 16#02967;
++entity("ldrushar") -> 16#0294B;
++entity("ldsh") -> 16#021B2;
++entity("le") -> 16#02264;
++entity("leftarrow") -> 16#02190;
++entity("leftarrowtail") -> 16#021A2;
++entity("leftharpoondown") -> 16#021BD;
++entity("leftharpoonup") -> 16#021BC;
++entity("leftleftarrows") -> 16#021C7;
++entity("leftrightarrow") -> 16#02194;
++entity("leftrightarrows") -> 16#021C6;
++entity("leftrightharpoons") -> 16#021CB;
++entity("leftrightsquigarrow") -> 16#021AD;
++entity("leftthreetimes") -> 16#022CB;
++entity("leg") -> 16#022DA;
++entity("leq") -> 16#02264;
++entity("leqq") -> 16#02266;
++entity("leqslant") -> 16#02A7D;
++entity("les") -> 16#02A7D;
++entity("lescc") -> 16#02AA8;
++entity("lesdot") -> 16#02A7F;
++entity("lesdoto") -> 16#02A81;
++entity("lesdotor") -> 16#02A83;
++entity("lesg") -> [16#022DA, 16#0FE00];
++entity("lesges") -> 16#02A93;
++entity("lessapprox") -> 16#02A85;
++entity("lessdot") -> 16#022D6;
++entity("lesseqgtr") -> 16#022DA;
++entity("lesseqqgtr") -> 16#02A8B;
++entity("lessgtr") -> 16#02276;
++entity("lesssim") -> 16#02272;
++entity("lfisht") -> 16#0297C;
++entity("lfloor") -> 16#0230A;
++entity("lfr") -> 16#1D529;
++entity("lg") -> 16#02276;
++entity("lgE") -> 16#02A91;
++entity("lhard") -> 16#021BD;
++entity("lharu") -> 16#021BC;
++entity("lharul") -> 16#0296A;
++entity("lhblk") -> 16#02584;
++entity("ljcy") -> 16#00459;
++entity("ll") -> 16#0226A;
++entity("llarr") -> 16#021C7;
++entity("llcorner") -> 16#0231E;
++entity("llhard") -> 16#0296B;
++entity("lltri") -> 16#025FA;
++entity("lmidot") -> 16#00140;
++entity("lmoust") -> 16#023B0;
++entity("lmoustache") -> 16#023B0;
++entity("lnE") -> 16#02268;
++entity("lnap") -> 16#02A89;
++entity("lnapprox") -> 16#02A89;
++entity("lne") -> 16#02A87;
++entity("lneq") -> 16#02A87;
++entity("lneqq") -> 16#02268;
++entity("lnsim") -> 16#022E6;
++entity("loang") -> 16#027EC;
++entity("loarr") -> 16#021FD;
++entity("lobrk") -> 16#027E6;
++entity("longleftarrow") -> 16#027F5;
++entity("longleftrightarrow") -> 16#027F7;
++entity("longmapsto") -> 16#027FC;
++entity("longrightarrow") -> 16#027F6;
++entity("looparrowleft") -> 16#021AB;
++entity("looparrowright") -> 16#021AC;
++entity("lopar") -> 16#02985;
++entity("lopf") -> 16#1D55D;
++entity("loplus") -> 16#02A2D;
++entity("lotimes") -> 16#02A34;
++entity("lowast") -> 16#02217;
++entity("lowbar") -> 16#0005F;
++entity("loz") -> 16#025CA;
++entity("lozenge") -> 16#025CA;
++entity("lozf") -> 16#029EB;
++entity("lpar") -> 16#00028;
++entity("lparlt") -> 16#02993;
++entity("lrarr") -> 16#021C6;
++entity("lrcorner") -> 16#0231F;
++entity("lrhar") -> 16#021CB;
++entity("lrhard") -> 16#0296D;
++entity("lrm") -> 16#0200E;
++entity("lrtri") -> 16#022BF;
++entity("lsaquo") -> 16#02039;
++entity("lscr") -> 16#1D4C1;
++entity("lsh") -> 16#021B0;
++entity("lsim") -> 16#02272;
++entity("lsime") -> 16#02A8D;
++entity("lsimg") -> 16#02A8F;
++entity("lsqb") -> 16#0005B;
++entity("lsquo") -> 16#02018;
++entity("lsquor") -> 16#0201A;
++entity("lstrok") -> 16#00142;
++entity("lt") -> 16#0003C;
++entity("ltcc") -> 16#02AA6;
++entity("ltcir") -> 16#02A79;
++entity("ltdot") -> 16#022D6;
++entity("lthree") -> 16#022CB;
++entity("ltimes") -> 16#022C9;
++entity("ltlarr") -> 16#02976;
++entity("ltquest") -> 16#02A7B;
++entity("ltrPar") -> 16#02996;
++entity("ltri") -> 16#025C3;
++entity("ltrie") -> 16#022B4;
++entity("ltrif") -> 16#025C2;
++entity("lurdshar") -> 16#0294A;
++entity("luruhar") -> 16#02966;
++entity("lvertneqq") -> [16#02268, 16#0FE00];
++entity("lvnE") -> [16#02268, 16#0FE00];
++entity("mDDot") -> 16#0223A;
++entity("macr") -> 16#000AF;
++entity("male") -> 16#02642;
++entity("malt") -> 16#02720;
++entity("maltese") -> 16#02720;
++entity("map") -> 16#021A6;
++entity("mapsto") -> 16#021A6;
++entity("mapstodown") -> 16#021A7;
++entity("mapstoleft") -> 16#021A4;
++entity("mapstoup") -> 16#021A5;
++entity("marker") -> 16#025AE;
++entity("mcomma") -> 16#02A29;
++entity("mcy") -> 16#0043C;
++entity("mdash") -> 16#02014;
++entity("measuredangle") -> 16#02221;
++entity("mfr") -> 16#1D52A;
++entity("mho") -> 16#02127;
++entity("micro") -> 16#000B5;
++entity("mid") -> 16#02223;
++entity("midast") -> 16#0002A;
++entity("midcir") -> 16#02AF0;
++entity("middot") -> 16#000B7;
++entity("minus") -> 16#02212;
++entity("minusb") -> 16#0229F;
++entity("minusd") -> 16#02238;
++entity("minusdu") -> 16#02A2A;
++entity("mlcp") -> 16#02ADB;
++entity("mldr") -> 16#02026;
++entity("mnplus") -> 16#02213;
++entity("models") -> 16#022A7;
++entity("mopf") -> 16#1D55E;
++entity("mp") -> 16#02213;
++entity("mscr") -> 16#1D4C2;
++entity("mstpos") -> 16#0223E;
++entity("mu") -> 16#003BC;
++entity("multimap") -> 16#022B8;
++entity("mumap") -> 16#022B8;
++entity("nGg") -> [16#022D9, 16#00338];
++entity("nGt") -> [16#0226B, 16#020D2];
++entity("nGtv") -> [16#0226B, 16#00338];
++entity("nLeftarrow") -> 16#021CD;
++entity("nLeftrightarrow") -> 16#021CE;
++entity("nLl") -> [16#022D8, 16#00338];
++entity("nLt") -> [16#0226A, 16#020D2];
++entity("nLtv") -> [16#0226A, 16#00338];
++entity("nRightarrow") -> 16#021CF;
++entity("nVDash") -> 16#022AF;
++entity("nVdash") -> 16#022AE;
++entity("nabla") -> 16#02207;
++entity("nacute") -> 16#00144;
++entity("nang") -> [16#02220, 16#020D2];
++entity("nap") -> 16#02249;
++entity("napE") -> [16#02A70, 16#00338];
++entity("napid") -> [16#0224B, 16#00338];
++entity("napos") -> 16#00149;
++entity("napprox") -> 16#02249;
++entity("natur") -> 16#0266E;
++entity("natural") -> 16#0266E;
++entity("naturals") -> 16#02115;
++entity("nbsp") -> 16#000A0;
++entity("nbump") -> [16#0224E, 16#00338];
++entity("nbumpe") -> [16#0224F, 16#00338];
++entity("ncap") -> 16#02A43;
++entity("ncaron") -> 16#00148;
++entity("ncedil") -> 16#00146;
++entity("ncong") -> 16#02247;
++entity("ncongdot") -> [16#02A6D, 16#00338];
++entity("ncup") -> 16#02A42;
++entity("ncy") -> 16#0043D;
++entity("ndash") -> 16#02013;
++entity("ne") -> 16#02260;
++entity("neArr") -> 16#021D7;
++entity("nearhk") -> 16#02924;
++entity("nearr") -> 16#02197;
++entity("nearrow") -> 16#02197;
++entity("nedot") -> [16#02250, 16#00338];
++entity("nequiv") -> 16#02262;
++entity("nesear") -> 16#02928;
++entity("nesim") -> [16#02242, 16#00338];
++entity("nexist") -> 16#02204;
++entity("nexists") -> 16#02204;
++entity("nfr") -> 16#1D52B;
++entity("ngE") -> [16#02267, 16#00338];
++entity("nge") -> 16#02271;
++entity("ngeq") -> 16#02271;
++entity("ngeqq") -> [16#02267, 16#00338];
++entity("ngeqslant") -> [16#02A7E, 16#00338];
++entity("nges") -> [16#02A7E, 16#00338];
++entity("ngsim") -> 16#02275;
++entity("ngt") -> 16#0226F;
++entity("ngtr") -> 16#0226F;
++entity("nhArr") -> 16#021CE;
++entity("nharr") -> 16#021AE;
++entity("nhpar") -> 16#02AF2;
++entity("ni") -> 16#0220B;
++entity("nis") -> 16#022FC;
++entity("nisd") -> 16#022FA;
++entity("niv") -> 16#0220B;
++entity("njcy") -> 16#0045A;
++entity("nlArr") -> 16#021CD;
++entity("nlE") -> [16#02266, 16#00338];
++entity("nlarr") -> 16#0219A;
++entity("nldr") -> 16#02025;
++entity("nle") -> 16#02270;
++entity("nleftarrow") -> 16#0219A;
++entity("nleftrightarrow") -> 16#021AE;
++entity("nleq") -> 16#02270;
++entity("nleqq") -> [16#02266, 16#00338];
++entity("nleqslant") -> [16#02A7D, 16#00338];
++entity("nles") -> [16#02A7D, 16#00338];
++entity("nless") -> 16#0226E;
++entity("nlsim") -> 16#02274;
++entity("nlt") -> 16#0226E;
++entity("nltri") -> 16#022EA;
++entity("nltrie") -> 16#022EC;
++entity("nmid") -> 16#02224;
++entity("nopf") -> 16#1D55F;
++entity("not") -> 16#000AC;
++entity("notin") -> 16#02209;
++entity("notinE") -> [16#022F9, 16#00338];
++entity("notindot") -> [16#022F5, 16#00338];
++entity("notinva") -> 16#02209;
++entity("notinvb") -> 16#022F7;
++entity("notinvc") -> 16#022F6;
++entity("notni") -> 16#0220C;
++entity("notniva") -> 16#0220C;
++entity("notnivb") -> 16#022FE;
++entity("notnivc") -> 16#022FD;
++entity("npar") -> 16#02226;
++entity("nparallel") -> 16#02226;
++entity("nparsl") -> [16#02AFD, 16#020E5];
++entity("npart") -> [16#02202, 16#00338];
++entity("npolint") -> 16#02A14;
++entity("npr") -> 16#02280;
++entity("nprcue") -> 16#022E0;
++entity("npre") -> [16#02AAF, 16#00338];
++entity("nprec") -> 16#02280;
++entity("npreceq") -> [16#02AAF, 16#00338];
++entity("nrArr") -> 16#021CF;
++entity("nrarr") -> 16#0219B;
++entity("nrarrc") -> [16#02933, 16#00338];
++entity("nrarrw") -> [16#0219D, 16#00338];
++entity("nrightarrow") -> 16#0219B;
++entity("nrtri") -> 16#022EB;
++entity("nrtrie") -> 16#022ED;
++entity("nsc") -> 16#02281;
++entity("nsccue") -> 16#022E1;
++entity("nsce") -> [16#02AB0, 16#00338];
++entity("nscr") -> 16#1D4C3;
++entity("nshortmid") -> 16#02224;
++entity("nshortparallel") -> 16#02226;
++entity("nsim") -> 16#02241;
++entity("nsime") -> 16#02244;
++entity("nsimeq") -> 16#02244;
++entity("nsmid") -> 16#02224;
++entity("nspar") -> 16#02226;
++entity("nsqsube") -> 16#022E2;
++entity("nsqsupe") -> 16#022E3;
++entity("nsub") -> 16#02284;
++entity("nsubE") -> [16#02AC5, 16#00338];
++entity("nsube") -> 16#02288;
++entity("nsubset") -> [16#02282, 16#020D2];
++entity("nsubseteq") -> 16#02288;
++entity("nsubseteqq") -> [16#02AC5, 16#00338];
++entity("nsucc") -> 16#02281;
++entity("nsucceq") -> [16#02AB0, 16#00338];
++entity("nsup") -> 16#02285;
++entity("nsupE") -> [16#02AC6, 16#00338];
++entity("nsupe") -> 16#02289;
++entity("nsupset") -> [16#02283, 16#020D2];
++entity("nsupseteq") -> 16#02289;
++entity("nsupseteqq") -> [16#02AC6, 16#00338];
++entity("ntgl") -> 16#02279;
++entity("ntilde") -> 16#000F1;
++entity("ntlg") -> 16#02278;
++entity("ntriangleleft") -> 16#022EA;
++entity("ntrianglelefteq") -> 16#022EC;
++entity("ntriangleright") -> 16#022EB;
++entity("ntrianglerighteq") -> 16#022ED;
++entity("nu") -> 16#003BD;
++entity("num") -> 16#00023;
++entity("numero") -> 16#02116;
++entity("numsp") -> 16#02007;
++entity("nvDash") -> 16#022AD;
++entity("nvHarr") -> 16#02904;
++entity("nvap") -> [16#0224D, 16#020D2];
++entity("nvdash") -> 16#022AC;
++entity("nvge") -> [16#02265, 16#020D2];
++entity("nvgt") -> [16#0003E, 16#020D2];
++entity("nvinfin") -> 16#029DE;
++entity("nvlArr") -> 16#02902;
++entity("nvle") -> [16#02264, 16#020D2];
++entity("nvlt") -> [16#0003C, 16#020D2];
++entity("nvltrie") -> [16#022B4, 16#020D2];
++entity("nvrArr") -> 16#02903;
++entity("nvrtrie") -> [16#022B5, 16#020D2];
++entity("nvsim") -> [16#0223C, 16#020D2];
++entity("nwArr") -> 16#021D6;
++entity("nwarhk") -> 16#02923;
++entity("nwarr") -> 16#02196;
++entity("nwarrow") -> 16#02196;
++entity("nwnear") -> 16#02927;
++entity("oS") -> 16#024C8;
++entity("oacute") -> 16#000F3;
++entity("oast") -> 16#0229B;
++entity("ocir") -> 16#0229A;
++entity("ocirc") -> 16#000F4;
++entity("ocy") -> 16#0043E;
++entity("odash") -> 16#0229D;
++entity("odblac") -> 16#00151;
++entity("odiv") -> 16#02A38;
++entity("odot") -> 16#02299;
++entity("odsold") -> 16#029BC;
++entity("oelig") -> 16#00153;
++entity("ofcir") -> 16#029BF;
++entity("ofr") -> 16#1D52C;
++entity("ogon") -> 16#002DB;
++entity("ograve") -> 16#000F2;
++entity("ogt") -> 16#029C1;
++entity("ohbar") -> 16#029B5;
++entity("ohm") -> 16#003A9;
++entity("oint") -> 16#0222E;
++entity("olarr") -> 16#021BA;
++entity("olcir") -> 16#029BE;
++entity("olcross") -> 16#029BB;
++entity("oline") -> 16#0203E;
++entity("olt") -> 16#029C0;
++entity("omacr") -> 16#0014D;
++entity("omega") -> 16#003C9;
++entity("omicron") -> 16#003BF;
++entity("omid") -> 16#029B6;
++entity("ominus") -> 16#02296;
++entity("oopf") -> 16#1D560;
++entity("opar") -> 16#029B7;
++entity("operp") -> 16#029B9;
++entity("oplus") -> 16#02295;
++entity("or") -> 16#02228;
++entity("orarr") -> 16#021BB;
++entity("ord") -> 16#02A5D;
++entity("order") -> 16#02134;
++entity("orderof") -> 16#02134;
++entity("ordf") -> 16#000AA;
++entity("ordm") -> 16#000BA;
++entity("origof") -> 16#022B6;
++entity("oror") -> 16#02A56;
++entity("orslope") -> 16#02A57;
++entity("orv") -> 16#02A5B;
++entity("oscr") -> 16#02134;
++entity("oslash") -> 16#000F8;
++entity("osol") -> 16#02298;
++entity("otilde") -> 16#000F5;
++entity("otimes") -> 16#02297;
++entity("otimesas") -> 16#02A36;
++entity("ouml") -> 16#000F6;
++entity("ovbar") -> 16#0233D;
++entity("par") -> 16#02225;
++entity("para") -> 16#000B6;
++entity("parallel") -> 16#02225;
++entity("parsim") -> 16#02AF3;
++entity("parsl") -> 16#02AFD;
++entity("part") -> 16#02202;
++entity("pcy") -> 16#0043F;
++entity("percnt") -> 16#00025;
++entity("period") -> 16#0002E;
++entity("permil") -> 16#02030;
++entity("perp") -> 16#022A5;
++entity("pertenk") -> 16#02031;
++entity("pfr") -> 16#1D52D;
++entity("phi") -> 16#003C6;
++entity("phiv") -> 16#003D5;
++entity("phmmat") -> 16#02133;
++entity("phone") -> 16#0260E;
++entity("pi") -> 16#003C0;
++entity("pitchfork") -> 16#022D4;
++entity("piv") -> 16#003D6;
++entity("planck") -> 16#0210F;
++entity("planckh") -> 16#0210E;
++entity("plankv") -> 16#0210F;
++entity("plus") -> 16#0002B;
++entity("plusacir") -> 16#02A23;
++entity("plusb") -> 16#0229E;
++entity("pluscir") -> 16#02A22;
++entity("plusdo") -> 16#02214;
++entity("plusdu") -> 16#02A25;
++entity("pluse") -> 16#02A72;
++entity("plusmn") -> 16#000B1;
++entity("plussim") -> 16#02A26;
++entity("plustwo") -> 16#02A27;
++entity("pm") -> 16#000B1;
++entity("pointint") -> 16#02A15;
++entity("popf") -> 16#1D561;
++entity("pound") -> 16#000A3;
++entity("pr") -> 16#0227A;
++entity("prE") -> 16#02AB3;
++entity("prap") -> 16#02AB7;
++entity("prcue") -> 16#0227C;
++entity("pre") -> 16#02AAF;
++entity("prec") -> 16#0227A;
++entity("precapprox") -> 16#02AB7;
++entity("preccurlyeq") -> 16#0227C;
++entity("preceq") -> 16#02AAF;
++entity("precnapprox") -> 16#02AB9;
++entity("precneqq") -> 16#02AB5;
++entity("precnsim") -> 16#022E8;
++entity("precsim") -> 16#0227E;
++entity("prime") -> 16#02032;
++entity("primes") -> 16#02119;
++entity("prnE") -> 16#02AB5;
++entity("prnap") -> 16#02AB9;
++entity("prnsim") -> 16#022E8;
++entity("prod") -> 16#0220F;
++entity("profalar") -> 16#0232E;
++entity("profline") -> 16#02312;
++entity("profsurf") -> 16#02313;
++entity("prop") -> 16#0221D;
++entity("propto") -> 16#0221D;
++entity("prsim") -> 16#0227E;
++entity("prurel") -> 16#022B0;
++entity("pscr") -> 16#1D4C5;
++entity("psi") -> 16#003C8;
++entity("puncsp") -> 16#02008;
++entity("qfr") -> 16#1D52E;
++entity("qint") -> 16#02A0C;
++entity("qopf") -> 16#1D562;
++entity("qprime") -> 16#02057;
++entity("qscr") -> 16#1D4C6;
++entity("quaternions") -> 16#0210D;
++entity("quatint") -> 16#02A16;
++entity("quest") -> 16#0003F;
++entity("questeq") -> 16#0225F;
++entity("quot") -> 16#00022;
++entity("rAarr") -> 16#021DB;
++entity("rArr") -> 16#021D2;
++entity("rAtail") -> 16#0291C;
++entity("rBarr") -> 16#0290F;
++entity("rHar") -> 16#02964;
++entity("race") -> [16#0223D, 16#00331];
++entity("racute") -> 16#00155;
++entity("radic") -> 16#0221A;
++entity("raemptyv") -> 16#029B3;
++entity("rang") -> 16#027E9;
++entity("rangd") -> 16#02992;
++entity("range") -> 16#029A5;
++entity("rangle") -> 16#027E9;
++entity("raquo") -> 16#000BB;
++entity("rarr") -> 16#02192;
++entity("rarrap") -> 16#02975;
++entity("rarrb") -> 16#021E5;
++entity("rarrbfs") -> 16#02920;
++entity("rarrc") -> 16#02933;
++entity("rarrfs") -> 16#0291E;
++entity("rarrhk") -> 16#021AA;
++entity("rarrlp") -> 16#021AC;
++entity("rarrpl") -> 16#02945;
++entity("rarrsim") -> 16#02974;
++entity("rarrtl") -> 16#021A3;
++entity("rarrw") -> 16#0219D;
++entity("ratail") -> 16#0291A;
++entity("ratio") -> 16#02236;
++entity("rationals") -> 16#0211A;
++entity("rbarr") -> 16#0290D;
++entity("rbbrk") -> 16#02773;
++entity("rbrace") -> 16#0007D;
++entity("rbrack") -> 16#0005D;
++entity("rbrke") -> 16#0298C;
++entity("rbrksld") -> 16#0298E;
++entity("rbrkslu") -> 16#02990;
++entity("rcaron") -> 16#00159;
++entity("rcedil") -> 16#00157;
++entity("rceil") -> 16#02309;
++entity("rcub") -> 16#0007D;
++entity("rcy") -> 16#00440;
++entity("rdca") -> 16#02937;
++entity("rdldhar") -> 16#02969;
++entity("rdquo") -> 16#0201D;
++entity("rdquor") -> 16#0201D;
++entity("rdsh") -> 16#021B3;
++entity("real") -> 16#0211C;
++entity("realine") -> 16#0211B;
++entity("realpart") -> 16#0211C;
++entity("reals") -> 16#0211D;
++entity("rect") -> 16#025AD;
++entity("reg") -> 16#000AE;
++entity("rfisht") -> 16#0297D;
++entity("rfloor") -> 16#0230B;
++entity("rfr") -> 16#1D52F;
++entity("rhard") -> 16#021C1;
++entity("rharu") -> 16#021C0;
++entity("rharul") -> 16#0296C;
++entity("rho") -> 16#003C1;
++entity("rhov") -> 16#003F1;
++entity("rightarrow") -> 16#02192;
++entity("rightarrowtail") -> 16#021A3;
++entity("rightharpoondown") -> 16#021C1;
++entity("rightharpoonup") -> 16#021C0;
++entity("rightleftarrows") -> 16#021C4;
++entity("rightleftharpoons") -> 16#021CC;
++entity("rightrightarrows") -> 16#021C9;
++entity("rightsquigarrow") -> 16#0219D;
++entity("rightthreetimes") -> 16#022CC;
++entity("ring") -> 16#002DA;
++entity("risingdotseq") -> 16#02253;
++entity("rlarr") -> 16#021C4;
++entity("rlhar") -> 16#021CC;
++entity("rlm") -> 16#0200F;
++entity("rmoust") -> 16#023B1;
++entity("rmoustache") -> 16#023B1;
++entity("rnmid") -> 16#02AEE;
++entity("roang") -> 16#027ED;
++entity("roarr") -> 16#021FE;
++entity("robrk") -> 16#027E7;
++entity("ropar") -> 16#02986;
++entity("ropf") -> 16#1D563;
++entity("roplus") -> 16#02A2E;
++entity("rotimes") -> 16#02A35;
++entity("rpar") -> 16#00029;
++entity("rpargt") -> 16#02994;
++entity("rppolint") -> 16#02A12;
++entity("rrarr") -> 16#021C9;
++entity("rsaquo") -> 16#0203A;
++entity("rscr") -> 16#1D4C7;
++entity("rsh") -> 16#021B1;
++entity("rsqb") -> 16#0005D;
++entity("rsquo") -> 16#02019;
++entity("rsquor") -> 16#02019;
++entity("rthree") -> 16#022CC;
++entity("rtimes") -> 16#022CA;
++entity("rtri") -> 16#025B9;
++entity("rtrie") -> 16#022B5;
++entity("rtrif") -> 16#025B8;
++entity("rtriltri") -> 16#029CE;
++entity("ruluhar") -> 16#02968;
++entity("rx") -> 16#0211E;
++entity("sacute") -> 16#0015B;
++entity("sbquo") -> 16#0201A;
++entity("sc") -> 16#0227B;
++entity("scE") -> 16#02AB4;
++entity("scap") -> 16#02AB8;
++entity("scaron") -> 16#00161;
++entity("sccue") -> 16#0227D;
++entity("sce") -> 16#02AB0;
++entity("scedil") -> 16#0015F;
++entity("scirc") -> 16#0015D;
++entity("scnE") -> 16#02AB6;
++entity("scnap") -> 16#02ABA;
++entity("scnsim") -> 16#022E9;
++entity("scpolint") -> 16#02A13;
++entity("scsim") -> 16#0227F;
++entity("scy") -> 16#00441;
++entity("sdot") -> 16#022C5;
++entity("sdotb") -> 16#022A1;
++entity("sdote") -> 16#02A66;
++entity("seArr") -> 16#021D8;
++entity("searhk") -> 16#02925;
++entity("searr") -> 16#02198;
++entity("searrow") -> 16#02198;
++entity("sect") -> 16#000A7;
++entity("semi") -> 16#0003B;
++entity("seswar") -> 16#02929;
++entity("setminus") -> 16#02216;
++entity("setmn") -> 16#02216;
++entity("sext") -> 16#02736;
++entity("sfr") -> 16#1D530;
++entity("sfrown") -> 16#02322;
++entity("sharp") -> 16#0266F;
++entity("shchcy") -> 16#00449;
++entity("shcy") -> 16#00448;
++entity("shortmid") -> 16#02223;
++entity("shortparallel") -> 16#02225;
++entity("shy") -> 16#000AD;
++entity("sigma") -> 16#003C3;
++entity("sigmaf") -> 16#003C2;
++entity("sigmav") -> 16#003C2;
++entity("sim") -> 16#0223C;
++entity("simdot") -> 16#02A6A;
++entity("sime") -> 16#02243;
++entity("simeq") -> 16#02243;
++entity("simg") -> 16#02A9E;
++entity("simgE") -> 16#02AA0;
++entity("siml") -> 16#02A9D;
++entity("simlE") -> 16#02A9F;
++entity("simne") -> 16#02246;
++entity("simplus") -> 16#02A24;
++entity("simrarr") -> 16#02972;
++entity("slarr") -> 16#02190;
++entity("smallsetminus") -> 16#02216;
++entity("smashp") -> 16#02A33;
++entity("smeparsl") -> 16#029E4;
++entity("smid") -> 16#02223;
++entity("smile") -> 16#02323;
++entity("smt") -> 16#02AAA;
++entity("smte") -> 16#02AAC;
++entity("smtes") -> [16#02AAC, 16#0FE00];
++entity("softcy") -> 16#0044C;
++entity("sol") -> 16#0002F;
++entity("solb") -> 16#029C4;
++entity("solbar") -> 16#0233F;
++entity("sopf") -> 16#1D564;
++entity("spades") -> 16#02660;
++entity("spadesuit") -> 16#02660;
++entity("spar") -> 16#02225;
++entity("sqcap") -> 16#02293;
++entity("sqcaps") -> [16#02293, 16#0FE00];
++entity("sqcup") -> 16#02294;
++entity("sqcups") -> [16#02294, 16#0FE00];
++entity("sqsub") -> 16#0228F;
++entity("sqsube") -> 16#02291;
++entity("sqsubset") -> 16#0228F;
++entity("sqsubseteq") -> 16#02291;
++entity("sqsup") -> 16#02290;
++entity("sqsupe") -> 16#02292;
++entity("sqsupset") -> 16#02290;
++entity("sqsupseteq") -> 16#02292;
++entity("squ") -> 16#025A1;
++entity("square") -> 16#025A1;
++entity("squarf") -> 16#025AA;
++entity("squf") -> 16#025AA;
++entity("srarr") -> 16#02192;
++entity("sscr") -> 16#1D4C8;
++entity("ssetmn") -> 16#02216;
++entity("ssmile") -> 16#02323;
++entity("sstarf") -> 16#022C6;
++entity("star") -> 16#02606;
++entity("starf") -> 16#02605;
++entity("straightepsilon") -> 16#003F5;
++entity("straightphi") -> 16#003D5;
++entity("strns") -> 16#000AF;
++entity("sub") -> 16#02282;
++entity("subE") -> 16#02AC5;
++entity("subdot") -> 16#02ABD;
++entity("sube") -> 16#02286;
++entity("subedot") -> 16#02AC3;
++entity("submult") -> 16#02AC1;
++entity("subnE") -> 16#02ACB;
++entity("subne") -> 16#0228A;
++entity("subplus") -> 16#02ABF;
++entity("subrarr") -> 16#02979;
++entity("subset") -> 16#02282;
++entity("subseteq") -> 16#02286;
++entity("subseteqq") -> 16#02AC5;
++entity("subsetneq") -> 16#0228A;
++entity("subsetneqq") -> 16#02ACB;
++entity("subsim") -> 16#02AC7;
++entity("subsub") -> 16#02AD5;
++entity("subsup") -> 16#02AD3;
++entity("succ") -> 16#0227B;
++entity("succapprox") -> 16#02AB8;
++entity("succcurlyeq") -> 16#0227D;
++entity("succeq") -> 16#02AB0;
++entity("succnapprox") -> 16#02ABA;
++entity("succneqq") -> 16#02AB6;
++entity("succnsim") -> 16#022E9;
++entity("succsim") -> 16#0227F;
++entity("sum") -> 16#02211;
++entity("sung") -> 16#0266A;
++entity("sup") -> 16#02283;
++entity("sup1") -> 16#000B9;
++entity("sup2") -> 16#000B2;
++entity("sup3") -> 16#000B3;
++entity("supE") -> 16#02AC6;
++entity("supdot") -> 16#02ABE;
++entity("supdsub") -> 16#02AD8;
++entity("supe") -> 16#02287;
++entity("supedot") -> 16#02AC4;
++entity("suphsol") -> 16#027C9;
++entity("suphsub") -> 16#02AD7;
++entity("suplarr") -> 16#0297B;
++entity("supmult") -> 16#02AC2;
++entity("supnE") -> 16#02ACC;
++entity("supne") -> 16#0228B;
++entity("supplus") -> 16#02AC0;
++entity("supset") -> 16#02283;
++entity("supseteq") -> 16#02287;
++entity("supseteqq") -> 16#02AC6;
++entity("supsetneq") -> 16#0228B;
++entity("supsetneqq") -> 16#02ACC;
++entity("supsim") -> 16#02AC8;
++entity("supsub") -> 16#02AD4;
++entity("supsup") -> 16#02AD6;
++entity("swArr") -> 16#021D9;
++entity("swarhk") -> 16#02926;
++entity("swarr") -> 16#02199;
++entity("swarrow") -> 16#02199;
++entity("swnwar") -> 16#0292A;
++entity("szlig") -> 16#000DF;
++entity("target") -> 16#02316;
++entity("tau") -> 16#003C4;
++entity("tbrk") -> 16#023B4;
++entity("tcaron") -> 16#00165;
++entity("tcedil") -> 16#00163;
++entity("tcy") -> 16#00442;
++entity("tdot") -> 16#020DB;
++entity("telrec") -> 16#02315;
++entity("tfr") -> 16#1D531;
++entity("there4") -> 16#02234;
++entity("therefore") -> 16#02234;
++entity("theta") -> 16#003B8;
++entity("thetasym") -> 16#003D1;
++entity("thetav") -> 16#003D1;
++entity("thickapprox") -> 16#02248;
++entity("thicksim") -> 16#0223C;
++entity("thinsp") -> 16#02009;
++entity("thkap") -> 16#02248;
++entity("thksim") -> 16#0223C;
++entity("thorn") -> 16#000FE;
++entity("tilde") -> 16#002DC;
++entity("times") -> 16#000D7;
++entity("timesb") -> 16#022A0;
++entity("timesbar") -> 16#02A31;
++entity("timesd") -> 16#02A30;
++entity("tint") -> 16#0222D;
++entity("toea") -> 16#02928;
++entity("top") -> 16#022A4;
++entity("topbot") -> 16#02336;
++entity("topcir") -> 16#02AF1;
++entity("topf") -> 16#1D565;
++entity("topfork") -> 16#02ADA;
++entity("tosa") -> 16#02929;
++entity("tprime") -> 16#02034;
++entity("trade") -> 16#02122;
++entity("triangle") -> 16#025B5;
++entity("triangledown") -> 16#025BF;
++entity("triangleleft") -> 16#025C3;
++entity("trianglelefteq") -> 16#022B4;
++entity("triangleq") -> 16#0225C;
++entity("triangleright") -> 16#025B9;
++entity("trianglerighteq") -> 16#022B5;
++entity("tridot") -> 16#025EC;
++entity("trie") -> 16#0225C;
++entity("triminus") -> 16#02A3A;
++entity("triplus") -> 16#02A39;
++entity("trisb") -> 16#029CD;
++entity("tritime") -> 16#02A3B;
++entity("trpezium") -> 16#023E2;
++entity("tscr") -> 16#1D4C9;
++entity("tscy") -> 16#00446;
++entity("tshcy") -> 16#0045B;
++entity("tstrok") -> 16#00167;
++entity("twixt") -> 16#0226C;
++entity("twoheadleftarrow") -> 16#0219E;
++entity("twoheadrightarrow") -> 16#021A0;
++entity("uArr") -> 16#021D1;
++entity("uHar") -> 16#02963;
++entity("uacute") -> 16#000FA;
++entity("uarr") -> 16#02191;
++entity("ubrcy") -> 16#0045E;
++entity("ubreve") -> 16#0016D;
++entity("ucirc") -> 16#000FB;
++entity("ucy") -> 16#00443;
++entity("udarr") -> 16#021C5;
++entity("udblac") -> 16#00171;
++entity("udhar") -> 16#0296E;
++entity("ufisht") -> 16#0297E;
++entity("ufr") -> 16#1D532;
++entity("ugrave") -> 16#000F9;
++entity("uharl") -> 16#021BF;
++entity("uharr") -> 16#021BE;
++entity("uhblk") -> 16#02580;
++entity("ulcorn") -> 16#0231C;
++entity("ulcorner") -> 16#0231C;
++entity("ulcrop") -> 16#0230F;
++entity("ultri") -> 16#025F8;
++entity("umacr") -> 16#0016B;
++entity("uml") -> 16#000A8;
++entity("uogon") -> 16#00173;
++entity("uopf") -> 16#1D566;
++entity("uparrow") -> 16#02191;
++entity("updownarrow") -> 16#02195;
++entity("upharpoonleft") -> 16#021BF;
++entity("upharpoonright") -> 16#021BE;
++entity("uplus") -> 16#0228E;
++entity("upsi") -> 16#003C5;
++entity("upsih") -> 16#003D2;
++entity("upsilon") -> 16#003C5;
++entity("upuparrows") -> 16#021C8;
++entity("urcorn") -> 16#0231D;
++entity("urcorner") -> 16#0231D;
++entity("urcrop") -> 16#0230E;
++entity("uring") -> 16#0016F;
++entity("urtri") -> 16#025F9;
++entity("uscr") -> 16#1D4CA;
++entity("utdot") -> 16#022F0;
++entity("utilde") -> 16#00169;
++entity("utri") -> 16#025B5;
++entity("utrif") -> 16#025B4;
++entity("uuarr") -> 16#021C8;
++entity("uuml") -> 16#000FC;
++entity("uwangle") -> 16#029A7;
++entity("vArr") -> 16#021D5;
++entity("vBar") -> 16#02AE8;
++entity("vBarv") -> 16#02AE9;
++entity("vDash") -> 16#022A8;
++entity("vangrt") -> 16#0299C;
++entity("varepsilon") -> 16#003F5;
++entity("varkappa") -> 16#003F0;
++entity("varnothing") -> 16#02205;
++entity("varphi") -> 16#003D5;
++entity("varpi") -> 16#003D6;
++entity("varpropto") -> 16#0221D;
++entity("varr") -> 16#02195;
++entity("varrho") -> 16#003F1;
++entity("varsigma") -> 16#003C2;
++entity("varsubsetneq") -> [16#0228A, 16#0FE00];
++entity("varsubsetneqq") -> [16#02ACB, 16#0FE00];
++entity("varsupsetneq") -> [16#0228B, 16#0FE00];
++entity("varsupsetneqq") -> [16#02ACC, 16#0FE00];
++entity("vartheta") -> 16#003D1;
++entity("vartriangleleft") -> 16#022B2;
++entity("vartriangleright") -> 16#022B3;
++entity("vcy") -> 16#00432;
++entity("vdash") -> 16#022A2;
++entity("vee") -> 16#02228;
++entity("veebar") -> 16#022BB;
++entity("veeeq") -> 16#0225A;
++entity("vellip") -> 16#022EE;
++entity("verbar") -> 16#0007C;
++entity("vert") -> 16#0007C;
++entity("vfr") -> 16#1D533;
++entity("vltri") -> 16#022B2;
++entity("vnsub") -> [16#02282, 16#020D2];
++entity("vnsup") -> [16#02283, 16#020D2];
++entity("vopf") -> 16#1D567;
++entity("vprop") -> 16#0221D;
++entity("vrtri") -> 16#022B3;
++entity("vscr") -> 16#1D4CB;
++entity("vsubnE") -> [16#02ACB, 16#0FE00];
++entity("vsubne") -> [16#0228A, 16#0FE00];
++entity("vsupnE") -> [16#02ACC, 16#0FE00];
++entity("vsupne") -> [16#0228B, 16#0FE00];
++entity("vzigzag") -> 16#0299A;
++entity("wcirc") -> 16#00175;
++entity("wedbar") -> 16#02A5F;
++entity("wedge") -> 16#02227;
++entity("wedgeq") -> 16#02259;
++entity("weierp") -> 16#02118;
++entity("wfr") -> 16#1D534;
++entity("wopf") -> 16#1D568;
++entity("wp") -> 16#02118;
++entity("wr") -> 16#02240;
++entity("wreath") -> 16#02240;
++entity("wscr") -> 16#1D4CC;
++entity("xcap") -> 16#022C2;
++entity("xcirc") -> 16#025EF;
++entity("xcup") -> 16#022C3;
++entity("xdtri") -> 16#025BD;
++entity("xfr") -> 16#1D535;
++entity("xhArr") -> 16#027FA;
++entity("xharr") -> 16#027F7;
++entity("xi") -> 16#003BE;
++entity("xlArr") -> 16#027F8;
++entity("xlarr") -> 16#027F5;
++entity("xmap") -> 16#027FC;
++entity("xnis") -> 16#022FB;
++entity("xodot") -> 16#02A00;
++entity("xopf") -> 16#1D569;
++entity("xoplus") -> 16#02A01;
++entity("xotime") -> 16#02A02;
++entity("xrArr") -> 16#027F9;
++entity("xrarr") -> 16#027F6;
++entity("xscr") -> 16#1D4CD;
++entity("xsqcup") -> 16#02A06;
++entity("xuplus") -> 16#02A04;
++entity("xutri") -> 16#025B3;
++entity("xvee") -> 16#022C1;
++entity("xwedge") -> 16#022C0;
++entity("yacute") -> 16#000FD;
++entity("yacy") -> 16#0044F;
++entity("ycirc") -> 16#00177;
++entity("ycy") -> 16#0044B;
++entity("yen") -> 16#000A5;
++entity("yfr") -> 16#1D536;
++entity("yicy") -> 16#00457;
++entity("yopf") -> 16#1D56A;
++entity("yscr") -> 16#1D4CE;
++entity("yucy") -> 16#0044E;
++entity("yuml") -> 16#000FF;
++entity("zacute") -> 16#0017A;
++entity("zcaron") -> 16#0017E;
++entity("zcy") -> 16#00437;
++entity("zdot") -> 16#0017C;
++entity("zeetrf") -> 16#02128;
++entity("zeta") -> 16#003B6;
++entity("zfr") -> 16#1D537;
++entity("zhcy") -> 16#00436;
++entity("zigrarr") -> 16#021DD;
++entity("zopf") -> 16#1D56B;
++entity("zscr") -> 16#1D4CF;
++entity("zwj") -> 16#0200D;
++entity("zwnj") -> 16#0200C;
++entity(_) -> undefined.
+
+ %%
+ %% Tests
+ %%
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
++-include_lib("eunit/include/eunit.hrl").
+
+ exhaustive_entity_test() ->
+ T = mochiweb_cover:clause_lookup_table(?MODULE, entity),
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochiweb_cookies.erl apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_cookies.erl
+--- apache-couchdb-1.2.1/src/mochiweb/mochiweb_cookies.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_cookies.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -23,6 +23,7 @@
+
+ %% @type proplist() = [{Key::string(), Value::string()}].
+ %% @type header() = {Name::string(), Value::string()}.
++%% @type int_seconds() = integer().
+
+ %% @spec cookie(Key::string(), Value::string()) -> header()
+ %% @doc Short-hand for <code>cookie(Key, Value, [])</code>.
+@@ -30,7 +31,7 @@
+ cookie(Key, Value, []).
+
+ %% @spec cookie(Key::string(), Value::string(), Options::[Option]) -> header()
+-%% where Option = {max_age, integer()} | {local_time, {date(), time()}}
++%% where Option = {max_age, int_seconds()} | {local_time, {date(), time()}}
+ %% | {domain, string()} | {path, string()}
+ %% | {secure, true | false} | {http_only, true | false}
+ %%
+@@ -115,12 +116,33 @@
+ orelse erlang:error({cookie_quoting_required, V}),
+ V.
+
++
++%% Return a date in the form of: Wdy, DD-Mon-YYYY HH:MM:SS GMT
++%% See also: rfc2109: 10.1.2
++rfc2109_cookie_expires_date(LocalTime) ->
++ {{YYYY,MM,DD},{Hour,Min,Sec}} =
++ case calendar:local_time_to_universal_time_dst(LocalTime) of
++ [] ->
++ {Date, {Hour1, Min1, Sec1}} = LocalTime,
++ LocalTime2 = {Date, {Hour1 + 1, Min1, Sec1}},
++ case calendar:local_time_to_universal_time_dst(LocalTime2) of
++ [Gmt] -> Gmt;
++ [_,Gmt] -> Gmt
++ end;
++ [Gmt] -> Gmt;
++ [_,Gmt] -> Gmt
++ end,
++ DayNumber = calendar:day_of_the_week({YYYY,MM,DD}),
++ lists:flatten(
++ io_lib:format("~s, ~2.2.0w-~3.s-~4.4.0w ~2.2.0w:~2.2.0w:~2.2.0w GMT",
++ [httpd_util:day(DayNumber),DD,httpd_util:month(MM),YYYY,Hour,Min,Sec])).
++
+ add_seconds(Secs, LocalTime) ->
+ Greg = calendar:datetime_to_gregorian_seconds(LocalTime),
+ calendar:gregorian_seconds_to_datetime(Greg + Secs).
+
+ age_to_cookie_date(Age, LocalTime) ->
+- httpd_util:rfc1123_date(add_seconds(Age, LocalTime)).
++ rfc2109_cookie_expires_date(add_seconds(Age, LocalTime)).
+
+ %% @spec parse_cookie(string()) -> [{K::string(), V::string()}]
+ %% @doc Parse the contents of a Cookie header field, ignoring cookie
+@@ -203,8 +225,8 @@
+ %%
+ %% Tests
+ %%
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
++-include_lib("eunit/include/eunit.hrl").
+
+ quote_test() ->
+ %% ?assertError eunit macro is not compatible with coverage module
+@@ -293,14 +315,14 @@
+ C2 = {"Set-Cookie",
+ "Customer=WILE_E_COYOTE; "
+ "Version=1; "
+- "Expires=Tue, 15 May 2007 13:45:33 GMT; "
++ "Expires=Tue, 15-May-2007 13:45:33 GMT; "
+ "Max-Age=0"},
+ C2 = cookie("Customer", "WILE_E_COYOTE",
+ [{max_age, -111}, {local_time, LocalTime}]),
+ C3 = {"Set-Cookie",
+ "Customer=WILE_E_COYOTE; "
+ "Version=1; "
+- "Expires=Wed, 16 May 2007 13:45:50 GMT; "
++ "Expires=Wed, 16-May-2007 13:45:50 GMT; "
+ "Max-Age=86417"},
+ C3 = cookie("Customer", "WILE_E_COYOTE",
+ [{max_age, 86417}, {local_time, LocalTime}]),
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochiweb_cover.erl apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_cover.erl
+--- apache-couchdb-1.2.1/src/mochiweb/mochiweb_cover.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_cover.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -46,8 +46,8 @@
+ %%
+ %% Tests
+ %%
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
++-include_lib("eunit/include/eunit.hrl").
+ foo_table(a) -> b;
+ foo_table("a") -> <<"b">>;
+ foo_table(123) -> {4, 3, 2};
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochiweb_echo.erl apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_echo.erl
+--- apache-couchdb-1.2.1/src/mochiweb/mochiweb_echo.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_echo.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -11,11 +11,14 @@
+ mochiweb_socket_server:stop(?MODULE).
+
+ start() ->
+- mochiweb_socket_server:start([{name, ?MODULE},
++ mochiweb_socket_server:start([{link, false} | options()]).
++
++options() ->
++ [{name, ?MODULE},
+ {port, 6789},
+ {ip, "127.0.0.1"},
+ {max, 1},
+- {loop, {?MODULE, loop}}]).
++ {loop, {?MODULE, loop}}].
+
+ loop(Socket) ->
+ case mochiweb_socket:recv(Socket, 0, 30000) of
+@@ -33,6 +36,6 @@
+ %%
+ %% Tests
+ %%
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
++-include_lib("eunit/include/eunit.hrl").
+ -endif.
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochiweb.erl apache-couchdb-1.2.1.q/src/mochiweb/mochiweb.erl
+--- apache-couchdb-1.2.1/src/mochiweb/mochiweb.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochiweb.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -6,22 +6,9 @@
+ -module(mochiweb).
+ -author('bob@mochimedia.com').
+
+--export([start/0, stop/0]).
+ -export([new_request/1, new_response/1]).
+ -export([all_loaded/0, all_loaded/1, reload/0]).
+-
+-%% @spec start() -> ok
+-%% @doc Start the MochiWeb server.
+-start() ->
+- ensure_started(crypto),
+- application:start(mochiweb).
+-
+-%% @spec stop() -> ok
+-%% @doc Stop the MochiWeb server.
+-stop() ->
+- Res = application:stop(mochiweb),
+- application:stop(crypto),
+- Res.
++-export([ensure_started/1]).
+
+ reload() ->
+ [c:l(Module) || Module <- all_loaded()].
+@@ -78,8 +65,8 @@
+ Code,
+ mochiweb_headers:make(Headers)).
+
+-%% Internal API
+-
++%% @spec ensure_started(App::atom()) -> ok
++%% @doc Start the given App if it has not been started already.
+ ensure_started(App) ->
+ case application:start(App) of
+ ok ->
+@@ -92,8 +78,8 @@
+ %%
+ %% Tests
+ %%
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
++-include_lib("eunit/include/eunit.hrl").
+
+ -record(treq, {path, body= <<>>, xreply= <<>>}).
+
+@@ -112,7 +98,7 @@
+ ssl ->
+ ServerOpts0 ++ [{ssl, true}, {ssl_opts, ssl_cert_opts()}]
+ end,
+- {ok, Server} = mochiweb_http:start(ServerOpts),
++ {ok, Server} = mochiweb_http:start_link(ServerOpts),
+ Port = mochiweb_socket_server:get(Server, port),
+ Res = (catch ClientFun(Transport, Port)),
+ mochiweb_http:stop(Server),
+@@ -123,6 +109,8 @@
+ "/foo/bar/baz wibble quux" = R:get(path),
+ ok.
+
++-define(LARGE_TIMEOUT, 60).
++
+ single_http_GET_test() ->
+ do_GET(plain, 1).
+
+@@ -135,11 +123,13 @@
+ multiple_https_GET_test() ->
+ do_GET(ssl, 3).
+
+-hundred_http_GET_test() ->
+- do_GET(plain, 100).
+-
+-hundred_https_GET_test() ->
+- do_GET(ssl, 100).
++hundred_http_GET_test_() -> % note the underscore
++ {timeout, ?LARGE_TIMEOUT,
++ fun() -> ?assertEqual(ok, do_GET(plain,100)) end}.
++
++hundred_https_GET_test_() -> % note the underscore
++ {timeout, ?LARGE_TIMEOUT,
++ fun() -> ?assertEqual(ok, do_GET(ssl,100)) end}.
+
+ single_128_http_POST_test() ->
+ do_POST(plain, 128, 1).
+@@ -165,11 +155,13 @@
+ multiple_100K_https_POST_test() ->
+ do_POST(ssl, 102400, 3).
+
+-hundred_128_http_POST_test() ->
+- do_POST(plain, 128, 100).
+-
+-hundred_128_https_POST_test() ->
+- do_POST(ssl, 128, 100).
++hundred_128_http_POST_test_() -> % note the underscore
++ {timeout, ?LARGE_TIMEOUT,
++ fun() -> ?assertEqual(ok, do_POST(plain, 128, 100)) end}.
++
++hundred_128_https_POST_test_() -> % note the underscore
++ {timeout, ?LARGE_TIMEOUT,
++ fun() -> ?assertEqual(ok, do_POST(ssl, 128, 100)) end}.
+
+ do_GET(Transport, Times) ->
+ PathPrefix = "/whatever/",
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochiweb_headers.erl apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_headers.erl
+--- apache-couchdb-1.2.1/src/mochiweb/mochiweb_headers.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_headers.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -6,7 +6,7 @@
+ -module(mochiweb_headers).
+ -author('bob@mochimedia.com').
+ -export([empty/0, from_list/1, insert/3, enter/3, get_value/2, lookup/2]).
+--export([delete_any/2, get_primary_value/2]).
++-export([delete_any/2, get_primary_value/2, get_combined_value/2]).
+ -export([default/3, enter_from_list/2, default_from_list/2]).
+ -export([to_list/1, make/1]).
+ -export([from_binary/1]).
+@@ -24,8 +24,8 @@
+ %% @doc Construct a headers() from the given list.
+ make(L) when is_list(L) ->
+ from_list(L);
+-%% assume a tuple is already mochiweb_headers.
+-make(T) when is_tuple(T) ->
++%% assume a non-list is already mochiweb_headers.
++make(T) ->
+ T.
+
+ %% @spec from_binary(iolist()) -> headers()
+@@ -112,6 +112,34 @@
+ lists:takewhile(fun (C) -> C =/= $; end, V)
+ end.
+
++%% @spec get_combined_value(key(), headers()) -> string() | undefined
++%% @doc Return the value from the given header using a case insensitive search.
++%% If the value of the header is a comma-separated list where holds values
++%% are all identical, the identical value will be returned.
++%% undefined will be returned for keys that are not present or the
++%% values in the list are not the same.
++%%
++%% NOTE: The process isn't designed for a general purpose. If you need
++%% to access all values in the combined header, please refer to
++%% '''tokenize_header_value/1'''.
++%%
++%% Section 4.2 of the RFC 2616 (HTTP 1.1) describes multiple message-header
++%% fields with the same field-name may be present in a message if and only
++%% if the entire field-value for that header field is defined as a
++%% comma-separated list [i.e., #(values)].
++get_combined_value(K, T) ->
++ case get_value(K, T) of
++ undefined ->
++ undefined;
++ V ->
++ case sets:to_list(sets:from_list(tokenize_header_value(V))) of
++ [Val] ->
++ Val;
++ _ ->
++ undefined
++ end
++ end.
++
+ %% @spec lookup(key(), headers()) -> {value, {key(), string()}} | none
+ %% @doc Return the case preserved key and value for the given header using
+ %% a case insensitive search. none will be returned for keys that are
+@@ -164,6 +192,49 @@
+
+ %% Internal API
+
++tokenize_header_value(undefined) ->
++ undefined;
++tokenize_header_value(V) ->
++ reversed_tokens(trim_and_reverse(V, false), [], []).
++
++trim_and_reverse([S | Rest], Reversed) when S=:=$ ; S=:=$\n; S=:=$\t ->
++ trim_and_reverse(Rest, Reversed);
++trim_and_reverse(V, false) ->
++ trim_and_reverse(lists:reverse(V), true);
++trim_and_reverse(V, true) ->
++ V.
++
++reversed_tokens([], [], Acc) ->
++ Acc;
++reversed_tokens([], Token, Acc) ->
++ [Token | Acc];
++reversed_tokens("\"" ++ Rest, [], Acc) ->
++ case extract_quoted_string(Rest, []) of
++ {String, NewRest} ->
++ reversed_tokens(NewRest, [], [String | Acc]);
++ undefined ->
++ undefined
++ end;
++reversed_tokens("\"" ++ _Rest, _Token, _Acc) ->
++ undefined;
++reversed_tokens([C | Rest], [], Acc) when C=:=$ ;C=:=$\n;C=:=$\t;C=:=$, ->
++ reversed_tokens(Rest, [], Acc);
++reversed_tokens([C | Rest], Token, Acc) when C=:=$ ;C=:=$\n;C=:=$\t;C=:=$, ->
++ reversed_tokens(Rest, [], [Token | Acc]);
++reversed_tokens([C | Rest], Token, Acc) ->
++ reversed_tokens(Rest, [C | Token], Acc);
++reversed_tokens(_, _, _) ->
++ undefeined.
++
++extract_quoted_string([], _Acc) ->
++ undefined;
++extract_quoted_string("\"\\" ++ Rest, Acc) ->
++ extract_quoted_string(Rest, "\"" ++ Acc);
++extract_quoted_string("\"" ++ Rest, Acc) ->
++ {Acc, Rest};
++extract_quoted_string([C | Rest], Acc) ->
++ extract_quoted_string(Rest, [C | Acc]).
++
+ expand({array, L}) ->
+ mochiweb_util:join(lists:reverse(L), ", ");
+ expand(V) ->
+@@ -195,8 +266,8 @@
+ %%
+ %% Tests.
+ %%
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
++-include_lib("eunit/include/eunit.hrl").
+
+ make_test() ->
+ Identity = make([{hdr, foo}]),
+@@ -237,6 +308,37 @@
+ get_primary_value(<<"baz">>, H)),
+ ok.
+
++get_combined_value_test() ->
++ H = make([{hdr, foo}, {baz, <<"wibble,taco">>}, {content_length, "123, 123"},
++ {test, " 123, 123, 123 , 123,123 "},
++ {test2, "456, 123, 123 , 123"},
++ {test3, "123"}, {test4, " 123, "}]),
++ ?assertEqual(
++ "foo",
++ get_combined_value(hdr, H)),
++ ?assertEqual(
++ undefined,
++ get_combined_value(bar, H)),
++ ?assertEqual(
++ undefined,
++ get_combined_value(<<"baz">>, H)),
++ ?assertEqual(
++ "123",
++ get_combined_value(<<"content_length">>, H)),
++ ?assertEqual(
++ "123",
++ get_combined_value(<<"test">>, H)),
++ ?assertEqual(
++ undefined,
++ get_combined_value(<<"test2">>, H)),
++ ?assertEqual(
++ "123",
++ get_combined_value(<<"test3">>, H)),
++ ?assertEqual(
++ "123",
++ get_combined_value(<<"test4">>, H)),
++ ok.
++
+ set_cookie_test() ->
+ H = make([{"set-cookie", foo}, {"set-cookie", bar}, {"set-cookie", baz}]),
+ ?assertEqual(
+@@ -296,4 +398,23 @@
+ [] = ?MODULE:to_list(?MODULE:from_binary([<<"\r\n\r\n">>])),
+ ok.
+
++tokenize_header_value_test() ->
++ ?assertEqual(["a quote in a \"quote\"."],
++ tokenize_header_value("\"a quote in a \\\"quote\\\".\"")),
++ ?assertEqual(["abc"], tokenize_header_value("abc")),
++ ?assertEqual(["abc", "def"], tokenize_header_value("abc def")),
++ ?assertEqual(["abc", "def"], tokenize_header_value("abc , def")),
++ ?assertEqual(["abc", "def"], tokenize_header_value(",abc ,, def,,")),
++ ?assertEqual(["abc def"], tokenize_header_value("\"abc def\" ")),
++ ?assertEqual(["abc, def"], tokenize_header_value("\"abc, def\"")),
++ ?assertEqual(["\\a\\$"], tokenize_header_value("\"\\a\\$\"")),
++ ?assertEqual(["abc def", "foo, bar", "12345", ""],
++ tokenize_header_value("\"abc def\" \"foo, bar\" , 12345, \"\"")),
++ ?assertEqual(undefined,
++ tokenize_header_value(undefined)),
++ ?assertEqual(undefined,
++ tokenize_header_value("umatched quote\"")),
++ ?assertEqual(undefined,
++ tokenize_header_value("\"unmatched quote")).
++
+ -endif.
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochiweb_html.erl apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_html.erl
+--- apache-couchdb-1.2.1/src/mochiweb/mochiweb_html.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_html.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -95,7 +95,12 @@
+ to_tokens({Tag0, [], Acc});
+ to_tokens({Tag0, Attrs, Acc}) ->
+ Tag = to_tag(Tag0),
+- to_tokens([{Tag, Acc}], [{start_tag, Tag, Attrs, is_singleton(Tag)}]).
++ case is_singleton(Tag) of
++ true ->
++ to_tokens([], [{start_tag, Tag, Attrs, true}]);
++ false ->
++ to_tokens([{Tag, Acc}], [{start_tag, Tag, Attrs, false}])
++ end.
+
+ %% @spec to_html([html_token()] | html_node()) -> iolist()
+ %% @doc Convert a list of html_token() to a HTML document.
+@@ -312,7 +317,8 @@
+ {Tag, S1} = tokenize_literal(B, ?ADV_COL(S, 2)),
+ {S2, _} = find_gt(B, S1),
+ {{end_tag, Tag}, S2};
+- <<_:O/binary, "<", C, _/binary>> when ?IS_WHITESPACE(C) ->
++ <<_:O/binary, "<", C, _/binary>>
++ when ?IS_WHITESPACE(C); not ?IS_LITERAL_SAFE(C) ->
+ %% This isn't really strict HTML
+ {{data, Data, _Whitespace}, S1} = tokenize_data(B, ?INC_COL(S)),
+ {{data, <<$<, Data/binary>>, false}, S1};
+@@ -501,8 +507,6 @@
+ tokenize_quoted_attr_value(B, S1, [Data|Acc], Q);
+ <<_:O/binary, Q, _/binary>> ->
+ { iolist_to_binary(lists:reverse(Acc)), ?INC_COL(S) };
+- <<_:O/binary, $\n, _/binary>> ->
+- { iolist_to_binary(lists:reverse(Acc)), ?INC_LINE(S) };
+ <<_:O/binary, C, _/binary>> ->
+ tokenize_quoted_attr_value(B, ?INC_COL(S), [C|Acc], Q)
+ end.
+@@ -603,32 +607,33 @@
+ end.
+
+ tokenize_charref(Bin, S=#decoder{offset=O}) ->
+- tokenize_charref(Bin, S, O).
++ try
++ tokenize_charref(Bin, S, O)
++ catch
++ throw:invalid_charref ->
++ {{data, <<"&">>, false}, S}
++ end.
+
+ tokenize_charref(Bin, S=#decoder{offset=O}, Start) ->
+ case Bin of
+ <<_:O/binary>> ->
+- <<_:Start/binary, Raw/binary>> = Bin,
+- {{data, Raw, false}, S};
++ throw(invalid_charref);
+ <<_:O/binary, C, _/binary>> when ?IS_WHITESPACE(C)
+ orelse C =:= ?SQUOTE
+ orelse C =:= ?QUOTE
+ orelse C =:= $/
+ orelse C =:= $> ->
+- Len = O - Start,
+- <<_:Start/binary, Raw:Len/binary, _/binary>> = Bin,
+- {{data, Raw, false}, S};
++ throw(invalid_charref);
+ <<_:O/binary, $;, _/binary>> ->
+ Len = O - Start,
+ <<_:Start/binary, Raw:Len/binary, _/binary>> = Bin,
+ Data = case mochiweb_charref:charref(Raw) of
+ undefined ->
+- Start1 = Start - 1,
+- Len1 = Len + 2,
+- <<_:Start1/binary, R:Len1/binary, _/binary>> = Bin,
+- R;
+- Unichar ->
+- mochiutf8:codepoint_to_bytes(Unichar)
++ throw(invalid_charref);
++ Unichar when is_integer(Unichar) ->
++ mochiutf8:codepoint_to_bytes(Unichar);
++ Unichars when is_list(Unichars) ->
++ unicode:characters_to_binary(Unichars)
+ end,
+ {{data, Data, false}, ?INC_COL(S)};
+ _ ->
+@@ -759,8 +764,8 @@
+ %%
+ %% Tests
+ %%
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
++-include_lib("eunit/include/eunit.hrl").
+
+ to_html_test() ->
+ ?assertEqual(
+@@ -1232,6 +1237,14 @@
+ { <<"img">>, [ { <<"src">>, <<"/images/icon>.png">> } ], [] }
+ ]},
+ mochiweb_html:parse(D2)),
++
++ %% Quoted attributes can contain whitespace and newlines
++ D3 = <<"<html><a href=\"#\" onclick=\"javascript: test(1,\ntrue);\"></html>">>,
++ ?assertEqual(
++ {<<"html">>,[],[
++ { <<"a">>, [ { <<"href">>, <<"#">> }, {<<"onclick">>, <<"javascript: test(1,\ntrue);">>} ], [] }
++ ]},
++ mochiweb_html:parse(D3)),
+ ok.
+
+ parse_missing_attr_name_test() ->
+@@ -1261,4 +1274,59 @@
+ mochiweb_html:parse(D0)),
+ ok.
+
++to_html_singleton_test() ->
++ D0 = <<"<link />">>,
++ T0 = {<<"link">>,[],[]},
++ ?assertEqual(D0, iolist_to_binary(to_html(T0))),
++
++ D1 = <<"<head><link /></head>">>,
++ T1 = {<<"head">>,[],[{<<"link">>,[],[]}]},
++ ?assertEqual(D1, iolist_to_binary(to_html(T1))),
++
++ D2 = <<"<head><link /><link /></head>">>,
++ T2 = {<<"head">>,[],[{<<"link">>,[],[]}, {<<"link">>,[],[]}]},
++ ?assertEqual(D2, iolist_to_binary(to_html(T2))),
++
++ %% Make sure singletons are converted to singletons.
++ D3 = <<"<head><link /></head>">>,
++ T3 = {<<"head">>,[],[{<<"link">>,[],[<<"funny">>]}]},
++ ?assertEqual(D3, iolist_to_binary(to_html(T3))),
++
++ D4 = <<"<link />">>,
++ T4 = {<<"link">>,[],[<<"funny">>]},
++ ?assertEqual(D4, iolist_to_binary(to_html(T4))),
++
++ ok.
++
++parse_amp_test_() ->
++ [?_assertEqual(
++ {<<"html">>,[],
++ [{<<"body">>,[{<<"onload">>,<<"javascript:A('1&2')">>}],[]}]},
++ mochiweb_html:parse("<html><body onload=\"javascript:A('1&2')\"></body></html>")),
++ ?_assertEqual(
++ {<<"html">>,[],
++ [{<<"body">>,[{<<"onload">>,<<"javascript:A('1& 2')">>}],[]}]},
++ mochiweb_html:parse("<html><body onload=\"javascript:A('1& 2')\"></body></html>")),
++ ?_assertEqual(
++ {<<"html">>,[],
++ [{<<"body">>,[],[<<"& ">>]}]},
++ mochiweb_html:parse("<html><body>& </body></html>")),
++ ?_assertEqual(
++ {<<"html">>,[],
++ [{<<"body">>,[],[<<"&">>]}]},
++ mochiweb_html:parse("<html><body>&</body></html>"))].
++
++parse_unescaped_lt_test() ->
++ D1 = <<"<div> < < <a href=\"/\">Back</a></div>">>,
++ ?assertEqual(
++ {<<"div">>, [], [<<" < < ">>, {<<"a">>, [{<<"href">>, <<"/">>}],
++ [<<"Back">>]}]},
++ mochiweb_html:parse(D1)),
++
++ D2 = <<"<div> << <a href=\"/\">Back</a></div>">>,
++ ?assertEqual(
++ {<<"div">>, [], [<<" << ">>, {<<"a">>, [{<<"href">>, <<"/">>}],
++ [<<"Back">>]}]},
++ mochiweb_html:parse(D2)).
++
+ -endif.
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochiweb_http.erl apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_http.erl
+--- apache-couchdb-1.2.1/src/mochiweb/mochiweb_http.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_http.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -5,13 +5,13 @@
+
+ -module(mochiweb_http).
+ -author('bob@mochimedia.com').
+--export([start/0, start/1, stop/0, stop/1]).
+--export([loop/2, default_body/1]).
++-export([start/1, start_link/1, stop/0, stop/1]).
++-export([loop/2]).
+ -export([after_response/2, reentry/1]).
+ -export([parse_range_request/1, range_skip_length/2]).
+
+--define(REQUEST_RECV_TIMEOUT, 300000). % timeout waiting for request line
+--define(HEADERS_RECV_TIMEOUT, 30000). % timeout waiting for headers
++-define(REQUEST_RECV_TIMEOUT, 300000). %% timeout waiting for request line
++-define(HEADERS_RECV_TIMEOUT, 30000). %% timeout waiting for headers
+
+ -define(MAX_HEADERS, 1000).
+ -define(DEFAULTS, [{name, ?MODULE},
+@@ -19,9 +19,7 @@
+
+ parse_options(Options) ->
+ {loop, HttpLoop} = proplists:lookup(loop, Options),
+- Loop = fun (S) ->
+- ?MODULE:loop(S, HttpLoop)
+- end,
++ Loop = {?MODULE, loop, [HttpLoop]},
+ Options1 = [{loop, Loop} | proplists:delete(loop, Options)],
+ mochilists:set_defaults(?DEFAULTS, Options1).
+
+@@ -31,15 +29,12 @@
+ stop(Name) ->
+ mochiweb_socket_server:stop(Name).
+
+-start() ->
+- start([{ip, "127.0.0.1"},
+- {loop, {?MODULE, default_body}}]).
+-
+ %% @spec start(Options) -> ServerRet
+ %% Options = [option()]
+ %% Option = {name, atom()} | {ip, string() | tuple()} | {backlog, integer()}
+ %% | {nodelay, boolean()} | {acceptor_pool_size, integer()}
+ %% | {ssl, boolean()} | {profile_fun, undefined | (Props) -> ok}
++%% | {link, false}
+ %% @doc Start a mochiweb server.
+ %% profile_fun is used to profile accept timing.
+ %% After each accept, if defined, profile_fun is called with a proplist of a subset of the mochiweb_socket_server state and timing information.
+@@ -48,62 +43,18 @@
+ start(Options) ->
+ mochiweb_socket_server:start(parse_options(Options)).
+
+-frm(Body) ->
+- ["<html><head></head><body>"
+- "<form method=\"POST\">"
+- "<input type=\"hidden\" value=\"message\" name=\"hidden\"/>"
+- "<input type=\"submit\" value=\"regular POST\">"
+- "</form>"
+- "<br />"
+- "<form method=\"POST\" enctype=\"multipart/form-data\""
+- " action=\"/multipart\">"
+- "<input type=\"hidden\" value=\"multipart message\" name=\"hidden\"/>"
+- "<input type=\"file\" name=\"file\"/>"
+- "<input type=\"submit\" value=\"multipart POST\" />"
+- "</form>"
+- "<pre>", Body, "</pre>"
+- "</body></html>"].
+-
+-default_body(Req, M, "/chunked") when M =:= 'GET'; M =:= 'HEAD' ->
+- Res = Req:ok({"text/plain", [], chunked}),
+- Res:write_chunk("First chunk\r\n"),
+- timer:sleep(5000),
+- Res:write_chunk("Last chunk\r\n"),
+- Res:write_chunk("");
+-default_body(Req, M, _Path) when M =:= 'GET'; M =:= 'HEAD' ->
+- Body = io_lib:format("~p~n", [[{parse_qs, Req:parse_qs()},
+- {parse_cookie, Req:parse_cookie()},
+- Req:dump()]]),
+- Req:ok({"text/html",
+- [mochiweb_cookies:cookie("mochiweb_http", "test_cookie")],
+- frm(Body)});
+-default_body(Req, 'POST', "/multipart") ->
+- Body = io_lib:format("~p~n", [[{parse_qs, Req:parse_qs()},
+- {parse_cookie, Req:parse_cookie()},
+- {body, Req:recv_body()},
+- Req:dump()]]),
+- Req:ok({"text/html", [], frm(Body)});
+-default_body(Req, 'POST', _Path) ->
+- Body = io_lib:format("~p~n", [[{parse_qs, Req:parse_qs()},
+- {parse_cookie, Req:parse_cookie()},
+- {parse_post, Req:parse_post()},
+- Req:dump()]]),
+- Req:ok({"text/html", [], frm(Body)});
+-default_body(Req, _Method, _Path) ->
+- Req:respond({501, [], []}).
+-
+-default_body(Req) ->
+- default_body(Req, Req:get(method), Req:get(path)).
++start_link(Options) ->
++ mochiweb_socket_server:start_link(parse_options(Options)).
+
+ loop(Socket, Body) ->
+- mochiweb_socket:setopts(Socket, [{packet, http}]),
++ ok = mochiweb_socket:setopts(Socket, [{packet, http}]),
+ request(Socket, Body).
+
+ request(Socket, Body) ->
+- mochiweb_socket:setopts(Socket, [{active, once}]),
++ ok = mochiweb_socket:setopts(Socket, [{active, once}]),
+ receive
+ {Protocol, _, {http_request, Method, Path, Version}} when Protocol == http orelse Protocol == ssl ->
+- mochiweb_socket:setopts(Socket, [{packet, httph}]),
++ ok = mochiweb_socket:setopts(Socket, [{packet, httph}]),
+ headers(Socket, {Method, Path, Version}, [], Body, 0);
+ {Protocol, _, {http_error, "\r\n"}} when Protocol == http orelse Protocol == ssl ->
+ request(Socket, Body);
+@@ -112,6 +63,13 @@
+ {tcp_closed, _} ->
+ mochiweb_socket:close(Socket),
+ exit(normal);
++ {ssl_closed, _} ->
++ mochiweb_socket:close(Socket),
++ exit(normal);
++ {tcp_error,_,emsgsize} ->
++ % R15B02 returns this then closes the socket, so close and exit
++ mochiweb_socket:close(Socket),
++ exit(normal);
+ _Other ->
+ handle_invalid_request(Socket)
+ after ?REQUEST_RECV_TIMEOUT ->
+@@ -126,10 +84,10 @@
+
+ headers(Socket, Request, Headers, _Body, ?MAX_HEADERS) ->
+ %% Too many headers sent, bad request.
+- mochiweb_socket:setopts(Socket, [{packet, raw}]),
++ ok = mochiweb_socket:setopts(Socket, [{packet, raw}]),
+ handle_invalid_request(Socket, Request, Headers);
+ headers(Socket, Request, Headers, Body, HeaderCount) ->
+- mochiweb_socket:setopts(Socket, [{active, once}]),
++ ok = mochiweb_socket:setopts(Socket, [{active, once}]),
+ receive
+ {Protocol, _, http_eoh} when Protocol == http orelse Protocol == ssl ->
+ Req = new_request(Socket, Request, Headers),
+@@ -141,6 +99,10 @@
+ {tcp_closed, _} ->
+ mochiweb_socket:close(Socket),
+ exit(normal);
++ {tcp_error,_,emsgsize} ->
++ % R15B02 returns this then closes the socket, so close and exit
++ mochiweb_socket:close(Socket),
++ exit(normal);
+ _Other ->
+ handle_invalid_request(Socket, Request, Headers)
+ after ?HEADERS_RECV_TIMEOUT ->
+@@ -148,14 +110,19 @@
+ exit(normal)
+ end.
+
++call_body({M, F, A}, Req) ->
++ erlang:apply(M, F, [Req | A]);
+ call_body({M, F}, Req) ->
+ M:F(Req);
+ call_body(Body, Req) ->
+ Body(Req).
+
++-spec handle_invalid_request(term()) -> no_return().
+ handle_invalid_request(Socket) ->
+- handle_invalid_request(Socket, {'GET', {abs_path, "/"}, {0,9}}, []).
++ handle_invalid_request(Socket, {'GET', {abs_path, "/"}, {0,9}}, []),
++ exit(normal).
+
++-spec handle_invalid_request(term(), term(), term()) -> no_return().
+ handle_invalid_request(Socket, Request, RevHeaders) ->
+ Req = new_request(Socket, Request, RevHeaders),
+ Req:respond({400, [], []}),
+@@ -163,7 +130,7 @@
+ exit(normal).
+
+ new_request(Socket, Request, RevHeaders) ->
+- mochiweb_socket:setopts(Socket, [{packet, raw}]),
++ ok = mochiweb_socket:setopts(Socket, [{packet, raw}]),
+ mochiweb:new_request({Socket, Request, lists:reverse(RevHeaders)}).
+
+ after_response(Body, Req) ->
+@@ -174,6 +141,7 @@
+ exit(normal);
+ false ->
+ Req:cleanup(),
++ erlang:garbage_collect(),
+ ?MODULE:loop(Socket, Body)
+ end.
+
+@@ -211,6 +179,8 @@
+ invalid_range;
+ {Start, End} when 0 =< Start, Start =< End, End < Size ->
+ {Start, End - Start + 1};
++ {Start, End} when 0 =< Start, Start =< End, End >= Size ->
++ {Start, Size - Start};
+ {_OutOfRange, _End} ->
+ invalid_range
+ end.
+@@ -218,8 +188,8 @@
+ %%
+ %% Tests
+ %%
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
++-include_lib("eunit/include/eunit.hrl").
+
+ range_test() ->
+ %% valid, single ranges
+@@ -265,19 +235,23 @@
+ BodySizeLess1 = BodySize - 1,
+ ?assertEqual({BodySizeLess1, 1},
+ range_skip_length({BodySize - 1, none}, BodySize)),
++ ?assertEqual({BodySizeLess1, 1},
++ range_skip_length({BodySize - 1, BodySize+5}, BodySize)),
++ ?assertEqual({BodySizeLess1, 1},
++ range_skip_length({BodySize - 1, BodySize}, BodySize)),
+
+ %% out of range, return whole thing
+ ?assertEqual({0, BodySize},
+ range_skip_length({none, BodySize + 1}, BodySize)),
+ ?assertEqual({0, BodySize},
+ range_skip_length({none, -1}, BodySize)),
++ ?assertEqual({0, BodySize},
++ range_skip_length({0, BodySize + 1}, BodySize)),
+
+ %% invalid ranges
+ ?assertEqual(invalid_range,
+ range_skip_length({-1, 30}, BodySize)),
+ ?assertEqual(invalid_range,
+- range_skip_length({0, BodySize + 1}, BodySize)),
+- ?assertEqual(invalid_range,
+ range_skip_length({-1, BodySize + 1}, BodySize)),
+ ?assertEqual(invalid_range,
+ range_skip_length({BodySize, 40}, BodySize)),
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochiweb_io.erl apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_io.erl
+--- apache-couchdb-1.2.1/src/mochiweb/mochiweb_io.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_io.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -38,9 +38,6 @@
+ %%
+ %% Tests
+ %%
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
+-
+-
+-
++-include_lib("eunit/include/eunit.hrl").
+ -endif.
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochiweb_mime.erl apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_mime.erl
+--- apache-couchdb-1.2.1/src/mochiweb/mochiweb_mime.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_mime.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -11,72 +11,393 @@
+ %% @doc Given a filename extension (e.g. ".html") return a guess for the MIME
+ %% type such as "text/html". Will return the atom undefined if no good
+ %% guess is available.
+-from_extension(".html") ->
+- "text/html";
+-from_extension(".xhtml") ->
+- "application/xhtml+xml";
+-from_extension(".xml") ->
+- "application/xml";
+-from_extension(".css") ->
+- "text/css";
++
++from_extension(".stl") ->
++ "application/SLA";
++from_extension(".stp") ->
++ "application/STEP";
++from_extension(".step") ->
++ "application/STEP";
++from_extension(".dwg") ->
++ "application/acad";
++from_extension(".ez") ->
++ "application/andrew-inset";
++from_extension(".ccad") ->
++ "application/clariscad";
++from_extension(".drw") ->
++ "application/drafting";
++from_extension(".tsp") ->
++ "application/dsptype";
++from_extension(".dxf") ->
++ "application/dxf";
++from_extension(".xls") ->
++ "application/excel";
++from_extension(".unv") ->
++ "application/i-deas";
++from_extension(".jar") ->
++ "application/java-archive";
++from_extension(".hqx") ->
++ "application/mac-binhex40";
++from_extension(".cpt") ->
++ "application/mac-compactpro";
++from_extension(".pot") ->
++ "application/vnd.ms-powerpoint";
++from_extension(".ppt") ->
++ "application/vnd.ms-powerpoint";
++from_extension(".dms") ->
++ "application/octet-stream";
++from_extension(".lha") ->
++ "application/octet-stream";
++from_extension(".lzh") ->
++ "application/octet-stream";
++from_extension(".oda") ->
++ "application/oda";
++from_extension(".ogg") ->
++ "application/ogg";
++from_extension(".ogm") ->
++ "application/ogg";
++from_extension(".pdf") ->
++ "application/pdf";
++from_extension(".pgp") ->
++ "application/pgp";
++from_extension(".ai") ->
++ "application/postscript";
++from_extension(".eps") ->
++ "application/postscript";
++from_extension(".ps") ->
++ "application/postscript";
++from_extension(".prt") ->
++ "application/pro_eng";
++from_extension(".rtf") ->
++ "application/rtf";
++from_extension(".smi") ->
++ "application/smil";
++from_extension(".smil") ->
++ "application/smil";
++from_extension(".sol") ->
++ "application/solids";
++from_extension(".vda") ->
++ "application/vda";
++from_extension(".xlm") ->
++ "application/vnd.ms-excel";
++from_extension(".cod") ->
++ "application/vnd.rim.cod";
++from_extension(".pgn") ->
++ "application/x-chess-pgn";
++from_extension(".cpio") ->
++ "application/x-cpio";
++from_extension(".csh") ->
++ "application/x-csh";
++from_extension(".deb") ->
++ "application/x-debian-package";
++from_extension(".dcr") ->
++ "application/x-director";
++from_extension(".dir") ->
++ "application/x-director";
++from_extension(".dxr") ->
++ "application/x-director";
++from_extension(".gz") ->
++ "application/x-gzip";
++from_extension(".hdf") ->
++ "application/x-hdf";
++from_extension(".ipx") ->
++ "application/x-ipix";
++from_extension(".ips") ->
++ "application/x-ipscript";
+ from_extension(".js") ->
+ "application/x-javascript";
+-from_extension(".jpg") ->
+- "image/jpeg";
+-from_extension(".gif") ->
+- "image/gif";
+-from_extension(".png") ->
+- "image/png";
++from_extension(".skd") ->
++ "application/x-koan";
++from_extension(".skm") ->
++ "application/x-koan";
++from_extension(".skp") ->
++ "application/x-koan";
++from_extension(".skt") ->
++ "application/x-koan";
++from_extension(".latex") ->
++ "application/x-latex";
++from_extension(".lsp") ->
++ "application/x-lisp";
++from_extension(".scm") ->
++ "application/x-lotusscreencam";
++from_extension(".mif") ->
++ "application/x-mif";
++from_extension(".com") ->
++ "application/x-msdos-program";
++from_extension(".exe") ->
++ "application/octet-stream";
++from_extension(".cdf") ->
++ "application/x-netcdf";
++from_extension(".nc") ->
++ "application/x-netcdf";
++from_extension(".pl") ->
++ "application/x-perl";
++from_extension(".pm") ->
++ "application/x-perl";
++from_extension(".rar") ->
++ "application/x-rar-compressed";
++from_extension(".sh") ->
++ "application/x-sh";
++from_extension(".shar") ->
++ "application/x-shar";
+ from_extension(".swf") ->
+ "application/x-shockwave-flash";
+-from_extension(".zip") ->
+- "application/zip";
+-from_extension(".bz2") ->
+- "application/x-bzip2";
+-from_extension(".gz") ->
+- "application/x-gzip";
++from_extension(".sit") ->
++ "application/x-stuffit";
++from_extension(".sv4cpio") ->
++ "application/x-sv4cpio";
++from_extension(".sv4crc") ->
++ "application/x-sv4crc";
++from_extension(".tar.gz") ->
++ "application/x-tar-gz";
++from_extension(".tgz") ->
++ "application/x-tar-gz";
+ from_extension(".tar") ->
+ "application/x-tar";
+-from_extension(".tgz") ->
+- "application/x-gzip";
++from_extension(".tcl") ->
++ "application/x-tcl";
++from_extension(".texi") ->
++ "application/x-texinfo";
++from_extension(".texinfo") ->
++ "application/x-texinfo";
++from_extension(".man") ->
++ "application/x-troff-man";
++from_extension(".me") ->
++ "application/x-troff-me";
++from_extension(".ms") ->
++ "application/x-troff-ms";
++from_extension(".roff") ->
++ "application/x-troff";
++from_extension(".t") ->
++ "application/x-troff";
++from_extension(".tr") ->
++ "application/x-troff";
++from_extension(".ustar") ->
++ "application/x-ustar";
++from_extension(".src") ->
++ "application/x-wais-source";
++from_extension(".zip") ->
++ "application/zip";
++from_extension(".tsi") ->
++ "audio/TSP-audio";
++from_extension(".au") ->
++ "audio/basic";
++from_extension(".snd") ->
++ "audio/basic";
++from_extension(".kar") ->
++ "audio/midi";
++from_extension(".mid") ->
++ "audio/midi";
++from_extension(".midi") ->
++ "audio/midi";
++from_extension(".mp2") ->
++ "audio/mpeg";
++from_extension(".mp3") ->
++ "audio/mpeg";
++from_extension(".mpga") ->
++ "audio/mpeg";
++from_extension(".aif") ->
++ "audio/x-aiff";
++from_extension(".aifc") ->
++ "audio/x-aiff";
++from_extension(".aiff") ->
++ "audio/x-aiff";
++from_extension(".m3u") ->
++ "audio/x-mpegurl";
++from_extension(".wax") ->
++ "audio/x-ms-wax";
++from_extension(".wma") ->
++ "audio/x-ms-wma";
++from_extension(".rpm") ->
++ "audio/x-pn-realaudio-plugin";
++from_extension(".ram") ->
++ "audio/x-pn-realaudio";
++from_extension(".rm") ->
++ "audio/x-pn-realaudio";
++from_extension(".ra") ->
++ "audio/x-realaudio";
++from_extension(".wav") ->
++ "audio/x-wav";
++from_extension(".pdb") ->
++ "chemical/x-pdb";
++from_extension(".ras") ->
++ "image/cmu-raster";
++from_extension(".gif") ->
++ "image/gif";
++from_extension(".ief") ->
++ "image/ief";
++from_extension(".jpe") ->
++ "image/jpeg";
++from_extension(".jpeg") ->
++ "image/jpeg";
++from_extension(".jpg") ->
++ "image/jpeg";
++from_extension(".jp2") ->
++ "image/jp2";
++from_extension(".png") ->
++ "image/png";
++from_extension(".tif") ->
++ "image/tiff";
++from_extension(".tiff") ->
++ "image/tiff";
++from_extension(".pnm") ->
++ "image/x-portable-anymap";
++from_extension(".pbm") ->
++ "image/x-portable-bitmap";
++from_extension(".pgm") ->
++ "image/x-portable-graymap";
++from_extension(".ppm") ->
++ "image/x-portable-pixmap";
++from_extension(".rgb") ->
++ "image/x-rgb";
++from_extension(".xbm") ->
++ "image/x-xbitmap";
++from_extension(".xwd") ->
++ "image/x-xwindowdump";
++from_extension(".iges") ->
++ "model/iges";
++from_extension(".igs") ->
++ "model/iges";
++from_extension(".mesh") ->
++ "model/mesh";
++from_extension(".") ->
++ "";
++from_extension(".msh") ->
++ "model/mesh";
++from_extension(".silo") ->
++ "model/mesh";
++from_extension(".vrml") ->
++ "model/vrml";
++from_extension(".wrl") ->
++ "model/vrml";
++from_extension(".css") ->
++ "text/css";
++from_extension(".htm") ->
++ "text/html";
++from_extension(".html") ->
++ "text/html";
++from_extension(".asc") ->
++ "text/plain";
++from_extension(".c") ->
++ "text/plain";
++from_extension(".cc") ->
++ "text/plain";
++from_extension(".f90") ->
++ "text/plain";
++from_extension(".f") ->
++ "text/plain";
++from_extension(".hh") ->
++ "text/plain";
++from_extension(".m") ->
++ "text/plain";
+ from_extension(".txt") ->
+ "text/plain";
+-from_extension(".doc") ->
+- "application/msword";
+-from_extension(".pdf") ->
+- "application/pdf";
+-from_extension(".xls") ->
+- "application/vnd.ms-excel";
+-from_extension(".rtf") ->
+- "application/rtf";
++from_extension(".rtx") ->
++ "text/richtext";
++from_extension(".sgm") ->
++ "text/sgml";
++from_extension(".sgml") ->
++ "text/sgml";
++from_extension(".tsv") ->
++ "text/tab-separated-values";
++from_extension(".jad") ->
++ "text/vnd.sun.j2me.app-descriptor";
++from_extension(".etx") ->
++ "text/x-setext";
++from_extension(".xml") ->
++ "application/xml";
++from_extension(".dl") ->
++ "video/dl";
++from_extension(".fli") ->
++ "video/fli";
++from_extension(".flv") ->
++ "video/x-flv";
++from_extension(".gl") ->
++ "video/gl";
++from_extension(".mp4") ->
++ "video/mp4";
++from_extension(".mpe") ->
++ "video/mpeg";
++from_extension(".mpeg") ->
++ "video/mpeg";
++from_extension(".mpg") ->
++ "video/mpeg";
+ from_extension(".mov") ->
+ "video/quicktime";
+-from_extension(".mp3") ->
+- "audio/mpeg";
++from_extension(".qt") ->
++ "video/quicktime";
++from_extension(".viv") ->
++ "video/vnd.vivo";
++from_extension(".vivo") ->
++ "video/vnd.vivo";
++from_extension(".asf") ->
++ "video/x-ms-asf";
++from_extension(".asx") ->
++ "video/x-ms-asx";
++from_extension(".wmv") ->
++ "video/x-ms-wmv";
++from_extension(".wmx") ->
++ "video/x-ms-wmx";
++from_extension(".wvx") ->
++ "video/x-ms-wvx";
++from_extension(".avi") ->
++ "video/x-msvideo";
++from_extension(".movie") ->
++ "video/x-sgi-movie";
++from_extension(".mime") ->
++ "www/mime";
++from_extension(".ice") ->
++ "x-conference/x-cooltalk";
++from_extension(".vrm") ->
++ "x-world/x-vrml";
++from_extension(".spx") ->
++ "audio/ogg";
++from_extension(".xhtml") ->
++ "application/xhtml+xml";
++from_extension(".bz2") ->
++ "application/x-bzip2";
++from_extension(".doc") ->
++ "application/msword";
+ from_extension(".z") ->
+ "application/x-compress";
+-from_extension(".wav") ->
+- "audio/x-wav";
+ from_extension(".ico") ->
+ "image/x-icon";
+ from_extension(".bmp") ->
+ "image/bmp";
+ from_extension(".m4a") ->
+ "audio/mpeg";
+-from_extension(".m3u") ->
+- "audio/x-mpegurl";
+-from_extension(".exe") ->
+- "application/octet-stream";
+ from_extension(".csv") ->
+ "text/csv";
++from_extension(".eot") ->
++ "application/vnd.ms-fontobject";
++from_extension(".m4v") ->
++ "video/mp4";
++from_extension(".svg") ->
++ "image/svg+xml";
++from_extension(".svgz") ->
++ "image/svg+xml";
++from_extension(".ttc") ->
++ "application/x-font-ttf";
++from_extension(".ttf") ->
++ "application/x-font-ttf";
++from_extension(".vcf") ->
++ "text/x-vcard";
++from_extension(".webm") ->
++ "video/web";
++from_extension(".webp") ->
++ "image/web";
++from_extension(".woff") ->
++ "application/x-font-woff";
++from_extension(".otf") ->
++ "font/opentype";
+ from_extension(_) ->
+ undefined.
+
+ %%
+ %% Tests
+ %%
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
++-include_lib("eunit/include/eunit.hrl").
+
+ exhaustive_from_extension_test() ->
+ T = mochiweb_cover:clause_lookup_table(?MODULE, from_extension),
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochiweb_multipart.erl apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_multipart.erl
+--- apache-couchdb-1.2.1/src/mochiweb/mochiweb_multipart.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_multipart.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -128,7 +128,7 @@
+
+ parse_multipart_request(Req, Callback) ->
+ %% TODO: Support chunked?
+- Length = list_to_integer(Req:get_header_value("content-length")),
++ Length = list_to_integer(Req:get_combined_header_value("content-length")),
+ Boundary = iolist_to_binary(
+ get_boundary(Req:get_header_value("content-type"))),
+ Prefix = <<"\r\n--", Boundary/binary>>,
+@@ -240,24 +240,22 @@
+ S
+ end.
+
+-find_in_binary(B, Data) when size(B) > 0 ->
+- case size(Data) - size(B) of
++%% @spec find_in_binary(Pattern::binary(), Data::binary()) ->
++%% {exact, N} | {partial, N, K} | not_found
++%% @doc Searches for the given pattern in the given binary.
++find_in_binary(P, Data) when size(P) > 0 ->
++ PS = size(P),
++ DS = size(Data),
++ case DS - PS of
+ Last when Last < 0 ->
+- partial_find(B, Data, 0, size(Data));
++ partial_find(P, Data, 0, DS);
+ Last ->
+- find_in_binary(B, size(B), Data, 0, Last)
++ case binary:match(Data, P) of
++ {Pos, _} -> {exact, Pos};
++ nomatch -> partial_find(P, Data, Last+1, PS-1)
++ end
+ end.
+
+-find_in_binary(B, BS, D, N, Last) when N =< Last->
+- case D of
+- <<_:N/binary, B:BS/binary, _/binary>> ->
+- {exact, N};
+- _ ->
+- find_in_binary(B, BS, D, 1 + N, Last)
+- end;
+-find_in_binary(B, BS, D, N, Last) when N =:= 1 + Last ->
+- partial_find(B, D, N, BS - 1).
+-
+ partial_find(_B, _D, _N, 0) ->
+ not_found;
+ partial_find(B, D, N, K) ->
+@@ -295,8 +293,8 @@
+ %%
+ %% Tests
+ %%
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
++-include_lib("eunit/include/eunit.hrl").
+
+ ssl_cert_opts() ->
+ EbinDir = filename:dirname(code:which(?MODULE)),
+@@ -313,7 +311,7 @@
+ ssl ->
+ ServerOpts0 ++ [{ssl, true}, {ssl_opts, ssl_cert_opts()}]
+ end,
+- {ok, Server} = mochiweb_socket_server:start(ServerOpts),
++ {ok, Server} = mochiweb_socket_server:start_link(ServerOpts),
+ Port = mochiweb_socket_server:get(Server, port),
+ ClientOpts = [binary, {active, false}],
+ {ok, Client} = case Transport of
+@@ -821,4 +819,54 @@
+ 10))),
+ ok.
+
++%% @todo Move somewhere more appropriate than in the test suite
++
++multipart_parsing_benchmark_test() ->
++ run_multipart_parsing_benchmark(1).
++
++run_multipart_parsing_benchmark(0) -> ok;
++run_multipart_parsing_benchmark(N) ->
++ multipart_parsing_benchmark(),
++ run_multipart_parsing_benchmark(N-1).
++
++multipart_parsing_benchmark() ->
++ ContentType = "multipart/form-data; boundary=----------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5",
++ Chunk = binary:copy(<<"This Is_%Some=Quite0Long4String2Used9For7BenchmarKing.5">>, 102400),
++ BinContent = <<"------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\nContent-Disposition: form-data; name=\"Filename\"\r\n\r\nhello.txt\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\nContent-Disposition: form-data; name=\"success_action_status\"\r\n\r\n201\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\nContent-Disposition: form-data; name=\"file\"; filename=\"hello.txt\"\r\nContent-Type: application/octet-stream\r\n\r\n", Chunk/binary, "\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\nContent-Disposition: form-data; name=\"Upload\"\r\n\r\nSubmit Query\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5--">>,
++ Expect = [{headers,
++ [{"content-disposition",
++ {"form-data", [{"name", "Filename"}]}}]},
++ {body, <<"hello.txt">>},
++ body_end,
++ {headers,
++ [{"content-disposition",
++ {"form-data", [{"name", "success_action_status"}]}}]},
++ {body, <<"201">>},
++ body_end,
++ {headers,
++ [{"content-disposition",
++ {"form-data", [{"name", "file"}, {"filename", "hello.txt"}]}},
++ {"content-type", {"application/octet-stream", []}}]},
++ {body, Chunk},
++ body_end,
++ {headers,
++ [{"content-disposition",
++ {"form-data", [{"name", "Upload"}]}}]},
++ {body, <<"Submit Query">>},
++ body_end,
++ eof],
++ TestCallback = fun (Next) -> test_callback(Next, Expect) end,
++ ServerFun = fun (Socket) ->
++ ok = mochiweb_socket:send(Socket, BinContent),
++ exit(normal)
++ end,
++ ClientFun = fun (Socket) ->
++ Req = fake_request(Socket, ContentType,
++ byte_size(BinContent)),
++ Res = parse_multipart_request(Req, TestCallback),
++ {0, <<>>, ok} = Res,
++ ok
++ end,
++ ok = with_socket_server(plain, ServerFun, ClientFun),
++ ok.
+ -endif.
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochiweb_request.erl apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_request.erl
+--- apache-couchdb-1.2.1/src/mochiweb/mochiweb_request.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_request.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -3,7 +3,7 @@
+
+ %% @doc MochiWeb HTTP Request abstraction.
+
+--module(mochiweb_request, [Socket, Method, RawPath, Version, Headers]).
++-module(mochiweb_request).
+ -author('bob@mochimedia.com').
+
+ -include_lib("kernel/include/file.hrl").
+@@ -11,17 +11,18 @@
+
+ -define(QUIP, "Any of you quaids got a smint?").
+
+--export([get_header_value/1, get_primary_header_value/1, get/1, dump/0]).
+--export([send/1, recv/1, recv/2, recv_body/0, recv_body/1, stream_body/3]).
+--export([start_response/1, start_response_length/1, start_raw_response/1]).
+--export([respond/1, ok/1]).
+--export([not_found/0, not_found/1]).
+--export([parse_post/0, parse_qs/0]).
+--export([should_close/0, cleanup/0]).
+--export([parse_cookie/0, get_cookie_value/1]).
+--export([serve_file/2, serve_file/3]).
+--export([accepted_encodings/1]).
+--export([accepts_content_type/1]).
++-export([new/5]).
++-export([get_header_value/2, get_primary_header_value/2, get_combined_header_value/2, get/2, dump/1]).
++-export([send/2, recv/2, recv/3, recv_body/1, recv_body/2, stream_body/4]).
++-export([start_response/2, start_response_length/2, start_raw_response/2]).
++-export([respond/2, ok/2]).
++-export([not_found/1, not_found/2]).
++-export([parse_post/1, parse_qs/1]).
++-export([should_close/1, cleanup/1]).
++-export([parse_cookie/1, get_cookie_value/2]).
++-export([serve_file/3, serve_file/4]).
++-export([accepted_encodings/2]).
++-export([accepts_content_type/2, accepted_content_types/2]).
+
+ -define(SAVE_QS, mochiweb_request_qs).
+ -define(SAVE_PATH, mochiweb_request_path).
+@@ -32,11 +33,10 @@
+ -define(SAVE_COOKIE, mochiweb_request_cookie).
+ -define(SAVE_FORCE_CLOSE, mochiweb_request_force_close).
+
+-%% @type iolist() = [iolist() | binary() | char()].
+-%% @type iodata() = binary() | iolist().
+ %% @type key() = atom() | string() | binary()
+ %% @type value() = atom() | string() | binary() | integer()
+ %% @type headers(). A mochiweb_headers structure.
++%% @type request(). A mochiweb_request parameterized module instance.
+ %% @type response(). A mochiweb_response parameterized module instance.
+ %% @type ioheaders() = headers() | [{key(), value()}].
+
+@@ -46,50 +46,58 @@
+ % Maximum recv_body() length of 1MB
+ -define(MAX_RECV_BODY, (1024*1024)).
+
+-%% @spec get_header_value(K) -> undefined | Value
++%% @spec new(Socket, Method, RawPath, Version, headers()) -> request()
++%% @doc Create a new request instance.
++new(Socket, Method, RawPath, Version, Headers) ->
++ {?MODULE, [Socket, Method, RawPath, Version, Headers]}.
++
++%% @spec get_header_value(K, request()) -> undefined | Value
+ %% @doc Get the value of a given request header.
+-get_header_value(K) ->
++get_header_value(K, {?MODULE, [_Socket, _Method, _RawPath, _Version, Headers]}) ->
+ mochiweb_headers:get_value(K, Headers).
+
+-get_primary_header_value(K) ->
++get_primary_header_value(K, {?MODULE, [_Socket, _Method, _RawPath, _Version, Headers]}) ->
+ mochiweb_headers:get_primary_value(K, Headers).
+
++get_combined_header_value(K, {?MODULE, [_Socket, _Method, _RawPath, _Version, Headers]}) ->
++ mochiweb_headers:get_combined_value(K, Headers).
++
+ %% @type field() = socket | scheme | method | raw_path | version | headers | peer | path | body_length | range
+
+-%% @spec get(field()) -> term()
++%% @spec get(field(), request()) -> term()
+ %% @doc Return the internal representation of the given field. If
+ %% <code>socket</code> is requested on a HTTPS connection, then
+ %% an ssl socket will be returned as <code>{ssl, SslSocket}</code>.
+ %% You can use <code>SslSocket</code> with the <code>ssl</code>
+ %% application, eg: <code>ssl:peercert(SslSocket)</code>.
+-get(socket) ->
++get(socket, {?MODULE, [Socket, _Method, _RawPath, _Version, _Headers]}) ->
+ Socket;
+-get(scheme) ->
++get(scheme, {?MODULE, [Socket, _Method, _RawPath, _Version, _Headers]}) ->
+ case mochiweb_socket:type(Socket) of
+ plain ->
+ http;
+ ssl ->
+ https
+ end;
+-get(method) ->
++get(method, {?MODULE, [_Socket, Method, _RawPath, _Version, _Headers]}) ->
+ Method;
+-get(raw_path) ->
++get(raw_path, {?MODULE, [_Socket, _Method, RawPath, _Version, _Headers]}) ->
+ RawPath;
+-get(version) ->
++get(version, {?MODULE, [_Socket, _Method, _RawPath, Version, _Headers]}) ->
+ Version;
+-get(headers) ->
++get(headers, {?MODULE, [_Socket, _Method, _RawPath, _Version, Headers]}) ->
+ Headers;
+-get(peer) ->
++get(peer, {?MODULE, [Socket, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+ case mochiweb_socket:peername(Socket) of
+ {ok, {Addr={10, _, _, _}, _Port}} ->
+- case get_header_value("x-forwarded-for") of
++ case get_header_value("x-forwarded-for", THIS) of
+ undefined ->
+ inet_parse:ntoa(Addr);
+ Hosts ->
+ string:strip(lists:last(string:tokens(Hosts, ",")))
+ end;
+ {ok, {{127, 0, 0, 1}, _Port}} ->
+- case get_header_value("x-forwarded-for") of
++ case get_header_value("x-forwarded-for", THIS) of
+ undefined ->
+ "127.0.0.1";
+ Hosts ->
+@@ -100,7 +108,7 @@
+ {error, enotconn} ->
+ exit(normal)
+ end;
+-get(path) ->
++get(path, {?MODULE, [_Socket, _Method, RawPath, _Version, _Headers]}) ->
+ case erlang:get(?SAVE_PATH) of
+ undefined ->
+ {Path0, _, _} = mochiweb_util:urlsplit_path(RawPath),
+@@ -110,35 +118,35 @@
+ Cached ->
+ Cached
+ end;
+-get(body_length) ->
++get(body_length, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+ case erlang:get(?SAVE_BODY_LENGTH) of
+ undefined ->
+- BodyLength = body_length(),
++ BodyLength = body_length(THIS),
+ put(?SAVE_BODY_LENGTH, {cached, BodyLength}),
+ BodyLength;
+ {cached, Cached} ->
+ Cached
+ end;
+-get(range) ->
+- case get_header_value(range) of
++get(range, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) ->
++ case get_header_value(range, THIS) of
+ undefined ->
+ undefined;
+ RawRange ->
+ mochiweb_http:parse_range_request(RawRange)
+ end.
+
+-%% @spec dump() -> {mochiweb_request, [{atom(), term()}]}
++%% @spec dump(request()) -> {mochiweb_request, [{atom(), term()}]}
+ %% @doc Dump the internal representation to a "human readable" set of terms
+ %% for debugging/inspection purposes.
+-dump() ->
++dump({?MODULE, [_Socket, Method, RawPath, Version, Headers]}) ->
+ {?MODULE, [{method, Method},
+ {version, Version},
+ {raw_path, RawPath},
+ {headers, mochiweb_headers:to_list(Headers)}]}.
+
+-%% @spec send(iodata()) -> ok
++%% @spec send(iodata(), request()) -> ok
+ %% @doc Send data over the socket.
+-send(Data) ->
++send(Data, {?MODULE, [Socket, _Method, _RawPath, _Version, _Headers]}) ->
+ case mochiweb_socket:send(Socket, Data) of
+ ok ->
+ ok;
+@@ -146,16 +154,16 @@
+ exit(normal)
+ end.
+
+-%% @spec recv(integer()) -> binary()
++%% @spec recv(integer(), request()) -> binary()
+ %% @doc Receive Length bytes from the client as a binary, with the default
+ %% idle timeout.
+-recv(Length) ->
+- recv(Length, ?IDLE_TIMEOUT).
++recv(Length, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) ->
++ recv(Length, ?IDLE_TIMEOUT, THIS).
+
+-%% @spec recv(integer(), integer()) -> binary()
++%% @spec recv(integer(), integer(), request()) -> binary()
+ %% @doc Receive Length bytes from the client as a binary, with the given
+ %% Timeout in msec.
+-recv(Length, Timeout) ->
++recv(Length, Timeout, {?MODULE, [Socket, _Method, _RawPath, _Version, _Headers]}) ->
+ case mochiweb_socket:recv(Socket, Length, Timeout) of
+ {ok, Data} ->
+ put(?SAVE_RECV, true),
+@@ -164,12 +172,12 @@
+ exit(normal)
+ end.
+
+-%% @spec body_length() -> undefined | chunked | unknown_transfer_encoding | integer()
++%% @spec body_length(request()) -> undefined | chunked | unknown_transfer_encoding | integer()
+ %% @doc Infer body length from transfer-encoding and content-length headers.
+-body_length() ->
+- case get_header_value("transfer-encoding") of
++body_length({?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) ->
++ case get_header_value("transfer-encoding", THIS) of
+ undefined ->
+- case get_header_value("content-length") of
++ case get_combined_header_value("content-length", THIS) of
+ undefined ->
+ undefined;
+ Length ->
+@@ -182,16 +190,16 @@
+ end.
+
+
+-%% @spec recv_body() -> binary()
++%% @spec recv_body(request()) -> binary()
+ %% @doc Receive the body of the HTTP request (defined by Content-Length).
+ %% Will only receive up to the default max-body length of 1MB.
+-recv_body() ->
+- recv_body(?MAX_RECV_BODY).
++recv_body({?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) ->
++ recv_body(?MAX_RECV_BODY, THIS).
+
+-%% @spec recv_body(integer()) -> binary()
++%% @spec recv_body(integer(), request()) -> binary()
+ %% @doc Receive the body of the HTTP request (defined by Content-Length).
+ %% Will receive up to MaxBody bytes.
+-recv_body(MaxBody) ->
++recv_body(MaxBody, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+ case erlang:get(?SAVE_BODY) of
+ undefined ->
+ % we could use a sane constant for max chunk size
+@@ -205,17 +213,18 @@
+ true ->
+ {NewLength, [Bin | BinAcc]}
+ end
+- end, {0, []}, MaxBody),
++ end, {0, []}, MaxBody, THIS),
+ put(?SAVE_BODY, Body),
+ Body;
+ Cached -> Cached
+ end.
+
+-stream_body(MaxChunkSize, ChunkFun, FunState) ->
+- stream_body(MaxChunkSize, ChunkFun, FunState, undefined).
++stream_body(MaxChunkSize, ChunkFun, FunState, {?MODULE,[_Socket,_Method,_RawPath,_Version,_Headers]}=THIS) ->
++ stream_body(MaxChunkSize, ChunkFun, FunState, undefined, THIS).
+
+-stream_body(MaxChunkSize, ChunkFun, FunState, MaxBodyLength) ->
+- Expect = case get_header_value("expect") of
++stream_body(MaxChunkSize, ChunkFun, FunState, MaxBodyLength,
++ {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) ->
++ Expect = case get_header_value("expect", THIS) of
+ undefined ->
+ undefined;
+ Value when is_list(Value) ->
+@@ -223,11 +232,12 @@
+ end,
+ case Expect of
+ "100-continue" ->
+- start_raw_response({100, gb_trees:empty()});
++ _ = start_raw_response({100, gb_trees:empty()}, THIS),
++ ok;
+ _Else ->
+ ok
+ end,
+- case body_length() of
++ case body_length(THIS) of
+ undefined ->
+ undefined;
+ {unknown_transfer_encoding, Unknown} ->
+@@ -236,7 +246,7 @@
+ % In this case the MaxBody is actually used to
+ % determine the maximum allowed size of a single
+ % chunk.
+- stream_chunked_body(MaxChunkSize, ChunkFun, FunState);
++ stream_chunked_body(MaxChunkSize, ChunkFun, FunState, THIS);
+ 0 ->
+ <<>>;
+ Length when is_integer(Length) ->
+@@ -244,62 +254,64 @@
+ MaxBodyLength when is_integer(MaxBodyLength), MaxBodyLength < Length ->
+ exit({body_too_large, content_length});
+ _ ->
+- stream_unchunked_body(Length, ChunkFun, FunState)
+- end;
+- Length ->
+- exit({length_not_integer, Length})
++ stream_unchunked_body(Length, ChunkFun, FunState, THIS)
++ end
+ end.
+
+
+-%% @spec start_response({integer(), ioheaders()}) -> response()
++%% @spec start_response({integer(), ioheaders()}, request()) -> response()
+ %% @doc Start the HTTP response by sending the Code HTTP response and
+ %% ResponseHeaders. The server will set header defaults such as Server
+ %% and Date if not present in ResponseHeaders.
+-start_response({Code, ResponseHeaders}) ->
++start_response({Code, ResponseHeaders}, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+ HResponse = mochiweb_headers:make(ResponseHeaders),
+ HResponse1 = mochiweb_headers:default_from_list(server_headers(),
+ HResponse),
+- start_raw_response({Code, HResponse1}).
++ start_raw_response({Code, HResponse1}, THIS).
+
+-%% @spec start_raw_response({integer(), headers()}) -> response()
++%% @spec start_raw_response({integer(), headers()}, request()) -> response()
+ %% @doc Start the HTTP response by sending the Code HTTP response and
+ %% ResponseHeaders.
+-start_raw_response({Code, ResponseHeaders}) ->
++start_raw_response({Code, ResponseHeaders}, {?MODULE, [_Socket, _Method, _RawPath, Version, _Headers]}=THIS) ->
+ F = fun ({K, V}, Acc) ->
+ [mochiweb_util:make_io(K), <<": ">>, V, <<"\r\n">> | Acc]
+ end,
+ End = lists:foldl(F, [<<"\r\n">>],
+ mochiweb_headers:to_list(ResponseHeaders)),
+- send([make_version(Version), make_code(Code), <<"\r\n">> | End]),
++ send([make_version(Version), make_code(Code), <<"\r\n">> | End], THIS),
+ mochiweb:new_response({THIS, Code, ResponseHeaders}).
+
+
+-%% @spec start_response_length({integer(), ioheaders(), integer()}) -> response()
++%% @spec start_response_length({integer(), ioheaders(), integer()}, request()) -> response()
+ %% @doc Start the HTTP response by sending the Code HTTP response and
+ %% ResponseHeaders including a Content-Length of Length. The server
+ %% will set header defaults such as Server
+ %% and Date if not present in ResponseHeaders.
+-start_response_length({Code, ResponseHeaders, Length}) ->
++start_response_length({Code, ResponseHeaders, Length},
++ {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+ HResponse = mochiweb_headers:make(ResponseHeaders),
+ HResponse1 = mochiweb_headers:enter("Content-Length", Length, HResponse),
+- start_response({Code, HResponse1}).
++ start_response({Code, HResponse1}, THIS).
+
+-%% @spec respond({integer(), ioheaders(), iodata() | chunked | {file, IoDevice}}) -> response()
++%% @spec respond({integer(), ioheaders(), iodata() | chunked | {file, IoDevice}}, request()) -> response()
+ %% @doc Start the HTTP response with start_response, and send Body to the
+ %% client (if the get(method) /= 'HEAD'). The Content-Length header
+ %% will be set by the Body length, and the server will insert header
+ %% defaults.
+-respond({Code, ResponseHeaders, {file, IoDevice}}) ->
++respond({Code, ResponseHeaders, {file, IoDevice}},
++ {?MODULE, [_Socket, Method, _RawPath, _Version, _Headers]}=THIS) ->
+ Length = mochiweb_io:iodevice_size(IoDevice),
+- Response = start_response_length({Code, ResponseHeaders, Length}),
++ Response = start_response_length({Code, ResponseHeaders, Length}, THIS),
+ case Method of
+ 'HEAD' ->
+ ok;
+ _ ->
+- mochiweb_io:iodevice_stream(fun send/1, IoDevice)
++ mochiweb_io:iodevice_stream(
++ fun (Body) -> send(Body, THIS) end,
++ IoDevice)
+ end,
+ Response;
+-respond({Code, ResponseHeaders, chunked}) ->
++respond({Code, ResponseHeaders, chunked}, {?MODULE, [_Socket, Method, _RawPath, Version, _Headers]}=THIS) ->
+ HResponse = mochiweb_headers:make(ResponseHeaders),
+ HResponse1 = case Method of
+ 'HEAD' ->
+@@ -320,35 +332,35 @@
+ put(?SAVE_FORCE_CLOSE, true),
+ HResponse
+ end,
+- start_response({Code, HResponse1});
+-respond({Code, ResponseHeaders, Body}) ->
+- Response = start_response_length({Code, ResponseHeaders, iolist_size(Body)}),
++ start_response({Code, HResponse1}, THIS);
++respond({Code, ResponseHeaders, Body}, {?MODULE, [_Socket, Method, _RawPath, _Version, _Headers]}=THIS) ->
++ Response = start_response_length({Code, ResponseHeaders, iolist_size(Body)}, THIS),
+ case Method of
+ 'HEAD' ->
+ ok;
+ _ ->
+- send(Body)
++ send(Body, THIS)
+ end,
+ Response.
+
+-%% @spec not_found() -> response()
++%% @spec not_found(request()) -> response()
+ %% @doc Alias for <code>not_found([])</code>.
+-not_found() ->
+- not_found([]).
++not_found({?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) ->
++ not_found([], THIS).
+
+-%% @spec not_found(ExtraHeaders) -> response()
++%% @spec not_found(ExtraHeaders, request()) -> response()
+ %% @doc Alias for <code>respond({404, [{"Content-Type", "text/plain"}
+ %% | ExtraHeaders], &lt;&lt;"Not found."&gt;&gt;})</code>.
+-not_found(ExtraHeaders) ->
++not_found(ExtraHeaders, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+ respond({404, [{"Content-Type", "text/plain"} | ExtraHeaders],
+- <<"Not found.">>}).
++ <<"Not found.">>}, THIS).
+
+-%% @spec ok({value(), iodata()} | {value(), ioheaders(), iodata() | {file, IoDevice}}) ->
++%% @spec ok({value(), iodata()} | {value(), ioheaders(), iodata() | {file, IoDevice}}, request()) ->
+ %% response()
+ %% @doc respond({200, [{"Content-Type", ContentType} | Headers], Body}).
+-ok({ContentType, Body}) ->
+- ok({ContentType, [], Body});
+-ok({ContentType, ResponseHeaders, Body}) ->
++ok({ContentType, Body}, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) ->
++ ok({ContentType, [], Body}, THIS);
++ok({ContentType, ResponseHeaders, Body}, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+ HResponse = mochiweb_headers:make(ResponseHeaders),
+ case THIS:get(range) of
+ X when (X =:= undefined orelse X =:= fail) orelse Body =:= chunked ->
+@@ -357,7 +369,7 @@
+ %% full response.
+ HResponse1 = mochiweb_headers:enter("Content-Type", ContentType,
+ HResponse),
+- respond({200, HResponse1, Body});
++ respond({200, HResponse1, Body}, THIS);
+ Ranges ->
+ {PartList, Size} = range_parts(Body, Ranges),
+ case PartList of
+@@ -366,7 +378,7 @@
+ ContentType,
+ HResponse),
+ %% could be 416, for now we'll just return 200
+- respond({200, HResponse1, Body});
++ respond({200, HResponse1, Body}, THIS);
+ PartList ->
+ {RangeHeaders, RangeBody} =
+ mochiweb_multipart:parts_to_body(PartList, ContentType, Size),
+@@ -374,46 +386,50 @@
+ [{"Accept-Ranges", "bytes"} |
+ RangeHeaders],
+ HResponse),
+- respond({206, HResponse1, RangeBody})
++ respond({206, HResponse1, RangeBody}, THIS)
+ end
+ end.
+
+-%% @spec should_close() -> bool()
++%% @spec should_close(request()) -> bool()
+ %% @doc Return true if the connection must be closed. If false, using
+ %% Keep-Alive should be safe.
+-should_close() ->
++should_close({?MODULE, [_Socket, _Method, _RawPath, Version, _Headers]}=THIS) ->
+ ForceClose = erlang:get(?SAVE_FORCE_CLOSE) =/= undefined,
+ DidNotRecv = erlang:get(?SAVE_RECV) =:= undefined,
+ ForceClose orelse Version < {1, 0}
+ %% Connection: close
+- orelse get_header_value("connection") =:= "close"
++ orelse is_close(get_header_value("connection", THIS))
+ %% HTTP 1.0 requires Connection: Keep-Alive
+ orelse (Version =:= {1, 0}
+- andalso get_header_value("connection") =/= "Keep-Alive")
++ andalso get_header_value("connection", THIS) =/= "Keep-Alive")
+ %% unread data left on the socket, can't safely continue
+ orelse (DidNotRecv
+- andalso get_header_value("content-length") =/= undefined
+- andalso list_to_integer(get_header_value("content-length")) > 0)
++ andalso get_combined_header_value("content-length", THIS) =/= undefined
++ andalso list_to_integer(get_combined_header_value("content-length", THIS)) > 0)
+ orelse (DidNotRecv
+- andalso get_header_value("transfer-encoding") =:= "chunked").
++ andalso get_header_value("transfer-encoding", THIS) =:= "chunked").
++
++is_close("close") ->
++ true;
++is_close(S=[_C, _L, _O, _S, _E]) ->
++ string:to_lower(S) =:= "close";
++is_close(_) ->
++ false.
+
+-%% @spec cleanup() -> ok
++%% @spec cleanup(request()) -> ok
+ %% @doc Clean up any junk in the process dictionary, required before continuing
+ %% a Keep-Alive request.
+-cleanup() ->
+- [erase(K) || K <- [?SAVE_QS,
+- ?SAVE_PATH,
+- ?SAVE_RECV,
+- ?SAVE_BODY,
+- ?SAVE_BODY_LENGTH,
+- ?SAVE_POST,
+- ?SAVE_COOKIE,
+- ?SAVE_FORCE_CLOSE]],
++cleanup({?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}) ->
++ L = [?SAVE_QS, ?SAVE_PATH, ?SAVE_RECV, ?SAVE_BODY, ?SAVE_BODY_LENGTH,
++ ?SAVE_POST, ?SAVE_COOKIE, ?SAVE_FORCE_CLOSE],
++ lists:foreach(fun(K) ->
++ erase(K)
++ end, L),
+ ok.
+
+-%% @spec parse_qs() -> [{Key::string(), Value::string()}]
++%% @spec parse_qs(request()) -> [{Key::string(), Value::string()}]
+ %% @doc Parse the query string of the URL.
+-parse_qs() ->
++parse_qs({?MODULE, [_Socket, _Method, RawPath, _Version, _Headers]}) ->
+ case erlang:get(?SAVE_QS) of
+ undefined ->
+ {_, QueryString, _} = mochiweb_util:urlsplit_path(RawPath),
+@@ -424,17 +440,17 @@
+ Cached
+ end.
+
+-%% @spec get_cookie_value(Key::string) -> string() | undefined
++%% @spec get_cookie_value(Key::string, request()) -> string() | undefined
+ %% @doc Get the value of the given cookie.
+-get_cookie_value(Key) ->
+- proplists:get_value(Key, parse_cookie()).
++get_cookie_value(Key, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) ->
++ proplists:get_value(Key, parse_cookie(THIS)).
+
+-%% @spec parse_cookie() -> [{Key::string(), Value::string()}]
++%% @spec parse_cookie(request()) -> [{Key::string(), Value::string()}]
+ %% @doc Parse the cookie header.
+-parse_cookie() ->
++parse_cookie({?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+ case erlang:get(?SAVE_COOKIE) of
+ undefined ->
+- Cookies = case get_header_value("cookie") of
++ Cookies = case get_header_value("cookie", THIS) of
+ undefined ->
+ [];
+ Value ->
+@@ -446,17 +462,17 @@
+ Cached
+ end.
+
+-%% @spec parse_post() -> [{Key::string(), Value::string()}]
++%% @spec parse_post(request()) -> [{Key::string(), Value::string()}]
+ %% @doc Parse an application/x-www-form-urlencoded form POST. This
+ %% has the side-effect of calling recv_body().
+-parse_post() ->
++parse_post({?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+ case erlang:get(?SAVE_POST) of
+ undefined ->
+- Parsed = case recv_body() of
++ Parsed = case recv_body(THIS) of
+ undefined ->
+ [];
+ Binary ->
+- case get_primary_header_value("content-type") of
++ case get_primary_header_value("content-type",THIS) of
+ "application/x-www-form-urlencoded" ++ _ ->
+ mochiweb_util:parse_qs(Binary);
+ _ ->
+@@ -469,41 +485,43 @@
+ Cached
+ end.
+
+-%% @spec stream_chunked_body(integer(), fun(), term()) -> term()
++%% @spec stream_chunked_body(integer(), fun(), term(), request()) -> term()
+ %% @doc The function is called for each chunk.
+ %% Used internally by read_chunked_body.
+-stream_chunked_body(MaxChunkSize, Fun, FunState) ->
+- case read_chunk_length() of
++stream_chunked_body(MaxChunkSize, Fun, FunState,
++ {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) ->
++ case read_chunk_length(THIS) of
+ 0 ->
+- Fun({0, read_chunk(0)}, FunState);
++ Fun({0, read_chunk(0, THIS)}, FunState);
+ Length when Length > MaxChunkSize ->
+- NewState = read_sub_chunks(Length, MaxChunkSize, Fun, FunState),
+- stream_chunked_body(MaxChunkSize, Fun, NewState);
++ NewState = read_sub_chunks(Length, MaxChunkSize, Fun, FunState, THIS),
++ stream_chunked_body(MaxChunkSize, Fun, NewState, THIS);
+ Length ->
+- NewState = Fun({Length, read_chunk(Length)}, FunState),
+- stream_chunked_body(MaxChunkSize, Fun, NewState)
++ NewState = Fun({Length, read_chunk(Length, THIS)}, FunState),
++ stream_chunked_body(MaxChunkSize, Fun, NewState, THIS)
+ end.
+
+-stream_unchunked_body(0, Fun, FunState) ->
++stream_unchunked_body(0, Fun, FunState, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}) ->
+ Fun({0, <<>>}, FunState);
+-stream_unchunked_body(Length, Fun, FunState) when Length > 0 ->
++stream_unchunked_body(Length, Fun, FunState,
++ {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) when Length > 0 ->
+ PktSize = case Length > ?RECBUF_SIZE of
+ true ->
+ ?RECBUF_SIZE;
+ false ->
+ Length
+ end,
+- Bin = recv(PktSize),
++ Bin = recv(PktSize, THIS),
+ NewState = Fun({PktSize, Bin}, FunState),
+- stream_unchunked_body(Length - PktSize, Fun, NewState).
++ stream_unchunked_body(Length - PktSize, Fun, NewState, THIS).
+
+-%% @spec read_chunk_length() -> integer()
++%% @spec read_chunk_length(request()) -> integer()
+ %% @doc Read the length of the next HTTP chunk.
+-read_chunk_length() ->
+- mochiweb_socket:setopts(Socket, [{packet, line}]),
++read_chunk_length({?MODULE, [Socket, _Method, _RawPath, _Version, _Headers]}) ->
++ ok = mochiweb_socket:setopts(Socket, [{packet, line}]),
+ case mochiweb_socket:recv(Socket, 0, ?IDLE_TIMEOUT) of
+ {ok, Header} ->
+- mochiweb_socket:setopts(Socket, [{packet, raw}]),
++ ok = mochiweb_socket:setopts(Socket, [{packet, raw}]),
+ Splitter = fun (C) ->
+ C =/= $\r andalso C =/= $\n andalso C =/= $
+ end,
+@@ -513,11 +531,11 @@
+ exit(normal)
+ end.
+
+-%% @spec read_chunk(integer()) -> Chunk::binary() | [Footer::binary()]
++%% @spec read_chunk(integer(), request()) -> Chunk::binary() | [Footer::binary()]
+ %% @doc Read in a HTTP chunk of the given length. If Length is 0, then read the
+ %% HTTP footers (as a list of binaries, since they're nominal).
+-read_chunk(0) ->
+- mochiweb_socket:setopts(Socket, [{packet, line}]),
++read_chunk(0, {?MODULE, [Socket, _Method, _RawPath, _Version, _Headers]}) ->
++ ok = mochiweb_socket:setopts(Socket, [{packet, line}]),
+ F = fun (F1, Acc) ->
+ case mochiweb_socket:recv(Socket, 0, ?IDLE_TIMEOUT) of
+ {ok, <<"\r\n">>} ->
+@@ -529,10 +547,10 @@
+ end
+ end,
+ Footers = F(F, []),
+- mochiweb_socket:setopts(Socket, [{packet, raw}]),
++ ok = mochiweb_socket:setopts(Socket, [{packet, raw}]),
+ put(?SAVE_RECV, true),
+ Footers;
+-read_chunk(Length) ->
++read_chunk(Length, {?MODULE, [Socket, _Method, _RawPath, _Version, _Headers]}) ->
+ case mochiweb_socket:recv(Socket, 2 + Length, ?IDLE_TIMEOUT) of
+ {ok, <<Chunk:Length/binary, "\r\n">>} ->
+ Chunk;
+@@ -540,32 +558,34 @@
+ exit(normal)
+ end.
+
+-read_sub_chunks(Length, MaxChunkSize, Fun, FunState) when Length > MaxChunkSize ->
+- Bin = recv(MaxChunkSize),
++read_sub_chunks(Length, MaxChunkSize, Fun, FunState,
++ {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) when Length > MaxChunkSize ->
++ Bin = recv(MaxChunkSize, THIS),
+ NewState = Fun({size(Bin), Bin}, FunState),
+- read_sub_chunks(Length - MaxChunkSize, MaxChunkSize, Fun, NewState);
++ read_sub_chunks(Length - MaxChunkSize, MaxChunkSize, Fun, NewState, THIS);
+
+-read_sub_chunks(Length, _MaxChunkSize, Fun, FunState) ->
+- Fun({Length, read_chunk(Length)}, FunState).
++read_sub_chunks(Length, _MaxChunkSize, Fun, FunState,
++ {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) ->
++ Fun({Length, read_chunk(Length, THIS)}, FunState).
+
+-%% @spec serve_file(Path, DocRoot) -> Response
++%% @spec serve_file(Path, DocRoot, request()) -> Response
+ %% @doc Serve a file relative to DocRoot.
+-serve_file(Path, DocRoot) ->
+- serve_file(Path, DocRoot, []).
++serve_file(Path, DocRoot, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) ->
++ serve_file(Path, DocRoot, [], THIS).
+
+-%% @spec serve_file(Path, DocRoot, ExtraHeaders) -> Response
++%% @spec serve_file(Path, DocRoot, ExtraHeaders, request()) -> Response
+ %% @doc Serve a file relative to DocRoot.
+-serve_file(Path, DocRoot, ExtraHeaders) ->
++serve_file(Path, DocRoot, ExtraHeaders, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+ case mochiweb_util:safe_relative_path(Path) of
+ undefined ->
+- not_found(ExtraHeaders);
++ not_found(ExtraHeaders, THIS);
+ RelPath ->
+ FullPath = filename:join([DocRoot, RelPath]),
+ case filelib:is_dir(FullPath) of
+ true ->
+- maybe_redirect(RelPath, FullPath, ExtraHeaders);
++ maybe_redirect(RelPath, FullPath, ExtraHeaders, THIS);
+ false ->
+- maybe_serve_file(FullPath, ExtraHeaders)
++ maybe_serve_file(FullPath, ExtraHeaders, THIS)
+ end
+ end.
+
+@@ -575,13 +595,14 @@
+ directory_index(FullPath) ->
+ filename:join([FullPath, "index.html"]).
+
+-maybe_redirect([], FullPath, ExtraHeaders) ->
+- maybe_serve_file(directory_index(FullPath), ExtraHeaders);
++maybe_redirect([], FullPath, ExtraHeaders, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) ->
++ maybe_serve_file(directory_index(FullPath), ExtraHeaders, THIS);
+
+-maybe_redirect(RelPath, FullPath, ExtraHeaders) ->
++maybe_redirect(RelPath, FullPath, ExtraHeaders,
++ {?MODULE, [_Socket, _Method, _RawPath, _Version, Headers]}=THIS) ->
+ case string:right(RelPath, 1) of
+ "/" ->
+- maybe_serve_file(directory_index(FullPath), ExtraHeaders);
++ maybe_serve_file(directory_index(FullPath), ExtraHeaders, THIS);
+ _ ->
+ Host = mochiweb_headers:get_value("host", Headers),
+ Location = "http://" ++ Host ++ "/" ++ RelPath ++ "/",
+@@ -596,16 +617,16 @@
+ "<p>The document has moved <a href=\"">>,
+ Bottom = <<">here</a>.</p></body></html>\n">>,
+ Body = <<Top/binary, LocationBin/binary, Bottom/binary>>,
+- respond({301, MoreHeaders, Body})
++ respond({301, MoreHeaders, Body}, THIS)
+ end.
+
+-maybe_serve_file(File, ExtraHeaders) ->
++maybe_serve_file(File, ExtraHeaders, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+ case file:read_file_info(File) of
+ {ok, FileInfo} ->
+ LastModified = httpd_util:rfc1123_date(FileInfo#file_info.mtime),
+- case get_header_value("if-modified-since") of
++ case get_header_value("if-modified-since", THIS) of
+ LastModified ->
+- respond({304, ExtraHeaders, ""});
++ respond({304, ExtraHeaders, ""}, THIS);
+ _ ->
+ case file:open(File, [raw, binary]) of
+ {ok, IoDevice} ->
+@@ -613,15 +634,15 @@
+ Res = ok({ContentType,
+ [{"last-modified", LastModified}
+ | ExtraHeaders],
+- {file, IoDevice}}),
+- file:close(IoDevice),
++ {file, IoDevice}}, THIS),
++ ok = file:close(IoDevice),
+ Res;
+ _ ->
+- not_found(ExtraHeaders)
++ not_found(ExtraHeaders, THIS)
+ end
+ end;
+ {error, _} ->
+- not_found(ExtraHeaders)
++ not_found(ExtraHeaders, THIS)
+ end.
+
+ server_headers() ->
+@@ -669,7 +690,7 @@
+ end,
+ {lists:foldr(F, [], Ranges), Size}.
+
+-%% @spec accepted_encodings([encoding()]) -> [encoding()] | bad_accept_encoding_value
++%% @spec accepted_encodings([encoding()], request()) -> [encoding()] | bad_accept_encoding_value
+ %% @type encoding() = string().
+ %%
+ %% @doc Returns a list of encodings accepted by a request. Encodings that are
+@@ -693,8 +714,8 @@
+ %% accepted_encodings(["gzip", "deflate", "identity"]) ->
+ %% ["deflate", "gzip", "identity"]
+ %%
+-accepted_encodings(SupportedEncodings) ->
+- AcceptEncodingHeader = case get_header_value("Accept-Encoding") of
++accepted_encodings(SupportedEncodings, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) ->
++ AcceptEncodingHeader = case get_header_value("Accept-Encoding", THIS) of
+ undefined ->
+ "";
+ Value ->
+@@ -709,7 +730,7 @@
+ )
+ end.
+
+-%% @spec accepts_content_type(string() | binary()) -> boolean() | bad_accept_header
++%% @spec accepts_content_type(string() | binary(), request()) -> boolean() | bad_accept_header
+ %%
+ %% @doc Determines whether a request accepts a given media type by analyzing its
+ %% "Accept" header.
+@@ -731,16 +752,9 @@
+ %% 5) For an "Accept" header with value "text/*; q=0.0, */*":
+ %% accepts_content_type("text/plain") -> false
+ %%
+-accepts_content_type(ContentType) when is_binary(ContentType) ->
+- accepts_content_type(binary_to_list(ContentType));
+-accepts_content_type(ContentType1) ->
++accepts_content_type(ContentType1, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) ->
+ ContentType = re:replace(ContentType1, "\\s", "", [global, {return, list}]),
+- AcceptHeader = case get_header_value("Accept") of
+- undefined ->
+- "*/*";
+- Value ->
+- Value
+- end,
++ AcceptHeader = accept_header(THIS),
+ case mochiweb_util:parse_qvalues(AcceptHeader) of
+ invalid_qvalue_string ->
+ bad_accept_header;
+@@ -761,9 +775,83 @@
+ (not lists:member({SuperType, 0.0}, QList))
+ end.
+
++%% @spec accepted_content_types([string() | binary()], request()) -> [string()] | bad_accept_header
++%%
++%% @doc Filters which of the given media types this request accepts. This filtering
++%% is performed by analyzing the "Accept" header. The returned list is sorted
++%% according to the preferences specified in the "Accept" header (higher Q values
++%% first). If two or more types have the same preference (Q value), they're order
++%% in the returned list is the same as they're order in the input list.
++%%
++%% Examples
++%%
++%% 1) For a missing "Accept" header:
++%% accepted_content_types(["text/html", "application/json"]) ->
++%% ["text/html", "application/json"]
++%%
++%% 2) For an "Accept" header with value "text/html, application/*":
++%% accepted_content_types(["application/json", "text/html"]) ->
++%% ["application/json", "text/html"]
++%%
++%% 3) For an "Accept" header with value "text/html, */*; q=0.0":
++%% accepted_content_types(["text/html", "application/json"]) ->
++%% ["text/html"]
++%%
++%% 4) For an "Accept" header with value "text/html; q=0.5, */*; q=0.1":
++%% accepts_content_types(["application/json", "text/html"]) ->
++%% ["text/html", "application/json"]
++%%
++accepted_content_types(Types1, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) ->
++ Types = lists:map(
++ fun(T) -> re:replace(T, "\\s", "", [global, {return, list}]) end,
++ Types1),
++ AcceptHeader = accept_header(THIS),
++ case mochiweb_util:parse_qvalues(AcceptHeader) of
++ invalid_qvalue_string ->
++ bad_accept_header;
++ QList ->
++ TypesQ = lists:foldr(
++ fun(T, Acc) ->
++ case proplists:get_value(T, QList) of
++ undefined ->
++ [MainType, _SubType] = string:tokens(T, "/"),
++ case proplists:get_value(MainType ++ "/*", QList) of
++ undefined ->
++ case proplists:get_value("*/*", QList) of
++ Q when is_float(Q), Q > 0.0 ->
++ [{Q, T} | Acc];
++ _ ->
++ Acc
++ end;
++ Q when Q > 0.0 ->
++ [{Q, T} | Acc];
++ _ ->
++ Acc
++ end;
++ Q when Q > 0.0 ->
++ [{Q, T} | Acc];
++ _ ->
++ Acc
++ end
++ end,
++ [], Types),
++ % Note: Stable sort. If 2 types have the same Q value we leave them in the
++ % same order as in the input list.
++ SortFun = fun({Q1, _}, {Q2, _}) -> Q1 >= Q2 end,
++ [Type || {_Q, Type} <- lists:sort(SortFun, TypesQ)]
++ end.
++
++accept_header({?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) ->
++ case get_header_value("Accept", THIS) of
++ undefined ->
++ "*/*";
++ Value ->
++ Value
++ end.
++
+ %%
+ %% Tests
+ %%
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
++-include_lib("eunit/include/eunit.hrl").
+ -endif.
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochiweb_request_tests.erl apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_request_tests.erl
+--- apache-couchdb-1.2.1/src/mochiweb/mochiweb_request_tests.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_request_tests.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -1,12 +1,13 @@
+ -module(mochiweb_request_tests).
+
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
++-include_lib("eunit/include/eunit.hrl").
+
+ accepts_content_type_test() ->
+ Req1 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
+ mochiweb_headers:make([{"Accept", "multipart/related"}])),
+ ?assertEqual(true, Req1:accepts_content_type("multipart/related")),
++ ?assertEqual(true, Req1:accepts_content_type(<<"multipart/related">>)),
+
+ Req2 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
+ mochiweb_headers:make([{"Accept", "text/html"}])),
+@@ -60,4 +61,122 @@
+ mochiweb_headers:make([{"Accept", "text/html;level=1;q=0.1, text/html"}])),
+ ?assertEqual(true, Req14:accepts_content_type("text/html; level=1")).
+
++accepted_encodings_test() ->
++ Req1 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
++ mochiweb_headers:make([])),
++ ?assertEqual(["identity"],
++ Req1:accepted_encodings(["gzip", "identity"])),
++
++ Req2 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
++ mochiweb_headers:make([{"Accept-Encoding", "gzip, deflate"}])),
++ ?assertEqual(["gzip", "identity"],
++ Req2:accepted_encodings(["gzip", "identity"])),
++
++ Req3 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
++ mochiweb_headers:make([{"Accept-Encoding", "gzip;q=0.5, deflate"}])),
++ ?assertEqual(["deflate", "gzip", "identity"],
++ Req3:accepted_encodings(["gzip", "deflate", "identity"])),
++
++ Req4 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
++ mochiweb_headers:make([{"Accept-Encoding", "identity, *;q=0"}])),
++ ?assertEqual(["identity"],
++ Req4:accepted_encodings(["gzip", "deflate", "identity"])),
++
++ Req5 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
++ mochiweb_headers:make([{"Accept-Encoding", "gzip; q=0.1, *;q=0"}])),
++ ?assertEqual(["gzip"],
++ Req5:accepted_encodings(["gzip", "deflate", "identity"])),
++
++ Req6 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
++ mochiweb_headers:make([{"Accept-Encoding", "gzip; q=, *;q=0"}])),
++ ?assertEqual(bad_accept_encoding_value,
++ Req6:accepted_encodings(["gzip", "deflate", "identity"])),
++
++ Req7 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
++ mochiweb_headers:make([{"Accept-Encoding", "gzip;q=2.0, *;q=0"}])),
++ ?assertEqual(bad_accept_encoding_value,
++ Req7:accepted_encodings(["gzip", "identity"])),
++
++ Req8 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
++ mochiweb_headers:make([{"Accept-Encoding", "deflate, *;q=0.0"}])),
++ ?assertEqual([],
++ Req8:accepted_encodings(["gzip", "identity"])).
++
++accepted_content_types_test() ->
++ Req1 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
++ mochiweb_headers:make([{"Accept", "text/html"}])),
++ ?assertEqual(["text/html"],
++ Req1:accepted_content_types(["text/html", "application/json"])),
++
++ Req2 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
++ mochiweb_headers:make([{"Accept", "text/html, */*;q=0"}])),
++ ?assertEqual(["text/html"],
++ Req2:accepted_content_types(["text/html", "application/json"])),
++
++ Req3 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
++ mochiweb_headers:make([{"Accept", "text/*, */*;q=0"}])),
++ ?assertEqual(["text/html"],
++ Req3:accepted_content_types(["text/html", "application/json"])),
++
++ Req4 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
++ mochiweb_headers:make([{"Accept", "text/*;q=0.8, */*;q=0.5"}])),
++ ?assertEqual(["text/html", "application/json"],
++ Req4:accepted_content_types(["application/json", "text/html"])),
++
++ Req5 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
++ mochiweb_headers:make([{"Accept", "text/*;q=0.8, */*;q=0.5"}])),
++ ?assertEqual(["text/html", "application/json"],
++ Req5:accepted_content_types(["text/html", "application/json"])),
++
++ Req6 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
++ mochiweb_headers:make([{"Accept", "text/*;q=0.5, */*;q=0.5"}])),
++ ?assertEqual(["application/json", "text/html"],
++ Req6:accepted_content_types(["application/json", "text/html"])),
++
++ Req7 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
++ mochiweb_headers:make(
++ [{"Accept", "text/html;q=0.5, application/json;q=0.5"}])),
++ ?assertEqual(["application/json", "text/html"],
++ Req7:accepted_content_types(["application/json", "text/html"])),
++
++ Req8 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
++ mochiweb_headers:make([{"Accept", "text/html"}])),
++ ?assertEqual([],
++ Req8:accepted_content_types(["application/json"])),
++
++ Req9 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1},
++ mochiweb_headers:make([{"Accept", "text/*;q=0.9, text/html;q=0.5, */*;q=0.7"}])),
++ ?assertEqual(["application/json", "text/html"],
++ Req9:accepted_content_types(["text/html", "application/json"])).
++
++should_close_test() ->
++ F = fun (V, H) ->
++ (mochiweb_request:new(
++ nil, 'GET', "/", V,
++ mochiweb_headers:make(H)
++ )):should_close()
++ end,
++ ?assertEqual(
++ true,
++ F({1, 1}, [{"Connection", "close"}])),
++ ?assertEqual(
++ true,
++ F({1, 0}, [{"Connection", "close"}])),
++ ?assertEqual(
++ true,
++ F({1, 1}, [{"Connection", "ClOSe"}])),
++ ?assertEqual(
++ false,
++ F({1, 1}, [{"Connection", "closer"}])),
++ ?assertEqual(
++ false,
++ F({1, 1}, [])),
++ ?assertEqual(
++ true,
++ F({1, 0}, [])),
++ ?assertEqual(
++ false,
++ F({1, 0}, [{"Connection", "Keep-Alive"}])),
++ ok.
++
+ -endif.
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochiweb_response.erl apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_response.erl
+--- apache-couchdb-1.2.1/src/mochiweb/mochiweb_response.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_response.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -3,39 +3,47 @@
+
+ %% @doc Response abstraction.
+
+--module(mochiweb_response, [Request, Code, Headers]).
++-module(mochiweb_response).
+ -author('bob@mochimedia.com').
+
+ -define(QUIP, "Any of you quaids got a smint?").
+
+--export([get_header_value/1, get/1, dump/0]).
+--export([send/1, write_chunk/1]).
++-export([new/3, get_header_value/2, get/2, dump/1]).
++-export([send/2, write_chunk/2]).
+
+-%% @spec get_header_value(string() | atom() | binary()) -> string() | undefined
++%% @type response(). A mochiweb_response parameterized module instance.
++
++%% @spec new(Request, Code, Headers) -> response()
++%% @doc Create a new mochiweb_response instance.
++new(Request, Code, Headers) ->
++ {?MODULE, [Request, Code, Headers]}.
++
++%% @spec get_header_value(string() | atom() | binary(), response()) ->
++%% string() | undefined
+ %% @doc Get the value of the given response header.
+-get_header_value(K) ->
++get_header_value(K, {?MODULE, [_Request, _Code, Headers]}) ->
+ mochiweb_headers:get_value(K, Headers).
+
+-%% @spec get(request | code | headers) -> term()
++%% @spec get(request | code | headers, response()) -> term()
+ %% @doc Return the internal representation of the given field.
+-get(request) ->
++get(request, {?MODULE, [Request, _Code, _Headers]}) ->
+ Request;
+-get(code) ->
++get(code, {?MODULE, [_Request, Code, _Headers]}) ->
+ Code;
+-get(headers) ->
++get(headers, {?MODULE, [_Request, _Code, Headers]}) ->
+ Headers.
+
+-%% @spec dump() -> {mochiweb_request, [{atom(), term()}]}
++%% @spec dump(response()) -> {mochiweb_request, [{atom(), term()}]}
+ %% @doc Dump the internal representation to a "human readable" set of terms
+ %% for debugging/inspection purposes.
+-dump() ->
++dump({?MODULE, [Request, Code, Headers]}) ->
+ [{request, Request:dump()},
+ {code, Code},
+ {headers, mochiweb_headers:to_list(Headers)}].
+
+-%% @spec send(iodata()) -> ok
++%% @spec send(iodata(), response()) -> ok
+ %% @doc Send data over the socket if the method is not HEAD.
+-send(Data) ->
++send(Data, {?MODULE, [Request, _Code, _Headers]}) ->
+ case Request:get(method) of
+ 'HEAD' ->
+ ok;
+@@ -43,22 +51,22 @@
+ Request:send(Data)
+ end.
+
+-%% @spec write_chunk(iodata()) -> ok
++%% @spec write_chunk(iodata(), response()) -> ok
+ %% @doc Write a chunk of a HTTP chunked response. If Data is zero length,
+ %% then the chunked response will be finished.
+-write_chunk(Data) ->
++write_chunk(Data, {?MODULE, [Request, _Code, _Headers]}=THIS) ->
+ case Request:get(version) of
+ Version when Version >= {1, 1} ->
+ Length = iolist_size(Data),
+- send([io_lib:format("~.16b\r\n", [Length]), Data, <<"\r\n">>]);
++ send([io_lib:format("~.16b\r\n", [Length]), Data, <<"\r\n">>], THIS);
+ _ ->
+- send(Data)
++ send(Data, THIS)
+ end.
+
+
+ %%
+ %% Tests
+ %%
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
++-include_lib("eunit/include/eunit.hrl").
+ -endif.
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochiweb_socket_server.erl apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_socket_server.erl
+--- apache-couchdb-1.2.1/src/mochiweb/mochiweb_socket_server.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_socket_server.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -9,7 +9,7 @@
+
+ -include("internal.hrl").
+
+--export([start/1, stop/1]).
++-export([start/1, start_link/1, stop/1]).
+ -export([init/1, handle_call/3, handle_cast/2, terminate/2, code_change/3,
+ handle_info/2]).
+ -export([get/2, set/3]).
+@@ -33,10 +33,22 @@
+
+ -define(is_old_state(State), not is_record(State, mochiweb_socket_server)).
+
+-start(State=#mochiweb_socket_server{}) ->
+- start_server(State);
++start_link(Options) ->
++ start_server(start_link, parse_options(Options)).
++
+ start(Options) ->
+- start(parse_options(Options)).
++ case lists:keytake(link, 1, Options) of
++ {value, {_Key, false}, Options1} ->
++ start_server(start, parse_options(Options1));
++ _ ->
++ %% TODO: https://github.com/mochi/mochiweb/issues/58
++ %% [X] Phase 1: Add new APIs (Sep 2011)
++ %% [_] Phase 2: Add deprecation warning
++ %% [_] Phase 3: Change default to {link, false} and ignore link
++ %% [_] Phase 4: Add deprecation warning for {link, _} option
++ %% [_] Phase 5: Remove support for {link, _} option
++ start_link(Options)
++ end.
+
+ get(Name, Property) ->
+ gen_server:call(Name, {get, Property}).
+@@ -61,6 +73,8 @@
+
+ %% Internal API
+
++parse_options(State=#mochiweb_socket_server{}) ->
++ State;
+ parse_options(Options) ->
+ parse_options(Options, #mochiweb_socket_server{}).
+
+@@ -116,22 +130,22 @@
+ parse_options(Rest, State#mochiweb_socket_server{profile_fun=ProfileFun}).
+
+
+-start_server(State=#mochiweb_socket_server{ssl=Ssl, name=Name}) ->
+- case Ssl of
+- true ->
+- application:start(crypto),
+- application:start(public_key),
+- application:start(ssl);
+- false ->
+- void
+- end,
++start_server(F, State=#mochiweb_socket_server{ssl=Ssl, name=Name}) ->
++ ok = prep_ssl(Ssl),
+ case Name of
+ undefined ->
+- gen_server:start_link(?MODULE, State, []);
++ gen_server:F(?MODULE, State, []);
+ _ ->
+- gen_server:start_link(Name, ?MODULE, State, [])
++ gen_server:F(Name, ?MODULE, State, [])
+ end.
+
++prep_ssl(true) ->
++ ok = mochiweb:ensure_started(crypto),
++ ok = mochiweb:ensure_started(public_key),
++ ok = mochiweb:ensure_started(ssl);
++prep_ssl(false) ->
++ ok.
++
+ ensure_int(N) when is_integer(N) ->
+ N;
+ ensure_int(S) when is_list(S) ->
+@@ -165,27 +179,7 @@
+ {_, _, _, _, _, _, _, _} -> % IPv6
+ [inet6, {ip, Ip} | BaseOpts]
+ end,
+- case listen(Port, Opts, State) of
+- {stop, eacces} ->
+- case Port < 1024 of
+- true ->
+- case catch fdsrv:start() of
+- {ok, _} ->
+- case fdsrv:bind_socket(tcp, Port) of
+- {ok, Fd} ->
+- listen(Port, [{fd, Fd} | Opts], State);
+- _ ->
+- {stop, fdsrv_bind_failed}
+- end;
+- _ ->
+- {stop, fdsrv_start_failed}
+- end;
+- false ->
+- {stop, eacces}
+- end;
+- Other ->
+- Other
+- end.
++ listen(Port, Opts, State).
+
+ new_acceptor_pool(Listen,
+ State=#mochiweb_socket_server{acceptor_pool=Pool,
+@@ -271,15 +265,8 @@
+
+ terminate(Reason, State) when ?is_old_state(State) ->
+ terminate(Reason, upgrade_state(State));
+-terminate(_Reason, #mochiweb_socket_server{listen=Listen, port=Port}) ->
+- mochiweb_socket:close(Listen),
+- case Port < 1024 of
+- true ->
+- catch fdsrv:stop(),
+- ok;
+- false ->
+- ok
+- end.
++terminate(_Reason, #mochiweb_socket_server{listen=Listen}) ->
++ mochiweb_socket:close(Listen).
+
+ code_change(_OldVsn, State, _Extra) ->
+ State.
+@@ -337,8 +324,8 @@
+ %%
+ %% Tests
+ %%
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
++-include_lib("eunit/include/eunit.hrl").
+
+ upgrade_state_test() ->
+ OldState = {mochiweb_socket_server,
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/mochiweb_util.erl apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_util.erl
+--- apache-couchdb-1.2.1/src/mochiweb/mochiweb_util.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/mochiweb_util.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -9,7 +9,7 @@
+ -export([path_split/1]).
+ -export([urlsplit/1, urlsplit_path/1, urlunsplit/1, urlunsplit_path/1]).
+ -export([guess_mime/1, parse_header/1]).
+--export([shell_quote/1, cmd/1, cmd_string/1, cmd_port/2, cmd_status/1]).
++-export([shell_quote/1, cmd/1, cmd_string/1, cmd_port/2, cmd_status/1, cmd_status/2]).
+ -export([record_to_proplist/2, record_to_proplist/3]).
+ -export([safe_relative_path/1, partition/2]).
+ -export([parse_qvalues/1, pick_accepted_encodings/3]).
+@@ -124,11 +124,17 @@
+ string:join([shell_quote(X) || X <- Argv], " ").
+
+ %% @spec cmd_status([string()]) -> {ExitStatus::integer(), Stdout::binary()}
+-%% @doc Accumulate the output and exit status from the given application, will be
+-%% spawned with cmd_port/2.
++%% @doc Accumulate the output and exit status from the given application,
++%% will be spawned with cmd_port/2.
+ cmd_status(Argv) ->
++ cmd_status(Argv, []).
++
++%% @spec cmd_status([string()], [atom()]) -> {ExitStatus::integer(), Stdout::binary()}
++%% @doc Accumulate the output and exit status from the given application,
++%% will be spawned with cmd_port/2.
++cmd_status(Argv, Options) ->
+ Port = cmd_port(Argv, [exit_status, stderr_to_stdout,
+- use_stdio, binary]),
++ use_stdio, binary | Options]),
+ try cmd_loop(Port, [])
+ after catch port_close(Port)
+ end.
+@@ -578,8 +584,8 @@
+ %%
+ %% Tests
+ %%
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
++-include_lib("eunit/include/eunit.hrl").
+
+ make_io_test() ->
+ ?assertEqual(
+diff -wbBur apache-couchdb-1.2.1/src/mochiweb/reloader.erl apache-couchdb-1.2.1.q/src/mochiweb/reloader.erl
+--- apache-couchdb-1.2.1/src/mochiweb/reloader.erl 2012-12-21 01:24:07.000000000 +0400
++++ apache-couchdb-1.2.1.q/src/mochiweb/reloader.erl 2013-03-22 15:26:58.000000000 +0400
+@@ -59,7 +59,7 @@
+ %% @doc gen_server callback.
+ handle_info(doit, State) ->
+ Now = stamp(),
+- doit(State#state.last, Now),
++ _ = doit(State#state.last, Now),
+ {noreply, State#state{last = Now}};
+ handle_info(_Info, State) ->
+ {noreply, State}.
+@@ -156,6 +156,6 @@
+ %%
+ %% Tests
+ %%
+--include_lib("eunit/include/eunit.hrl").
+ -ifdef(TEST).
++-include_lib("eunit/include/eunit.hrl").
+ -endif.