anchor.diff:  handle_recv({error, Error}, _App, _State) ->
       {stop, {recv_error, Error}}.
   
  -is_eof(<<>>) -> true;
  -is_eof(_) -> false.
  -
  -error_on_recv_body_after_eof(false, _Result, _App) -> ok;
  -error_on_recv_body_after_eof(true, {recv_body, _, _, _}, App) ->
  -    error({recv_body_after_eof, App});
  -error_on_recv_body_after_eof(true, {recv_body, _, _, _, _}, App) ->
  -    error({recv_body_after_eof, App});
  -error_on_recv_body_after_eof(true, _Result, _App) -> ok.
  -
  -increment_recv_len(I, #state{recv_len=Len}=S) ->
  -    S#state{recv_len=I + Len}.
  +%%%===================================================================
  +%%% recv_form_data support
  +%%%===================================================================
   
   handle_app_recv_form_data(App, Env, Options, State) ->
       ContentType = psycho:env_val(content_type, Env),
  -    handle_recv_form_data_type(ContentType, App, setenv(Env, State), Options).
  -
  -handle_recv_form_data_type("application/x-www-form-urlencoded",
  -                           App, State, Options) ->
  +    handle_app_recv_form_data_type(
  +      ContentType, App, setenv(Env, State), Options).
  +
  +handle_app_recv_form_data_type(
  +  "application/x-www-form-urlencoded", App, State, Options) ->
  +    handle_app_recv_urlencoded_data(App, State, Options);
  +handle_app_recv_form_data_type(
  +  "multipart/form-data;"++_, App, State, Options) ->
  +    handle_app_recv_multipart(App, State, Options);
  +handle_app_recv_form_data_type(ContentType, _App, State, _Options) ->
  +    respond(internal_error("Unsupported content type"), State),
  +    error({form_data_content_type, ContentType}).
  +
  +%%%===================================================================
  +%%% urlencoded form data
  +%%%===================================================================
  +
  +handle_app_recv_urlencoded_data(App, State, Options) ->
       Timeout = proplists:get_value(recv_timeout, Options, ?IDLE_TIMEOUT),
       RecvResult = recv_remaining(Timeout, State),
  -    handle_recv_urlencoded_form_data(RecvResult, App, State);
  -handle_recv_form_data_type(ContentType, _App, State, _Options) ->
  -    respond(internal_error("Unsupported content type"), State),
  -    error({form_data_content_type, ContentType}).
  -
  -internal_error() ->
  -    internal_error("Server error").
  -
  -internal_error(Msg) ->
  -    {?status_internal_server_error, [{"Content-Type", "text/plain"}], Msg}.
  +    handle_recv_urlencoded_form_data(RecvResult, App, State).
   
   handle_recv_urlencoded_form_data({ok, Data}, App, #state{env=Env}=State) ->
       DecodedData = decode_urlencoded_form_data(Data),
  
positive.code: 
  -define(IDLE_TIMEOUT, 300000).
  -define(DEFAULT_RECV_LEN, 32768).
  
  start_link(Sock, App) ->
      proc:start_link(?MODULE, [Sock, App]).
  
negative.code: set_socket_active_once(#state{sock=S}) ->
      ok = inet:setopts(S, [{active, once}]).
  
  %%%===================================================================
  %%% Request init / pre app dispatch
  %%%===================================================================
  
  set_request(Method, Path, Ver, State) ->
      State#state{
        env=init_env(Method, Path, Ver),
  