anchor.diff:       ?_assertEqual([2, 4, 6], zip_lists([[1,2,3], [1,2,3,4]], fun lists:sum/1)),
        ?_assertEqual([2, 4, 6], zip_lists([[1,2,3], [1,2,3,4,5,6,7]], fun lists:sum/1)),
        ?_assertEqual([3, 6, 9], zip_lists([[1,2,3], [1,2,3], [1,2,3]], fun lists:sum/1))
  +    ].
  +
  +moving_average_test_() ->
  +    [?_assertEqual([], moving_average([], 3)),
  +     ?_assertEqual([6/3,9/3,10/3,9/3,6/3,4/3,3/3], moving_average([1,2,3,4,3,2,1,1,1], 3)),
  +     ?_assertEqual([6/3], moving_average([1,4,1], 3)),
  +     ?_assertEqual([6/3], moving_average([1,4,1], 4)),
  +     ?_assertEqual([1/1,4/1,1/1], moving_average([1,4,1], 1)),
  +     ?_assertEqual([5/2,9/3,10/3,9/3,6/3,4/3,2/2], moving_average([null,2,3,4,3,2,1,1,null], 3))
       ].
   
   percentile_test_() ->
  
positive.code:                               % there is no metrics handler already meaning
                                % there is nothing cached to be merged
                                % -> just read from fs directly instead
                                File = statser_metric_handler:get_whisper_file(Path),
                                Result = statser_whisper:fetch(File, From, Until, Now),
                                Result#series{target=Path};
  
negative.code:     safe_sum(Vs, Acc + Value).
  
  
  safe_length(Vs) ->
      safe_length(Vs, 0).
  
  safe_length([], Len) -> Len;
  safe_length([null | Xs], Len) ->
      safe_length(Xs, Len);
  safe_length([{_TS, null} | Xs], Len) ->
      safe_length(Xs, Len);
  safe_length([_ | Xs], Len) ->
      safe_length(Xs, Len + 1).
  
  
  safe_multiply([]) -> null;
  safe_multiply([{_TS, V} | Vs]) ->
      safe_multiply(Vs, V);
  