anchor.diff:  %%
   %% %CopyrightBegin%
   %%
  -%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
  +%% Copyright Ericsson AB 2010-2022. All Rights Reserved.
   %%
   %% Licensed under the Apache License, Version 2.0 (the "License");
   %% you may not use this file except in compliance with the License.
  
positive.code: %% ---------------------------------------------------------------------------
  %% run/1
  %%
  %% Evaluate functions in parallel and return a list of those that
  %% failed to return. The fun takes a boolean (did the function return
  %% or not), the function that was evaluated, the return value or exit
  %% reason and the prevailing accumulator.
  
  run(L) ->
      fold(fun cons/4, [], L).
  
  cons(true, _, _, Acc) ->
      Acc;
  cons(false, F, RC, Acc) ->
      [{F, RC} | Acc].
  
  %% ---------------------------------------------------------------------------
  %% fold/3
  %%
  %% Parallel fold. Results are folded in the order received.
  
  fold(Fun, Acc0, L)
    when is_function(Fun, 4) ->
      Ref = make_ref(),
      %% Spawn a middleman to collect down messages from processes
      %% spawned for each function so as not to assume that all DOWN
      %% messages are ours.
      MRef = run1([fun fold/4, Ref, Fun, Acc0, L], Ref),
      {Ref, RC} = down(MRef),
      RC.
  
  fold(Ref, Fun, Acc0, L) ->
      recv(run(Ref, L), Ref, Fun, Acc0).
  
  run(Ref, L) ->
      [{run1(F, Ref), F} || F <- L].
  
  run1(F, Ref) ->
      {_, MRef} = spawn_monitor(fun() -> exit({Ref, eval(F)}) end),
      MRef.
  
  recv([], _, _, Acc) ->
      Acc;
  recv(L, Ref, Fun, Acc) ->
      {MRef, R} = down(),
      {MRef, F} = lists:keyfind(MRef, 1, L),
      recv(lists:keydelete(MRef, 1, L),
           Ref,
           Fun,
           acc(R, Ref, F, Fun, Acc)).
  
  acc({Ref, RC}, Ref, F, Fun, Acc) ->
      Fun(true, F, RC, Acc);
  acc(Reason, _, F, Fun, Acc) ->
      Fun(false, F, Reason, Acc).
  
  down(MRef) ->
      receive {'DOWN', MRef, process, _, Reason} -> Reason end.
  
  down() ->
      receive {'DOWN', MRef, process, _, Reason} -> {MRef, Reason} end.
  
  %% ---------------------------------------------------------------------------
  %% foldl/3
  %%
  %% Parallel fold. Results are folded in order of the function list.
  
  foldl(Fun, Acc0, L)
    when is_function(Fun, 4) ->
      Ref = make_ref(),
      recvl(run(Ref, L), Ref, Fun, Acc0).
  
  recvl([], _, _, Acc) ->
      Acc;
  recvl([{MRef, F} | L], Ref, Fun, Acc) ->
      R = down(MRef),
      recvl(L, Ref, Fun, acc(R, Ref, F, Fun, Acc)).
  
  %% ---------------------------------------------------------------------------
  %% scramble/1
  
negative.code:          fold/3,
           foldl/3,
           scramble/1,
           choose/1,
           tmpdir/0,
           mktemp/1,
           unique_string/0,
           have_sctp/0,
           eprof/1]).
  