anchor.diff:  %%      partition("foo/bar", "/") = {"foo", "/", "bar"},
   %%      partition("foo", "/") = {"foo", "", ""}.
   partition(String, Sep) ->
  -    case partition(String, Sep, []) of
  -        undefined ->
  -            {String, "", ""};
  -        Result ->
  -            Result
  -    end.
  +  case partition(String, Sep, []) of
  +    undefined ->
  +      {String, "", ""};
  +    Result ->
  +      Result
  +  end.
   
   partition("", _Sep, _Acc) ->
  -    undefined;
  +  undefined;
   partition(S, Sep, Acc) ->
  -    case partition2(S, Sep) of
  -        undefined ->
  -            [C | Rest] = S,
  -            partition(Rest, Sep, [C | Acc]);
  -        Rest ->
  -            {lists:reverse(Acc), Sep, Rest}
  -    end.
  +  case partition2(S, Sep) of
  +    undefined ->
  +      [C | Rest] = S,
  +      partition(Rest, Sep, [C | Acc]);
  +    Rest ->
  +      {lists:reverse(Acc), Sep, Rest}
  +  end.
   
   partition2(Rest, "") ->
  -    Rest;
  +  Rest;
   partition2([C | R1], [C | R2]) ->
  -    partition2(R1, R2);
  +  partition2(R1, R2);
   partition2(_S, _Sep) ->
  -    undefined.
  +  undefined.
   
   
   
  
positive.code: %%      where record_type is the record type of Record
  record_to_proplist(Record, Fields, TypeKey)
    when is_tuple(Record),
         is_list(Fields),
         size(Record) - 1 =:= length(Fields) ->
      lists:zip([TypeKey | Fields], tuple_to_list(Record)).
  
  
  shell_quote([], Acc) ->
      lists:reverse([$\" | Acc]);
  shell_quote([C | Rest], Acc) when C =:= $\" orelse C =:= $\` orelse
                                    C =:= $\\ orelse C =:= $\$ ->
      shell_quote(Rest, [C, $\\ | Acc]);
  shell_quote([C | Rest], Acc) ->
      shell_quote(Rest, [C | Acc]).
  
  test() ->
      test_join(),
      test_quote_plus(),
      test_unquote(),
      test_urlencode(),
      test_parse_qs(),
      test_urlsplit_path(),
      test_urlunsplit_path(),
      test_urlsplit(),
      test_urlunsplit(),
      test_path_split(),
      test_guess_mime(),
      test_parse_header(),
      test_shell_quote(),
      test_cmd(),
      test_cmd_string(),
      test_partition(),
      test_safe_relative_path(),
      ok.
  
  test_shell_quote() ->
      "\"foo \\$bar\\\"\\`' baz\"" = shell_quote("foo $bar\"`' baz"),
      ok.
  
  test_cmd() ->
      "$bling$ `word`!\n" = cmd(["echo", "$bling$ `word`!"]),
      ok.
  
  test_cmd_string() ->
      "\"echo\" \"\\$bling\\$ \\`word\\`!\"" = cmd_string(["echo", "$bling$ `word`!"]),
      ok.
  
  test_parse_header() ->
      {"multipart/form-data", [{"boundary", "AaB03x"}]} =
          parse_header("multipart/form-data; boundary=AaB03x"),
      ok.
  
  test_guess_mime() ->
      "text/plain" = guess_mime(""),
      "text/plain" = guess_mime(".text"),
      "application/zip" = guess_mime(".zip"),
      "application/zip" = guess_mime("x.zip"),
      "text/html" = guess_mime("x.html"),
      "application/xhtml+xml" = guess_mime("x.xhtml"),
      ok.
  
  test_path_split() ->
      {"", "foo/bar"} = path_split("/foo/bar"),
      {"foo", "bar"} = path_split("foo/bar"),
      {"bar", ""} = path_split("bar"),
      ok.
  
  test_urlsplit() ->
      {"", "", "/foo", "", "bar?baz"} = urlsplit("/foo#bar?baz"),
      {"http", "host:port", "/foo", "", "bar?baz"} =
          urlsplit("http://host:port/foo#bar?baz"),
      ok.
  
  test_urlsplit_path() ->
      {"/foo/bar", "", ""} = urlsplit_path("/foo/bar"),
      {"/foo", "baz", ""} = urlsplit_path("/foo?baz"),
      {"/foo", "", "bar?baz"} = urlsplit_path("/foo#bar?baz"),
      {"/foo", "", "bar?baz#wibble"} = urlsplit_path("/foo#bar?baz#wibble"),
      {"/foo", "bar", "baz"} = urlsplit_path("/foo?bar#baz"),
      {"/foo", "bar?baz", "baz"} = urlsplit_path("/foo?bar?baz#baz"),
      ok.
  
  test_urlunsplit() ->
      "/foo#bar?baz" = urlunsplit({"", "", "/foo", "", "bar?baz"}),
      "http://host:port/foo#bar?baz" =
          urlunsplit({"http", "host:port", "/foo", "", "bar?baz"}),
      ok.
  
  test_urlunsplit_path() ->
      "/foo/bar" = urlunsplit_path({"/foo/bar", "", ""}),
      "/foo?baz" = urlunsplit_path({"/foo", "baz", ""}),
      "/foo#bar?baz" = urlunsplit_path({"/foo", "", "bar?baz"}),
      "/foo#bar?baz#wibble" = urlunsplit_path({"/foo", "", "bar?baz#wibble"}),
      "/foo?bar#baz" = urlunsplit_path({"/foo", "bar", "baz"}),
      "/foo?bar?baz#baz" = urlunsplit_path({"/foo", "bar?baz", "baz"}),
      ok.
  
  test_join() ->
      "foo,bar,baz" = join(["foo", "bar", "baz"], $,),
      "foo,bar,baz" = join(["foo", "bar", "baz"], ","),
      "foo bar" = join([["foo", " bar"]], ","),
      "foo bar,baz" = join([["foo", " bar"], "baz"], ","),
      "foo" = join(["foo"], ","),
      "foobarbaz" = join(["foo", "bar", "baz"], ""),
      ok.
  
  test_quote_plus() ->
      "foo" = quote_plus(foo),
      "1" = quote_plus(1),
      "1.1" = quote_plus(1.1),
      "foo" = quote_plus("foo"),
      "foo+bar" = quote_plus("foo bar"),
      "foo%0A" = quote_plus("foo\n"),
      "foo%0A" = quote_plus("foo\n"),
      "foo%3B%26%3D" = quote_plus("foo;&="),
      ok.
  
  test_unquote() ->
      "foo bar" = unquote("foo+bar"),
      "foo bar" = unquote("foo%20bar"),
      "foo\r\n" = unquote("foo%0D%0A"),
      ok.
  
  test_urlencode() ->
      "foo=bar&baz=wibble+%0D%0A&z=1" = urlencode([{foo, "bar"},
                                                   {"baz", "wibble \r\n"},
                                                   {z, 1}]),
      ok.
  
  test_parse_qs() ->
      [{"foo", "bar"}, {"baz", "wibble \r\n"}, {"z", "1"}] =
          parse_qs("foo=bar&baz=wibble+%0D%0A&z=1"),
      ok.
  
  test_partition() ->
      {"foo", "", ""} = partition("foo", "/"),
      {"foo", "/", "bar"} = partition("foo/bar", "/"),
      {"foo", "/", ""} = partition("foo/", "/"),
      {"", "/", "bar"} = partition("/bar", "/"),
      {"f", "oo/ba", "r"} = partition("foo/bar", "oo/ba"),
      ok.
  
  test_safe_relative_path() ->
      "foo" = safe_relative_path("foo"),
      "foo/" = safe_relative_path("foo/"),
      "foo" = safe_relative_path("foo/bar/.."),
      "bar" = safe_relative_path("foo/../bar"),
      "bar/" = safe_relative_path("foo/../bar/"),
      "" = safe_relative_path("foo/.."),
      "" = safe_relative_path("foo/../"),
      undefined = safe_relative_path("/foo"),
      undefined = safe_relative_path("../foo"),
      undefined = safe_relative_path("foo/../.."),
      undefined = safe_relative_path("foo//"),
      ok.
  
negative.code: 
  -define(PERCENT, 37).  % $\%
  -define(FULLSTOP, 46). % $\.
  -define(LBRACE, 91). % $\[.
  -define(RBRACE, 93). % $\].
  -define(IS_HEX(C), ((C >= $0 andalso C =< $9) orelse
                      (C >= $a andalso C =< $f) orelse
                      (C >= $A andalso C =< $F))).
  