anchor.diff:  groupby_duplicates_test() ->
       Inp = [c, a, b, c, a, b],
       Exp = [{a, [a,a]}, {b, [b,b]}, {c, [c,c]}],
  -    Fun = fun(E) -> E end,
  +    Fun = fun(E) -> {E, E} end,
       ?assertEqual(Exp, ?utils:group(Fun, Inp)).
   
   -ifdef(PROPER).
  
positive.code: 	 list_shuffle/1, date_str/1, any_to_list/1,
       merge_proplists/2, compare_proplists/2,
       find/2, wait/1, expect/1, shutdown/1, ping/1,
       first/0, group/2]).
  
  %% "mock-like" functions
  -export([reply/1]).
  
negative.code: %% This function will return a list of key-value pairs where
  %% the key is returned by the key function and the value is
  %% a list of values having that key.
  %% The function must return a {Key, Value} pair.
  %% @end
  -spec group(fun((term()) -> {term(), term()}), []) -> [{term(), []}].
  group(Function, List) ->
      groupby(Function, List, gb_trees:empty()).
  
  groupby(_Function, [], Acc) ->
      gb_trees:to_list(Acc);
  
  groupby(Function, [H|T], Acc) ->
      {Key, Value} = Function(H),
      TmpAcc = case gb_trees:is_defined(Key, Acc) of
          true  -> Acc;
          false -> gb_trees:insert(Key, [], Acc)
      end,
      Values = gb_trees:get(Key, TmpAcc),
      NewAcc = gb_trees:update(Key, [Value|Values], TmpAcc),
      groupby(Function, T, NewAcc).
  
  
  % @doc Subtract a time delta in millsecs from a now() triple
  