anchor.diff:           terminate/2,
            code_change/3]).
   
  --record(state, {port, socket, counters, timers, gauges, sets, timer}).
  +-record(state, {port, interval, counters, timers, gauges, sets, timer}).
   
   -define(DELIMITER_PIPE, <<"|">>).
   -define(DELIMITER_COLON, <<":">>).
  
positive.code: -ifdef(TEST).
  
  calculate_timer_test_() ->
      [?_assertEqual(null, calculate_timer([], 0)),
       ?_assertEqual({0, 100, 100/2, 100/2, 5000.0, [0, 100], [0, 10000], 2, 100, 10000}, calculate_timer([100, 0], 2)),
       ?_assertEqual({1, 3, 2.0, 2.0, 2.0, [1, 3, 6], [1, 5, 14], 3, 6, 14}, calculate_timer([1, 3, 2], 3))
      ].
  
  -endif.
  
negative.code: %%                                  {stop, Reason, State}
  %% @end
  %%--------------------------------------------------------------------
  handle_cast(accept, #state{port=Port, interval=Interval} = State) ->
      Self = self(),
      {ok, Socket} = gen_udp:open(Port, [binary, {active, false}]),
      lager:info("UDP listener opened port at ~w [~p]", [Port, Socket]),
  
      % TODO: maybe we want to synchronize the flush interval with
      % the wall clock time matching with the graphite aggregation
      {ok, Timer} = timer:send_interval(Interval, flush),
  
      % TODO: handle exit/failure
      spawn_link(?MODULE, listen, [Self, Socket]),
      {noreply, State#state{timer=Timer}};
  
  handle_cast(_Msg, State) ->
      {noreply, State}.
  