Index: files/patch-lib_ssl_c_src_Makefile.in
===================================================================
--- files/patch-lib_ssl_c_src_Makefile.in	(revision 41597)
+++ files/patch-lib_ssl_c_src_Makefile.in	(working copy)
@@ -1,6 +1,6 @@
---- lib/ssl/c_src/Makefile.in.orig	2008-04-13 20:41:08.000000000 -0700
-+++ lib/ssl/c_src/Makefile.in	2008-04-13 20:38:18.000000000 -0700
-@@ -38,7 +38,7 @@
+--- lib/ssl/c_src/Makefile.in.orig	2008-11-04 12:17:23.000000000 +0100
++++ lib/ssl/c_src/Makefile.in	2008-11-06 07:46:48.000000000 +0100
+@@ -40,7 +40,7 @@
  CC = @CC@
  LD = @LD@
  SHELL = /bin/sh
@@ -9,7 +9,7 @@
  PLAIN_CFLAGS = @CFLAGS@
  
  # ----------------------------------------------------
-@@ -124,7 +124,7 @@
+@@ -126,7 +126,7 @@
  CC_R_OPT = $(CC_R_FLAG)$(SSL_LIBDIR)
  endif
  
Index: files/patch-decode_fun.c.diff
===================================================================
--- files/patch-decode_fun.c.diff	(revision 0)
+++ files/patch-decode_fun.c.diff	(revision 0)
@@ -0,0 +1,11 @@
+--- lib/erl_interface/src/decode/decode_fun.c.orig	2008-11-06 06:53:46.000000000 +0100
++++ lib/erl_interface/src/decode/decode_fun.c	2008-11-06 06:54:09.000000000 +0100
+@@ -103,7 +103,7 @@
+ 		memcpy(p->free_vars, s, n);
+ 	    }
+ 	}
+-	*index += s-s0;
++	*index += n + s-s0;
+         return 0;
+ 	break;
+     default:
Index: files/patch-erts_emulator_sys_unix_ddll.c
===================================================================
--- files/patch-erts_emulator_sys_unix_ddll.c	(revision 41597)
+++ files/patch-erts_emulator_sys_unix_ddll.c	(working copy)
@@ -1,27 +0,0 @@
---- erts/emulator/sys/unix/erl_unix_sys_ddll.c	2007-11-26 20:01:23.000000000 +0100
-+++ erts/emulator/sys/unix/erl_unix_sys_ddll.c	2008-09-07 10:13:54.000000000 +0200
-@@ -127,6 +127,7 @@
- 	    } else {
- 		ret = ERL_DE_ERROR_UNSPECIFIED;
- 	    }
-+		NSDestroyObjectFileImage(ofile);
- 	    break;
- 	/* XXX:PaN should anything return something else ? */
- 	/*case NSObjectFileImageInappropriateFile:
-@@ -240,7 +241,15 @@
- int erts_sys_ddll_close(void *handle)
- {
- #if defined(HAVE_MACH_O_DYLD_H)
--    return ERL_DE_NO_ERROR; /* XXX:PaN No close functionality in MacOSX??? */
-+    {
-+	int ret;
-+	if (NSUnLinkModule((NSModule) handle, NSUNLINKMODULE_OPTION_NONE)) {
-+	    ret = ERL_DE_NO_ERROR;
-+	} else {
-+	    ret = ERL_DE_ERROR_UNSPECIFIED;
-+	}
-+	return ret;
-+    }
- #elif defined(HAVE_DLOPEN)
-     {
- 	int ret;
Index: files/patch-lib_ssl_c_src_esock_openssl.c
===================================================================
--- files/patch-lib_ssl_c_src_esock_openssl.c	(revision 41597)
+++ files/patch-lib_ssl_c_src_esock_openssl.c	(working copy)
@@ -1,6 +1,6 @@
---- lib/ssl/c_src/esock_openssl.c.orig	2008-03-12 22:15:41.000000000 -0700
-+++ lib/ssl/c_src/esock_openssl.c	2008-03-12 22:16:01.000000000 -0700
-@@ -905,8 +905,8 @@
+--- lib/ssl/c_src/esock_openssl.c.orig	2008-11-04 12:17:23.000000000 +0100
++++ lib/ssl/c_src/esock_openssl.c	2008-11-06 07:46:48.000000000 +0100
+@@ -907,8 +907,8 @@
      }
  
      /* info callback */
Index: files/patch-eunit_xml.diff
===================================================================
--- files/patch-eunit_xml.diff	(revision 0)
+++ files/patch-eunit_xml.diff	(revision 0)
@@ -0,0 +1,542 @@
+Index: lib/eunit/src/eunit_xml.erl
+===================================================================
+--- lib/eunit/src/eunit_xml.erl	(revision 0)
++++ lib/eunit/src/eunit_xml.erl	(revision 0)
+@@ -0,0 +1,496 @@
++%% This library is free software; you can redistribute it and/or modify
++%% it under the terms of the GNU Lesser General Public License as
++%% published by the Free Software Foundation; either version 2 of the
++%% License, or (at your option) any later version.
++%%
++%% This library is distributed in the hope that it will be useful, but
++%% WITHOUT ANY WARRANTY; without even the implied warranty of
++%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++%% Lesser General Public License for more details.
++%%
++%% You should have received a copy of the GNU Lesser General Public
++%% License along with this library; if not, write to the Free Software
++%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++%% USA
++%%
++%% $Id$ 
++%%
++%% @author Paul Guyot <paulguyot@ieee.org>
++%% @copyright 2008 Paul Guyot
++%% @private
++%% @see eunit
++%% @doc XML reports for EUnit
++
++-module(eunit_xml).
++
++-include("eunit.hrl").
++-include("eunit_internal.hrl").
++
++-export([start/3]).
++
++%% ============================================================================
++%% MACROS
++%% ============================================================================
++-define(INDENT, <<"  ">>).
++-define(NEWLINE, <<"\n">>).
++
++%% ============================================================================
++%% TYPES
++%% ============================================================================
++-type(chars() :: [char() | any()]). % chars()
++-type(item_name() :: {
++    Module :: atom(),
++    Function :: atom(),
++    Line :: integer() } | {
++    Module :: atom(),
++    Function :: atom() }).
++-type(tree_entry() :: {
++    Kind :: group | item,
++    Id :: [integer()],
++    Description :: string(),
++    item_name() | [any()]}). % tree_entry()
++
++%% ============================================================================
++%% RECORDS
++%% ============================================================================
++-record(testcase,
++    {
++    name :: chars(),
++    description :: chars(),
++    result :: ok | {failed, tuple()} | {aborted, tuple()} | {skipped, tuple()},
++    time :: integer(),
++    output :: chars()
++    }).
++-record(testsuite,
++    {
++    name = [] :: chars(),
++    time = 0 :: integer(),
++    output = [] :: chars(),
++    succeeded = 0 :: integer(),
++    failed = 0 :: integer(),
++    aborted = 0 :: integer(),
++    skipped = 0 :: integer(),
++    testcases = [] :: [#testcase{}]
++    }).
++
++-spec(start/3::([any()], [any()], string())->pid()).
++start(List, Options, XmlDir) ->
++    spawn(fun() -> init(List, Options, XmlDir) end).
++
++init(List, _Options, XmlDir) ->
++    TestSuites = dict:new(),
++    loop(TestSuites, List, XmlDir).
++
++loop(TestSuites, List, XmlDir) ->
++    receive
++        {status, Id, Status} ->
++            NewTestSuites = process_status(TestSuites, List, Id, Status),
++            loop(NewTestSuites, List, XmlDir);
++        {start, _Reference} ->
++            loop(TestSuites, List, XmlDir);
++        {stop, _Reference, _Pid} ->
++            write_reports(TestSuites, XmlDir);
++        Unknown ->
++            io:format("Unknown message: ~p~n", [Unknown]),
++            loop(TestSuites, List, XmlDir)
++    end.
++
++%% ----------------------------------------------------------------------------
++%% Process a status message.
++%% ----------------------------------------------------------------------------
++process_status(TestSuites, _List, _Id, {progress, 'begin', _Result}) ->
++    TestSuites;
++process_status(TestSuites, _List, [], {progress, 'end', _Result}) ->
++    TestSuites;
++process_status(TestSuites, List, [GroupId] = Id, {progress, 'end', {Count, Time, Output}}) when is_integer(Count) ->
++    TestSuite = case dict:find(GroupId, TestSuites) of
++        {ok, Value} -> Value;
++        error -> #testsuite{}
++    end,
++    Name = case entry(List, Id) of
++        {value, {group, Id, Description, _Items}} ->
++            Description;
++        _ -> ["Unknown-", integer_to_list(GroupId)]
++    end,
++    NewTestSuite = TestSuite#testsuite{
++        name = Name,
++        time = Time,
++        output = Output},
++    dict:store(GroupId, NewTestSuite, TestSuites);
++process_status(TestSuites, _List, _Id, {progress, 'end', {Count, _Time, _Output}}) when is_integer(Count)->
++    TestSuites;
++process_status(TestSuites, List, [GroupId | _Tail] = Id, {progress, 'end', {ok, Time, Output}}) ->
++    case entry(List, Id) of
++        {value, {item, Id, Description, NameTuple}} ->
++            TestSuite = case dict:find(GroupId, TestSuites) of
++                {ok, Value} -> Value;
++                error -> #testsuite{}
++            end,
++            Name = format_name(NameTuple),
++            TestCase = #testcase{
++                    name = Name,
++                    description = Description,
++                    result = ok,
++                    time = Time,
++                    output = Output},
++            NewTestSuite = TestSuite#testsuite{
++                succeeded = TestSuite#testsuite.succeeded + 1,
++                testcases = [TestCase | TestSuite#testsuite.testcases]},
++            dict:store(GroupId, NewTestSuite, TestSuites);
++        _ -> TestSuites
++    end;
++process_status(
++        TestSuites, List, [GroupId | _Tail] = Id,
++        {progress, 'end', {{error, {error, {AssertionException, _Details}, _Trace} = Exception}, Time, Output}})
++            when
++                AssertionException == assertion_failed;
++                AssertionException == assertMatch_failed;
++                AssertionException == assertEqual_failed;
++                AssertionException == assertException_failed;
++                AssertionException == assertCmd_failed;
++                AssertionException == assertCmdOutput_failed ->
++    case entry(List, Id) of
++        {value, {item, Id, Description, NameTuple}} ->
++            TestSuite = case dict:find(GroupId, TestSuites) of
++                {ok, Value} -> Value;
++                error -> #testsuite{}
++            end,
++            Name = format_name(NameTuple),
++            TestCase = #testcase{
++                    name = Name,
++                    description = Description,
++                    result = {failed, Exception},
++                    time = Time,
++                    output = Output},
++            NewTestSuite = TestSuite#testsuite{
++                failed = TestSuite#testsuite.failed + 1,
++                testcases = [TestCase | TestSuite#testsuite.testcases]},
++            dict:store(GroupId, NewTestSuite, TestSuites);
++        _ -> TestSuites
++    end;
++process_status(TestSuites, List, [GroupId | _Tail] = Id, {progress, 'end', {{error, Exception}, Time, Output}}) ->
++    case entry(List, Id) of
++        {value, {item, Id, Description, NameTuple}} ->
++            TestSuite = case dict:find(GroupId, TestSuites) of
++                {ok, Value} -> Value;
++                error -> #testsuite{}
++            end,
++            Name = format_name(NameTuple),
++            TestCase = #testcase{
++                    name = Name,
++                    description = Description,
++                    result = {aborted, Exception},
++                    time = Time,
++                    output = Output},
++            NewTestSuite = TestSuite#testsuite{
++                aborted = TestSuite#testsuite.aborted + 1,
++                testcases = [TestCase | TestSuite#testsuite.testcases]},
++            dict:store(GroupId, NewTestSuite, TestSuites);
++        _ -> TestSuites
++    end;
++process_status(TestSuites, _List, _Id, {cancel, undefined}) -> TestSuites;
++process_status(TestSuites, List, [GroupId, _Tail] = Id, {cancel, Reason}) ->
++    TestSuite = case dict:find(GroupId, TestSuites) of
++        {ok, Value} -> Value;
++        error -> #testsuite{}
++    end,
++    dict:store(GroupId, process_cancel(TestSuite, List, Id, Reason), TestSuites);
++process_status(TestSuites, _List, _Id, Status) ->
++    io:format("Unknown status = ~p~n", [Status]),
++    TestSuites.
++
++%% ----------------------------------------------------------------------------
++%% Process a cancel status.
++%% ----------------------------------------------------------------------------
++process_cancel(TestSuite, List, Id, Reason) ->
++    case entry(List, Id) of
++        {value, {item, Id, _Description, _NameTuple} = Item} ->
++            process_cancel_items(TestSuite, [Item], [], Reason);
++        {value, {group, Id, _Description, Items}} ->
++            process_cancel_items(TestSuite, Items, [], Reason);
++        _ -> TestSuite
++    end.
++
++%% ----------------------------------------------------------------------------
++%% Process the tests that were skipped because of an error.
++%%
++-spec(process_cancel_items/4 :: (#testsuite{}, Items :: [tree_entry()], Acc :: [[tree_entry()]], Reason :: tuple()) -> #testsuite{}).
++%% ----------------------------------------------------------------------------
++process_cancel_items(TestSuite, [], [], _Reason) -> TestSuite;
++process_cancel_items(TestSuite, [], [Acc | Tail], Reason) ->
++    process_cancel_items(TestSuite, Acc, Tail, Reason);
++process_cancel_items(TestSuite, [{item, _Id, Description, NameTuple} | Tail], Acc, Reason) ->
++    Name = format_name(NameTuple),
++    TestCase = #testcase{
++        name = Name,
++        description = Description,
++        result = {skipped, Reason},
++        time = 0,
++        output = []},
++    NewTestSuite = TestSuite#testsuite{
++        skipped = TestSuite#testsuite.skipped + 1,
++        testcases = [TestCase | TestSuite#testsuite.testcases]},
++    process_cancel_items(NewTestSuite, Tail, Acc, Reason);
++process_cancel_items(TestSuite, [{group, _Id, _Description, Items} | Tail], Acc, Reason) ->
++    process_cancel_items(TestSuite, Items, [Tail | Acc], Reason).
++
++%% ----------------------------------------------------------------------------
++%% Convert a test description into a test case name.
++%% If the test description is a module function, use the function's name.
++%% If the test description is a module function plus a line, use function.line.
++%% ----------------------------------------------------------------------------
++format_name({_Module, Function}) -> atom_to_list(Function);
++format_name({_Module, Function, Line}) -> [atom_to_list(Function), $., integer_to_list(Line)].
++
++%% ----------------------------------------------------------------------------
++%% Write the reports to the XML directory.
++%% ----------------------------------------------------------------------------
++write_reports(TestSuites, XmlDir) ->
++    dict:fold(fun(_GroupId, TestSuite, Acc) -> write_report(TestSuite, XmlDir), Acc end, [], TestSuites).
++
++%% ----------------------------------------------------------------------------
++%% Write a report to the XML directory.
++%% This function opens the report file, calls write_report_to/2 and closes the file.
++%% ----------------------------------------------------------------------------
++write_report(#testsuite{name = Name} = TestSuite, XmlDir) ->
++    Filename = filename:join(XmlDir, lists:flatten(["TEST-", escape_suitename(Name)], ".xml")),
++    case file:open(Filename, [write, raw]) of
++        {ok, FileDescriptor} ->
++            try
++                write_report_to(TestSuite, FileDescriptor)
++            after
++                file:close(FileDescriptor)
++            end;
++        {error, _Reason} = Error -> throw(Error)
++    end.
++
++%% ----------------------------------------------------------------------------
++%% Actually write a report.
++%% ----------------------------------------------------------------------------
++write_report_to(TestSuite, FileDescriptor) ->
++    write_header(FileDescriptor),
++    write_start_tag(TestSuite, FileDescriptor),
++    write_testcases(TestSuite#testsuite.testcases, FileDescriptor),
++    write_end_tag(FileDescriptor).
++
++%% ----------------------------------------------------------------------------
++%% Write the XML header.
++%% ----------------------------------------------------------------------------
++write_header(FileDescriptor) ->
++    file:write(FileDescriptor, [<<"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>">>, ?NEWLINE]).
++
++%% ----------------------------------------------------------------------------
++%% Write the testsuite start tag, with attributes describing the statistics
++%% of the test suite.
++%% ----------------------------------------------------------------------------
++write_start_tag(
++        #testsuite{
++            name = Name,
++            time = Time,
++            succeeded = Succeeded,
++            failed = Failed,
++            skipped = Skipped,
++            aborted = Aborted},
++        FileDescriptor) ->
++    Total = Succeeded + Failed + Skipped + Aborted,
++    StartTag = [
++        <<"<testsuite tests=\"">>, integer_to_list(Total),
++        <<"\" failures=\"">>, integer_to_list(Failed),
++        <<"\" errors=\"">>, integer_to_list(Aborted),
++        <<"\" skipped=\"">>, integer_to_list(Skipped),
++        <<"\" time=\"">>, format_time(Time),
++        <<"\" name=\"">>, escape_attr(Name),
++        <<"\">">>, ?NEWLINE],        
++    file:write(FileDescriptor, StartTag).
++
++%% ----------------------------------------------------------------------------
++%% Recursive function to write the test cases.
++%% ----------------------------------------------------------------------------
++write_testcases([], _FileDescriptor) -> void;
++write_testcases([TestCase| Tail], FileDescriptor) ->
++    write_testcase(TestCase, FileDescriptor),
++    write_testcases(Tail, FileDescriptor).
++
++%% ----------------------------------------------------------------------------
++%% Write the testsuite end tag.
++%% ----------------------------------------------------------------------------
++write_end_tag(FileDescriptor) ->
++    file:write(FileDescriptor, [<<"</testsuite>">>, ?NEWLINE]).
++
++%% ----------------------------------------------------------------------------
++%% Write a test case, as a testcase tag.
++%% If the test case was successful and if there was no output, we write an empty
++%% tag.
++%% ----------------------------------------------------------------------------
++write_testcase(
++        #testcase{
++            name = Name,
++            description = Description,
++            result = Result,
++            time = Time,
++            output = Output},
++        FileDescriptor) ->
++    DescriptionAttr = case Description of
++        [] -> [];
++        _ -> [<<" description=\"">>, escape_attr(Description), <<"\"">>]
++    end,
++    StartTag = [
++        ?INDENT, <<"<testcase time=\"">>, format_time(Time),
++        <<"\" name=\"">>, escape_attr(Name), <<"\"">>,
++        DescriptionAttr],
++    ContentAndEndTag = case {Result, Output} of
++        {ok, []} -> [<<"/>">>, ?NEWLINE];
++        _ -> [<<">">>, ?NEWLINE, format_testcase_result(Result), format_testcase_output(Output), ?INDENT, <<"</testcase>">>, ?NEWLINE]
++    end,
++    file:write(FileDescriptor, [StartTag, ContentAndEndTag]).
++
++%% ----------------------------------------------------------------------------
++%% Format the result of the test.
++%% Failed tests are represented with a failure tag.
++%% Aborted tests are represented with an error tag.
++%% Skipped tests are represented with a skipped tag.
++%% ----------------------------------------------------------------------------
++format_testcase_result(ok) -> [];
++format_testcase_result({failed, {error, {Type, _}, _} = Exception}) when is_atom(Type) ->
++    [?INDENT, ?INDENT, <<"<failure type=\"">>, escape_attr(atom_to_list(Type)), <<"\">">>, ?NEWLINE,
++    <<"::">>, escape_text(eunit_lib:format_exception(Exception)),
++    ?INDENT, ?INDENT, <<"</failure>">>, ?NEWLINE];
++format_testcase_result({failed, Term}) ->
++    [?INDENT, ?INDENT, <<"<failure type=\"unknown\">">>, ?NEWLINE,
++    escape_text(io_lib:write(Term)),
++    ?INDENT, ?INDENT, <<"</failure>">>, ?NEWLINE];
++format_testcase_result({aborted, {Class, _Term, _Trace} = Exception}) when is_atom(Class) ->
++    [?INDENT, ?INDENT, <<"<error type=\"">>, escape_attr(atom_to_list(Class)), <<"\">">>, ?NEWLINE,
++    <<"::">>, escape_text(eunit_lib:format_exception(Exception)),
++    ?INDENT, ?INDENT, <<"</error>">>, ?NEWLINE];
++format_testcase_result({aborted, Term}) ->
++    [?INDENT, ?INDENT, <<"<error type=\"unknown\">">>, ?NEWLINE,
++    escape_text(io_lib:write(Term)),
++    ?INDENT, ?INDENT, <<"</error>">>, ?NEWLINE];
++format_testcase_result({skipped, {abort, Error}}) when is_tuple(Error) ->
++    [?INDENT, ?INDENT, <<"<skipped type=\"">>, escape_attr(atom_to_list(element(1, Error))), <<"\">">>, ?NEWLINE,
++    escape_text(eunit_lib:format_error(Error)),
++    ?INDENT, ?INDENT, <<"</skipped>">>, ?NEWLINE];
++format_testcase_result({skipped, {Type, Term}}) when is_atom(Type) ->
++    [?INDENT, ?INDENT, <<"<skipped type=\"">>, escape_attr(atom_to_list(Type)), <<"\">">>, ?NEWLINE,
++    escape_text(io_lib:write(Term)),
++    ?INDENT, ?INDENT, <<"</skipped>">>, ?NEWLINE];
++format_testcase_result({skipped, Term}) ->
++    [?INDENT, ?INDENT, <<"<skipped type=\"unknown\">">>, ?NEWLINE,
++    escape_text(io_lib:write(Term)),
++    ?INDENT, ?INDENT, <<"</skipped>">>, ?NEWLINE].
++
++%% ----------------------------------------------------------------------------
++%% Format the output of a test case in xml.
++%% Empty output is simply the empty string.
++%% Other output is inside a <system-out> xml tag.
++%% ----------------------------------------------------------------------------
++format_testcase_output([]) -> [];
++format_testcase_output(Output) ->
++    [?INDENT, ?INDENT, <<"<system-out>">>, escape_text(Output), ?NEWLINE, ?INDENT, ?INDENT, <<"</system-out>">>, ?NEWLINE].
++
++%% ----------------------------------------------------------------------------
++%% Return the time in the SECS.MILLISECS format.
++%% ----------------------------------------------------------------------------
++format_time(Time) ->
++    format_time_s(lists:reverse(integer_to_list(Time))).
++format_time_s([Digit]) -> ["0.00", Digit];
++format_time_s([Digit1, Digit2]) -> ["0.0", Digit2, Digit1];
++format_time_s([Digit1, Digit2, Digit3]) -> ["0.", Digit3, Digit2, Digit1];
++format_time_s([Digit1, Digit2, Digit3 | Tail]) -> [lists:reverse(Tail), $., Digit3, Digit2, Digit1].
++
++%% ----------------------------------------------------------------------------
++%% Escape a suite's name to generate the filename.
++%% Remark: we might overwrite another testsuite's file.
++%% ----------------------------------------------------------------------------
++escape_suitename([Head | _T] = List) when is_list(Head) ->
++    escape_suitename(lists:flatten(List));
++escape_suitename("module '" ++ String) ->
++    escape_suitename(String);
++escape_suitename(String) ->
++    escape_suitename(String, []).
++
++escape_suitename([], Acc) -> lists:reverse(Acc);
++escape_suitename([$  | Tail], Acc) -> escape_suitename(Tail, [$_ | Acc]);
++escape_suitename([$' | Tail], Acc) -> escape_suitename(Tail, Acc);
++escape_suitename([$/ | Tail], Acc) -> escape_suitename(Tail, [$: | Acc]);
++escape_suitename([$\\ | Tail], Acc) -> escape_suitename(Tail, [$: | Acc]);
++escape_suitename([Char | Tail], Acc) when Char < $! -> escape_suitename(Tail, Acc);
++escape_suitename([Char | Tail], Acc) when Char > $~ -> escape_suitename(Tail, Acc);
++escape_suitename([Char | Tail], Acc) -> escape_suitename(Tail, [Char | Acc]).
++
++%% ----------------------------------------------------------------------------
++%% Escape text for XML text nodes.
++%% Replace < with &lt;, > with &gt; and & with &amp;
++%% ----------------------------------------------------------------------------
++escape_text(Text) -> escape_xml(lists:flatten(Text), [], false).
++
++%% ----------------------------------------------------------------------------
++%% Escape text for XML attribute nodes.
++%% Replace < with &lt;, > with &gt; and & with &amp;
++%% ----------------------------------------------------------------------------
++escape_attr(Text) -> escape_xml(lists:flatten(Text), [], true).
++
++escape_xml([], Acc, _ForAttr) -> lists:reverse(Acc);
++escape_xml([$< | Tail], Acc, ForAttr) -> escape_xml(Tail, [$;, $t, $l, $& | Acc], ForAttr);
++escape_xml([$> | Tail], Acc, ForAttr) -> escape_xml(Tail, [$;, $t, $g, $& | Acc], ForAttr);
++escape_xml([$& | Tail], Acc, ForAttr) -> escape_xml(Tail, [$;, $p, $m, $a, $& | Acc], ForAttr);
++escape_xml([$" | Tail], Acc, true) -> escape_xml(Tail, [$;, $t, $o, $u, $q, $& | Acc], true);
++escape_xml([Char | Tail], Acc, ForAttr) when is_integer(Char) -> escape_xml(Tail, [Char | Acc], ForAttr).
++
++%% ----------------------------------------------------------------------------
++%% Determine if the second list begins with the first list.
++%% Return true if it does, false if it doesn't.
++%% ----------------------------------------------------------------------------
++begins_with([], _L2) -> true;
++begins_with([H|T1], [H|T2]) -> begins_with(T1, T2);
++begins_with(_, _) -> false.
++
++%% ----------------------------------------------------------------------------
++%% Return the entry in the tree for a given ID.
++%% Return {value, Entry} if the entry was found or
++%% not_found if it wasn't.
++-spec(entry/2 :: (List :: [tree_entry()], Id :: [integer()]) -> {value, tree_entry()} | not_found).
++%% ----------------------------------------------------------------------------
++entry([{_Kind, Id, _Description, _Data} = Entry | _Tail], Id) -> {value, Entry};
++entry([{group, [H|_] = Id, _Description, Subnodes} | Tail], [H|_] = NodeId) ->
++    case begins_with(Id, NodeId) of
++        true -> entry(Subnodes, NodeId);
++        false -> entry(Tail, NodeId)
++    end;
++entry([_Node | Tail], NodeId) -> entry(Tail, NodeId);
++entry([], _NodeId) -> not_found.
++
++-ifdef(TEST).
++
++format_time_test_() ->
++    [
++    ?_assertEqual("0.000", lists:flatten(format_time(0))),
++    ?_assertEqual("0.001", lists:flatten(format_time(1))),
++    ?_assertEqual("0.042", lists:flatten(format_time(42))),
++    ?_assertEqual("0.123", lists:flatten(format_time(123))),
++    ?_assertEqual("1.000", lists:flatten(format_time(1000))),
++    ?_assertEqual("1.001", lists:flatten(format_time(1001))),
++    ?_assertEqual("1.042", lists:flatten(format_time(1042))),
++    ?_assertEqual("20.042", lists:flatten(format_time(20042)))
++    ].
++
++escape_suitename_test_() ->
++    [
++    ?_assertEqual("sqlite_test", escape_suitename("module 'sqlite_test'")),
++    ?_assertEqual("Unknown-2", escape_suitename(["Unknown-", "2"]))
++    ].
++
++escape_test_() ->
++    [
++    ?_assertEqual("bla bla bla", escape_text("bla bla bla")),
++    ?_assertEqual("1 &lt; 2 -&gt; true", escape_text("1 < 2 -> true")),
++    ?_assertEqual("1 &amp; 2 -&gt; 0", escape_text("1 & 2 -> 0")),
++    ?_assertEqual("and then it said \"Hello, Dave!\"", escape_text("and then it said \"Hello, Dave!\"")),
++    ?_assertEqual("bla bla bla", escape_attr("bla bla bla")),
++    ?_assertEqual("1 &lt; 2 -&gt; true", escape_attr("1 < 2 -> true")),
++    ?_assertEqual("1 &amp; 2 -&gt; 0", escape_attr("1 & 2 -> 0")),
++    ?_assertEqual("and then it said &quot;Hello, Dave!&quot;", escape_attr("and then it said \"Hello, Dave!\""))
++    ].
++
++-endif.  % TEST
+Index: lib/eunit/src/eunit.erl
+===================================================================
+--- lib/eunit/src/eunit.erl.orig	2008-11-04 11:52:12.000000000 +0100
++++ lib/eunit/src/eunit.erl	2008-11-06 07:24:28.000000000 +0100
+@@ -148,7 +148,7 @@
+     try eunit_data:list(Tests) of
+ 	List ->
+ 	    Listeners = [eunit_tty:start(List, Options)
+-			 | listeners(Options)],
++			 | listeners(List, Options)],
+ 	    Serial = eunit_serial:start(Listeners),
+ 	    case eunit_server:start_test(Server, Serial, Tests, Options) of
+ 		{ok, Reference} -> test_run(Reference, Listeners);
+@@ -197,10 +197,12 @@
+     Dummy = spawn(fun devnull/0),
+     eunit_server:start_test(Server, Dummy, T, Options).
+ 
+-listeners(Options) ->
++listeners(List, Options) ->
+     case proplists:get_value(event_log, Options) of
+ 	undefined ->
+ 	    [];
++	{xml, XmlDirectory} ->
++	    [eunit_xml:start(List, Options, XmlDirectory)];
+ 	LogFile ->
+ 	    [spawn(fun () -> event_logger(LogFile) end)]
+     end.
+Index: lib/eunit/src/Makefile
+===================================================================
+--- lib/eunit/src/Makefile.orig	2008-11-04 11:52:12.000000000 +0100
++++ lib/eunit/src/Makefile	2008-11-06 07:23:09.000000000 +0100
+@@ -37,7 +37,8 @@
+ 	eunit_test.erl \
+ 	eunit_lib.erl \
+ 	eunit_data.erl \
+-	eunit_tty.erl
++	eunit_tty.erl \
++	eunit_xml.erl
+ 
+ OBJECTS=$(SOURCES:%.erl=$(EBIN)/%.$(EMULATOR)) $(APP_TARGET) $(APPUP_TARGET)
+ 
Index: files/patch-decode_big.c.diff
===================================================================
--- files/patch-decode_big.c.diff	(revision 0)
+++ files/patch-decode_big.c.diff	(revision 0)
@@ -0,0 +1,13 @@
+--- lib/erl_interface/src/decode/decode_big.c.orig	2008-11-06 06:57:02.000000000 +0100
++++ lib/erl_interface/src/decode/decode_big.c	2008-11-06 06:58:39.000000000 +0100
+@@ -51,7 +51,9 @@
+       u = (unsigned char *) s;
+       for (i = 0; i < b->arity; ++i) {
+ 	  dt[i] = u[i*2];
+-	  dt[i] |= ((unsigned short) u[(i*2)+1]) << 8;
++        if ((i*2 + 1) < digit_bytes) {
++          dt[i] |= ((unsigned short) u[(i*2)+1]) << 8;
++        }
+       }
+   } else {
+       s++; /* skip sign byte */
Index: Portfile
===================================================================
--- Portfile	(revision 41597)
+++ Portfile	(working copy)
@@ -2,8 +2,7 @@
 
 PortSystem 1.0
 name		erlang
-version		R12B-4
-revision    1
+version		R12B-5
 categories	lang erlang
 maintainers	bfulgham@macports.org
 platforms	darwin
@@ -32,29 +31,34 @@
 		otp_doc_man_${version}${extract.suffix}		\
 		otp_doc_html_${version}${extract.suffix}
 
-checksums       otp_src_R12B-4.tar.gz \
-                    md5     ae81edda4a17506af7a9d73abca033b2 \
-                    sha1    4e42454c3f560ce6efd3c917a79a5b288664e329 \
-                    rmd160  3c57ae04388c0493d97c76529c57c50de639bdce \
-                otp_doc_man_R12B-4.tar.gz \
-                    md5     ef8f96d1721a2345cc87b208cde3de06 \
-                    sha1    b954711b493e384606ce23d32a6d980017637b10 \
-                    rmd160  f14eb1f542ebecceddd6ac70aa4ed325f91b0b24 \
-                otp_doc_html_R12B-4.tar.gz \
-                    md5     f633cd418d8260af7a11c998aa88072b \
-                    sha1    cbe6bc52a5000b21de5cac5f9b2672b935e94ed7 \
-                    rmd160  bf05981ddf2e97910141739980cee09572b1c34d
+checksums       otp_src_R12B-5.tar.gz \
+                    md5     250fc48242a098073474e563c3f23e76 \
+                    sha1    681570df942cd53d2c18404b356dd5dc1ff016ef \
+                    rmd160  7473d6119a55365ebe582c55c8b19c3f2870565a \
+                otp_doc_man_R12B-5.tar.gz \
+                    md5     6231cb172847040395cc34b20781aa3b \
+                    sha1    ae7036bd2afc9d1fca97f0de2eca84f56656def8 \
+                    rmd160  e28d555d0a86fc69e0ee091864828c8eaa58d2be \
+                otp_doc_html_R12B-5.tar.gz \
+                    md5     fb0c5454bbd865e881b6712295f6d41f \
+                    sha1    0bd369d02051e01bac58c9b8665bd3538e116f51 \
+                    rmd160  b460906043171b27735332ec90c45e38d888869a
 
 extract.only	otp_src_${version}${extract.suffix}
 
 pre-patch	{ file rename ${workpath}/otp_src_${version} ${workpath}/${name}-${version} }
 
+# http://www.erlang.org/pipermail/erlang-bugs/2008-October/001023.html
+# http://www.erlang.org/pipermail/erlang-bugs/2008-October/001024.html
+# http://support.process-one.net/browse/EUNIT-13
 patchfiles	patch-toolbar.erl \
                 patch-erts_emulator_Makefile.in \
                 patch-lib_ssl_c_src_esock_openssl.c \
                 patch-lib_ssl_c_src_Makefile.dist \
                 patch-lib_ssl_c_src_Makefile.in \
-                patch-erts_emulator_sys_unix_ddll.c
+                patch-decode_big.c.diff \
+                patch-decode_fun.c.diff \
+                patch-eunit_xml.diff
 
 configure.args  --prefix=${destroot}${prefix}	\
                 --enable-kernel-poll            \
@@ -94,7 +98,7 @@
 	system "tar -C ${destroot}${prefix}/lib/erlang -zxvf ${distpath}/otp_doc_html_${version}${extract.suffix}"
 	system "tar -C ${destroot}${prefix}/lib/erlang -zxvf ${distpath}/otp_doc_man_${version}${extract.suffix}"
  
-        set erts_dir   erts-5.6.4
+        set erts_dir   erts-5.6.5
 
         reinplace s|${destroot}|| ${destroot}${prefix}/lib/erlang/bin/erl
         reinplace s|${destroot}|| ${destroot}${prefix}/lib/erlang/bin/start
@@ -106,4 +110,9 @@
 
 	file delete -force ${destroot}${prefix}/lib/erlang/bin/epmd
 	system "ln -s ../${erts_dir}/bin/epmd ${destroot}${prefix}/lib/erlang/bin/epmd"
+
+    # Fix eunit.
+    # See http://www.erlang.org/pipermail/erlang-questions/2008-November/039625.html
+    file mkdir ${destroot}${prefix}/lib/erlang/lib/eunit-2.0/include/
+	file copy ${worksrcpath}/lib/eunit/include/eunit.hrl ${destroot}${prefix}/lib/erlang/lib/eunit-2.0/include/
 }
