anchor.diff:  %%% gen_server callbacks
   %%%===================================================================
   init([]) ->
  -    {ok, #state{}}.
  +    %%Set up orddict and put it in state
  +    Orddict = setup_zone_expiration_orddict(),
  +    {ok, #state{zone_expirations = Orddict, orddict_size = orddict:size(Orddict)}, 0}.
   
   handle_call(_Request, _From, State) ->
       {reply, ok, State}.
   
   handle_cast({send_notify, {_BindIP, _DestinationIP, _ZoneName, _ZoneClass} = Args}, State) ->
       Spec = {{erldns_zone_transfer_worker, now()}, {erldns_zone_transfer_worker, start_link, [send_notify, Args]},
  -            temporary, 5000, worker, [erldns_zone_transfer_worker]},
  +        temporary, 5000, worker, [erldns_zone_transfer_worker]},
       supervisor:start_child(erldns_zone_transfer_sup, Spec),
  -    {noreply, State};
  +    {noreply, State, ?REFRESH_INTERVAL};
   handle_cast({handle_notify, {_Message, _ClientIP, _ServerIP} = Args}, State) ->
       Spec = {{erldns_zone_transfer_worker, now()}, {erldns_zone_transfer_worker, start_link, [handle_notify, Args]},
           temporary, 5000, worker, [erldns_zone_transfer_worker]},
       supervisor:start_child(erldns_zone_transfer_sup, Spec),
  -    {noreply, State};
  +    {noreply, State, ?REFRESH_INTERVAL};
   handle_cast({send_axfr, {_ZoneName, _ServerIP} = Args}, State) ->
       Spec = {{erldns_zone_transfer_worker, now()}, {erldns_zone_transfer_worker, start_link, [send_axfr, Args]},
           temporary, 5000, worker, [erldns_zone_transfer_worker]},
       supervisor:start_child(erldns_zone_transfer_sup, Spec),
  -    {noreply, State};
  +    {noreply, State, ?REFRESH_INTERVAL};
   handle_cast(_Request, State) ->
       erldns_log:info("Some other message: ~p", [_Request]),
  -    {noreply, State}.
  +    {noreply, State, ?REFRESH_INTERVAL}.
   
  +%% @doc Every interval it checks for entry in orrdict to see if zone is expired, if not it restarts
  +%% timer with the same order, else it sends an axfr to the associated master, reorders the
  +%% dict and restarts the timer.
  +%% @end
  +handle_info(timeout, #state{zone_expirations = Orddict, orddict_size = Size} = State) when Size > 0 ->
  +    Before = now(),
  +    %% DO MAGIC
  +    Timestamp = timestamp(),
  +    NewOrddict = case hd(orddict:to_list(Orddict)) of
  +                     {Expiration, ListOfExpiredZones} when Expiration < Timestamp ->
  +                         [gen_server:cast(erldns_manager, {send_axfr, Args}) || Args <- ListOfExpiredZones],
  +                         create_new_zone_expiration_orddict(Expiration, Orddict, ListOfExpiredZones);
  +                     {Expiration, _ListOfExpiredZone} when Expiration >= Timestamp ->
  +                         Orddict
  +                 end,
  +    TimeSpentMs = timer:now_diff(now(), Before) div 1000,
  +    {noreply, State#state{zone_expirations = NewOrddict, orddict_size = orddict:size(NewOrddict)},
  +        ?REFRESH_INTERVAL + TimeSpentMs};
  +handle_info(timeout, State)  ->
  +    %%TODO Should we attempt a refresh? And check if there are now zones in our authroity we should watch?
  +    {noreply, State, ?REFRESH_INTERVAL};
   handle_info(_Info, State) ->
  -    {noreply, State}.
  +    {noreply, State, ?REFRESH_INTERVAL}.
   
   terminate(_Reason, _State) ->
       ok.
   
   code_change(_OldVsn, State, _Extra) ->
  -    {ok, State}.
  +    {ok, State, ?REFRESH_INTERVAL}.
   
   %%%===================================================================
   %%% Internal functions
   %%%===================================================================
  +%% @doc This function creates a orrdict for the zones the slave  has. This orddict serves as
  +%% a data structure that stores expiration as a key with the list of arguments necessary to
  +%% initiate a zone transfer (AXFR) for the expired zone(s).
  +%% @end
  +-spec setup_zone_expiration_orddict() -> orddict:orddict().
  +setup_zone_expiration_orddict() ->
  +    %% Get the bind IP we will use to send the AXFR
  +    {ok, IFAddrs} = inet:getifaddrs(),
  +    MountedIPAddresses = [begin
  +                             {addr, Addr} = lists:keyfind(addr, 1, List),
  +                             Addr
  +                         end || {_, List} <- IFAddrs],
  +    NewOrrdict = lists:foldl(
  +        fun({ZoneName, _ZoneVersion}, Orrdict) ->
  +            {ok, Zone} = erldns_zone_cache:get_zone_with_records(ZoneName),
  +            case Zone#zone.allow_transfer of
  +                [] ->
  +                    Orrdict;
  +                _ ->
  +                    MountedIP = hd(lists:sort([IP || IP <- MountedIPAddresses,
  +                        lists:member(IP, Zone#zone.allow_transfer)])),
  +                    case Zone#zone.notify_source =:= MountedIP of
  +                        true ->
  +                            %% We are the zone Authority, we don't need to keep track of this zone.
  +                            Orrdict;
  +                        false ->
  +                            %% We are slave of a zone, we need to keep track of it and send afxr when it expires
  +                            [ZoneAuth0] = Zone#zone.authority,
  +                            ZoneAuth = ZoneAuth0#dns_rr.data,
  +                            Expiration = ZoneAuth#dns_rrdata_soa.expire + timestamp(),
  +                            ArgsToSendAXFR = {ZoneName, MountedIP},
  +                            orddict:append(Expiration, ArgsToSendAXFR, Orrdict)
  +                    end
  +            end
  +         end,
  +        orddict:new(),
  +        erldns_zone_cache:zone_names_and_versions()),
  +    NewOrrdict.
   
  +%% @doc This function takes the expiration of the zone list as the key, and deletes that entry in the
  +%% orddict. Then appends a refreshed expiration in the correct order of the dict.
  +%% @end
  +-spec create_new_zone_expiration_orddict(integer(), orddict:orddict(),
  +    [{ZoneName :: binary(), BindIP :: inet:ip_address()}]) -> orddict:orddict().
  +create_new_zone_expiration_orddict(ExpirationKey, Orddict, ListOfExpiredZones) ->
  +    Orddict0 = orddict:erase(ExpirationKey, Orddict),
  +    lists:flatten([orddict:append(get_expiration(ZoneName), Args, Orddict0)
  +        || {ZoneName, _ServerIP} = Args <- ListOfExpiredZones]).
  +
  +%%     lists:foldl(fun({ZoneName, _ServerIP} = Args, NewOrddict) ->
  +%%                     orddict:append(get_expiration(ZoneName), Args, NewOrddict)
  +%%                     end, Orddict0, ListOfExpiredZones).
  +
  +%% @doc Gets the expiration of the given zone name
  +-spec get_expiration(binary()) -> integer().
  +get_expiration(ZoneName) ->
  +    {ok, #zone{} = Zone} = erldns_zone_cache:get_zone_with_records(ZoneName),
  +    [#dns_rr{data = #dns_rrdata_soa{expire = Expire}}] = Zone#zone.authority,
  +    Expire + timestamp().
  +
  +timestamp() ->
  +    {TM, TS, _} = os:timestamp(),
  +    (TM * 1000000) + TS.
  
positive.code: 
  -behaviour(gen_server).
  
  %% API
  -export([start_link/0]).
  
  
negative.code:     code_change/3]).
  
  -define(SERVER, ?MODULE).
  -define(REFRESH_INTERVAL, 5000).
  
  -record(state, {zone_expirations, orddict_size}).
  
  %%%===================================================================
  %%% API
  