anchor.diff:      "arrays of numbers, or objects. Objects cannot be mixed with other data "
       "structures. Objects can be arbitrarily nested, provided that the values "
       "for all fields are themselves numbers, arrays of numbers, or objects.">>).
  +
  +-define(STATERROR, <<"The _stats function requires that map values be numbers "
  +    "or arrays of numbers.">>).
   
   % https://gist.github.com/df10284c76d85f988c3f
   -define(SUMREGEX, {re_pattern,3,0,<<69,82,67,80,194,0,0,0,8,0,0,0,5,0,0,0,3,0,
  
positive.code:     ?assertEqual(Z, sum_values(X, Y)),
      ?assertEqual(Z, sum_values(Y, X)).
  
  -endif.
  
negative.code: sum_arrays(_, _) ->
      throw({invalid_value, ?SUMERROR}).
  
  builtin_stats(_, []) ->
      {[{sum,0}, {count,0}, {min,0}, {max,0}, {sumsqr,0}]};
  builtin_stats(_, [[_,First]|Rest]) ->
      Unpacked = lists:foldl(fun([_key, Value], Acc) -> stat_values(Value, Acc) end,
                             build_initial_accumulator(First), Rest),
      pack_stats(Unpacked).
  
  stat_values(Value, Acc) when is_list(Value), is_list(Acc) ->
      lists:zipwith(fun stat_values/2, Value, Acc);
  stat_values({PreRed}, Acc) when is_list(PreRed) ->
      stat_values(unpack_stats({PreRed}), Acc);
  stat_values(Value, Acc) when is_number(Value) ->
      stat_values({Value, 1, Value, Value, Value*Value}, Acc);
  stat_values(Value, Acc) when is_number(Acc) ->
      stat_values(Value, {Acc, 1, Acc, Acc, Acc*Acc});
  stat_values(Value, Acc) when is_tuple(Value), is_tuple(Acc) ->
      {Sum0, Cnt0, Min0, Max0, Sqr0} = Value,
      {Sum1, Cnt1, Min1, Max1, Sqr1} = Acc,
      {
        Sum0 + Sum1,
        Cnt0 + Cnt1,
        erlang:min(Min0, Min1),
        erlang:max(Max0, Max1),
        Sqr0 + Sqr1
      };
  stat_values(_Else, _Acc) ->
      throw({invalid_value, ?STATERROR}).
  
  build_initial_accumulator(L) when is_list(L) ->
      [build_initial_accumulator(X) || X <- L];
  build_initial_accumulator(X) when is_number(X) ->
      {X, 1, X, X, X*X};
  build_initial_accumulator({Props}) ->
      unpack_stats({Props});
  build_initial_accumulator(Else) ->
      Msg = io_lib:format("non-numeric _stats input: ~w", [Else]),
      throw({invalid_value, iolist_to_binary(Msg)}).
  
  unpack_stats({PreRed}) when is_list(PreRed) ->
      {
        get_number(<<"sum">>, PreRed),
        get_number(<<"count">>, PreRed),
        get_number(<<"min">>, PreRed),
        get_number(<<"max">>, PreRed),
        get_number(<<"sumsqr">>, PreRed)
      }.
  
  pack_stats({Sum, Cnt, Min, Max, Sqr}) ->
      {[{<<"sum">>,Sum}, {<<"count">>,Cnt}, {<<"min">>,Min}, {<<"max">>,Max}, {<<"sumsqr">>,Sqr}]};
  pack_stats(Stats) when is_list(Stats) ->
      lists:map(fun pack_stats/1, Stats).
  
  get_number(Key, Props) ->
      case couch_util:get_value(Key, Props) of
  