anchor.diff:           get_zone_notify_source/1
           ]).
   
  -% Write APIs
  +%% Write APIs
   -export([
            build_zone/8,
            build_zone/9,
  
positive.code:             ok = put_zone(ZoneName, Zone),
              send_notify(ZoneName, Zone)
      end.
  % ----------------------------------------------------------------------------------------------------
  % Gen server init
  
  %% @doc Initialize the zone cache.
  -spec init([]) -> {ok, #state{}}.
  init([]) ->
    case erldns_config:storage_type() of
      erldns_storage_mnesia ->
          erldns_storage:create(schema);
      _ ->
          ok
    end,
    erldns_storage:create(zones),
    erldns_storage:create(authorities),
    {ok, #state{parsers = []}}.
  
  % ----------------------------------------------------------------------------------------------------
  % gen_server callbacks
  
  %% @doc Write the zone into the cache.
  handle_call({put, Name, Zone}, _From, State) ->
    erldns_storage:insert(zones, {normalize_name(Name), Zone}),
    {reply, ok, State};
  
  handle_call({put, Name, Sha, Records, AllowNotifyList, AllowTransferList, AllowUpdateList, AlsoNotifyList,
      NotifySourceIP}, _From, State) ->
    erldns_storage:insert(zones, {normalize_name(Name), build_zone(Name, AllowNotifyList,
        AllowTransferList, AllowUpdateList, AlsoNotifyList, NotifySourceIP, Sha, Records)}),
    {reply, ok, State}.
  
  handle_cast({put, Name, Zone}, State) ->
    erldns_storage:insert(zones, {normalize_name(Name), Zone}),
    {noreply, State};
  
  handle_cast({put, Name, Sha, Records, AllowNotifyList, AllowTransferList, AllowUpdateList, AlsoNotifyList,
      NotifySourceIP}, State) ->
    erldns_storage:insert(zones, {normalize_name(Name), build_zone(Name, AllowNotifyList,
        AllowTransferList, AllowUpdateList, AlsoNotifyList, NotifySourceIP, Sha, Records)}),
    {noreply, State};
  
  handle_cast({delete, Name}, State) ->
    erldns_storage:delete(zones, normalize_name(Name)),
    {noreply, State};
  
  handle_cast(Message, State) ->
    erldns_log:debug("Received unsupported message: ~p", [Message]),
    {noreply, State}.
  
  handle_info(_Message, State) ->
    {noreply, State}.
  
  terminate(_Reason, _State) ->
    ok.
  
  code_change(_PreviousVersion, State, _Extra) ->
    {ok, State}.
  
  
  % Internal API
  %% @doc Removes the expiration timestamp from the list of dns_rrs stored in the dict.
  -spec remove_expiry([{non_neg_integer(), dns:rr()}] | []) -> [] | [dns:rr()].
  remove_expiry([]) ->
  
negative.code: %% This function will build the necessary Zone record before interting.
  -spec put_zone({binary(), binary(), [#dns_rr{}]}) -> ok | {error, Reason :: term()}.
  put_zone({Name, Sha, Records, AllowNotifyList, AllowTransferList, AllowUpdateList, AlsoNotifyList,
            NotifySourceIP}) ->
      erldns_storage:insert(zones,
                            {normalize_name(Name), build_zone(Name, AllowNotifyList, AllowTransferList,
                                                              AllowUpdateList, AlsoNotifyList,
                                                              NotifySourceIP, Sha, Records)}).
  
  %% @doc Put a zone into the cache and wait for a response.
  -spec put_zone(binary(), #zone{}) -> ok | {error, Reason :: term()}.
  put_zone(Name, #zone{} = Zone) ->
      erldns_storage:insert(zones, {normalize_name(Name), Zone}).
  
  %% @doc Put a zone into the cache without waiting for a response.
  -spec put_zone_async({binary(), binary(), [#dns_rr{}]}) -> ok | {error, Reason :: term()}.
  put_zone_async({Name, Sha, Records, AllowNotifyList, AllowTransferList, AllowUpdateList, AlsoNotifyList,
                  NotifySourceIP}) ->
      erldns_storage:insert(zones,
                            {normalize_name(Name), build_zone(Name, AllowNotifyList,AllowTransferList,
                                                              AllowUpdateList, AlsoNotifyList,
                                                              NotifySourceIP, Sha, Records)}).
  
  %% @doc Put a zone into the cache without waiting for a response.
  -spec put_zone_async(binary(), #zone{}) -> ok | {error, Reason :: term()}.
  put_zone_async(Name, Zone) ->
      erldns_storage:insert(zones, {normalize_name(Name), Zone}).
  
  %% @doc Remove a zone from the cache.
  -spec delete_zone(binary()) -> ok | {error, term()}.
  