# File lib/dnstraverse/traverser.rb, line 122
    def run(r, args = {})
      Log.debug { "run entry, initialising stack to: " + r.to_s }
      cleanup = args[:cleanup]
      stack = Array.new
      stack << r
      while stack.size > 0 do
        Log.debug { "stack size is #{stack.size}" }
        Log.debug {
          counter = 0
          output = ""
          for entry in stack.reverse do
            output+= sprintf "%04d %s\n", counter, entry.to_s
            counter+= 1
          end
          output
        }
        raise "bad stack" if stack.size > 1000
        r = stack.pop
        Log.debug { "running on stack entry #{r}" }
        case r
          when :calc_resolve
          r = stack.pop
          r.resolve_calculate
          refres = r.referral_resolution?
          p = (refres == true ? @progress_resolve : @progress_main)
          p.call(:state => @state, :referral => r, :stage => :resolve)
          stack << r # now need to process
          next
          when :calc_answer
          r = stack.pop
          r.answer_calculate
          refres = r.referral_resolution?
          p = (refres == true ? @progress_resolve : @progress_main)
          p.call(:state => @state, :referral => r, :stage => :answer)
          r.cleanup(cleanup)
          if @fast then
            # store away in @answered hash so we can lookup later
            # XXX fast method should use IP and not server name?
            # or maybe we should append IPs to end... 
            key = "#{r.qname}:#{r.qclass}:#{r.qtype}:#{r.server}:#{r.txt_ips_verbose}"
            key.downcase!
            Log.debug { "Fast mode cache store: #{key}" }
            @answered[key] = r
          end
          unless r.server.nil? then
            @seen[r.server.downcase] = [] unless @seen.has_key?(r.server)
            @seen[r.server.downcase].concat(r.ips_as_array)
            @seen[r.server.downcase].uniq!
          end
          next
        else
          refres = r.referral_resolution?
          p = (refres == true ? @progress_resolve : @progress_main)
          p.call(:state => @state, :referral => r, :stage => :start)
        end
        unless r.resolved? then
          # get resolve Referral objects, place on stack with placeholder
          stack << r << :calc_resolve
          stack.push(*r.resolve({}).reverse)
          next
        end
        unless r.processed? then
          # get Referral objects, place on stack with placeholder
          stack << r << :calc_answer
          children = r.process({})
          if @fast then
            Log.debug { "Checking #{r} for already completed children" }
            newchildren = []
            for c in children do
              key = "#{c.qname}:#{c.qclass}:#{c.qtype}:#{c.server}:#{c.txt_ips_verbose}"
              key.downcase!
              Log.debug { "Fast mode cache lookup: #{key}" }
              # check for previously stored answer
              # special case noglue situation, don't use previous answer
              # because attributes are complicated for stats collection and
              # we don't want to merge them together - creating the noglue
              # response object is fast anyway
              if @answered.key?(key) and (not c.noglue?) then
                Log.debug { "Fast method - completed #{c}" }
                r.replace_child(c, @answered[key])
                refres = r.referral_resolution?
                p = (refres == true ? @progress_resolve : @progress_main)
                p.call(:state => @state, :referral => c, :stage => :answer_fast)
              else
                newchildren << c
              end
            end
            children = newchildren
          end
          stack.push(*children.reverse)
          next
        end
        raise "Fatal stack error at #{r} - size still #{stack.size}"
      end
    end