anchor.diff:        % if it is a sibling then we should not restart
         case check_if_parent(Name, Answer#dns_rr.name) of
           true ->
  -          restart_delegated_query(Message, Name, Qtype, Host, CnameChain, Zone, erldns_zone_cache:in_zone(Name));
  +          restart_delegated_query(Message, Name, Qtype, ClientIP, CnameChain, Zone, erldns_zone_cache:in_zone(Name));
           false ->
             Message#dns_message{aa = true, rc = ?DNS_RCODE_NOERROR, answers = Message#dns_message.answers ++ MatchedRecords}
         end
  
positive.code: 
  %% There were no exact type matches, but there were other name matches and there are NS records.
  %% Since the Qtype is ANY we indicate we are authoritative and include the NS records.
  resolve_no_exact_type_match(Message, ?DNS_TYPE_ANY, _Host, _CnameChain, _ExactTypeMatches, _Zone, [], [], AuthorityRecords) ->
    Message#dns_message{aa = true, authority = AuthorityRecords};
  resolve_no_exact_type_match(Message, _Qtype, _Host, _CnameChain, [], Zone, _MatchedRecords, [], _AuthorityRecords) ->
    Message#dns_message{aa = true, authority = Zone#zone.authority};
  resolve_no_exact_type_match(Message, _Qtype, _Host, _CnameChain, ExactTypeMatches, _Zone, _MatchedRecords, [], _AuthorityRecords) ->
    Message#dns_message{aa = true, answers = Message#dns_message.answers ++ ExactTypeMatches};
  resolve_no_exact_type_match(Message, Qtype, _Host, _CnameChain, _ExactTypeMatches, _Zone, MatchedRecords, ReferralRecords, AuthorityRecords) ->
    resolve_exact_match_referral(Message, Qtype, MatchedRecords, ReferralRecords, AuthorityRecords).
  
  
  
negative.code: 
  % There is a CNAME record and the request was for a CNAME record so append the CNAME records to
  % the answers section..
  resolve_exact_match_with_cname(Message, ?DNS_TYPE_CNAME, _ClientIP, _CnameChain, _MatchedRecords, _Zone, CnameRecords) ->
    Message#dns_message{aa = true, answers = Message#dns_message.answers ++ CnameRecords};
  % There is a CNAME record, however the Qtype is not CNAME, check for a CNAME loop before continuing.
  resolve_exact_match_with_cname(Message, Qtype, ClientIP, CnameChain, MatchedRecords, Zone, CnameRecords) ->
    resolve_exact_match_with_cname(Message, Qtype, ClientIP, CnameChain, MatchedRecords, Zone, CnameRecords, lists:member(lists:last(CnameRecords), CnameChain)).
  
  %% Indicates a CNAME loop. The response code is a SERVFAIL in this case.
  resolve_exact_match_with_cname(Message, _Qtype, _ClientIP, _CnameChain, _MatchedRecords, _Zone, _CnameRecords, true) ->
    %lager:debug("CNAME loop detected (exact match)"),
    Message#dns_message{aa = true, rc = ?DNS_RCODE_SERVFAIL};
  % No CNAME loop, restart the query with the CNAME content.
  resolve_exact_match_with_cname(Message, Qtype, ClientIP, CnameChain, _MatchedRecords, Zone, CnameRecords, false) ->
    CnameRecord = lists:last(CnameRecords),
    Name = CnameRecord#dns_rr.data#dns_rrdata_cname.dname,
    %lager:debug("Restarting query with CNAME name ~p (exact match)", [Name]),
    restart_query(Message#dns_message{aa = true, answers = Message#dns_message.answers ++ CnameRecords}, Name, Qtype, ClientIP, CnameChain ++ CnameRecords, Zone, erldns_zone_cache:in_zone(Name)).
  
  
  
  % The CNAME is in the zone so we do not need to look it up again.
  restart_query(Message, Name, Qtype, ClientIP, CnameChain, Zone, true) ->
    resolve(Message, Name, Qtype, Zone, ClientIP, CnameChain);
  % The CNAME is not in the zone, so we need to find the zone using the
  % CNAME content.
  restart_query(Message, Name, Qtype, ClientIP, CnameChain, _Zone, false) ->
    resolve(Message, Name, Qtype, erldns_zone_cache:find_zone(Name), ClientIP, CnameChain).
  
  % Delegated, but in the same zone.
  restart_delegated_query(Message, Name, Qtype, ClientIP, CnameChain, Zone, true) ->
    resolve(Message, Name, Qtype, Zone, ClientIP, CnameChain);
  % Delegated to a different zone.
  restart_delegated_query(Message, Name, Qtype, ClientIP, CnameChain, Zone, false) ->
    resolve(Message, Name, Qtype, erldns_zone_cache:find_zone(Name, Zone#zone.authority), ClientIP, CnameChain). % Zone lookup
  
  
  
  % There was no exact match for the Qname, so we use the best matches that were
  % returned by the best_match() function.
  best_match_resolution(Message, Qname, Qtype, ClientIP, CnameChain, BestMatchRecords, Zone) ->
    %lager:debug("No exact match found, using ~p", [BestMatchRecords]),
    ReferralRecords = lists:filter(erldns_records:match_type(?DNS_TYPE_NS), BestMatchRecords), % NS lookup
    best_match_resolution(Message, Qname, Qtype, ClientIP, CnameChain, BestMatchRecords, Zone, ReferralRecords).
  
  % There were no NS records in the best matches.
  best_match_resolution(Message, Qname, Qtype, ClientIP, CnameChain, BestMatchRecords, Zone, []) ->
    resolve_best_match(Message, Qname, Qtype, ClientIP, CnameChain, BestMatchRecords, Zone);
  % There were NS records in the best matches, so this is a referral.
  best_match_resolution(Message, Qname, Qtype, ClientIP, CnameChain, BestMatchRecords, Zone, ReferralRecords) ->
    resolve_best_match_referral(Message, Qname, Qtype, ClientIP, CnameChain, BestMatchRecords, Zone, ReferralRecords).
  
  
  % There is no referral, so check to see if there is a wildcard.
  resolve_best_match(Message, Qname, Qtype, ClientIP, CnameChain, BestMatchRecords, Zone) ->
    %lager:debug("No referrals found"),
    resolve_best_match(Message, Qname, Qtype, ClientIP, CnameChain, BestMatchRecords, Zone, lists:any(erldns_records:match_wildcard(), BestMatchRecords)).
  
  %% It's a wildcard match
  resolve_best_match(Message, Qname, Qtype, ClientIP, CnameChain, BestMatchRecords, Zone, true) ->
    %lager:debug("Matched records are wildcard."),
    CnameRecords = lists:filter(erldns_records:match_type(?DNS_TYPE_CNAME), lists:map(erldns_records:replace_name(Qname), BestMatchRecords)),
    resolve_best_match_with_wildcard(Message, Qname, Qtype, ClientIP, CnameChain, BestMatchRecords, Zone, CnameRecords);
  %% It is not a wildcard.
  resolve_best_match(Message, Qname, _Qtype, _ClientIP, _CnameChain, _BestMatchRecords, Zone, false) ->
    %lager:debug("Matched records are not wildcard."),
    [Question|_] = Message#dns_message.questions,
    case Qname =:= Question#dns_query.name of
  