# File lib/sup/ferret_index.rb, line 185
  def each_message_in_thread_for m, opts={}
    #debug "Building thread for #{m.id}: #{m.subj}"
    messages = {}
    searched = {}
    num_queries = 0

    pending = [m.id]
    if $config[:thread_by_subject] # do subject queries
      date_min = m.date - (SAME_SUBJECT_DATE_LIMIT * 12 * 3600)
      date_max = m.date + (SAME_SUBJECT_DATE_LIMIT * 12 * 3600)

      q = Ferret::Search::BooleanQuery.new true
      sq = Ferret::Search::PhraseQuery.new(:subject)
      wrap_subj(Message.normalize_subj(m.subj)).split.each do |t|
        sq.add_term t
      end
      q.add_query sq, :must
      q.add_query Ferret::Search::RangeQuery.new(:date, :>= => date_min.to_indexable_s, :<= => date_max.to_indexable_s), :must

      q = build_ferret_query :qobj => q

      p1 = @index_mutex.synchronize { @index.search(q).hits.map { |hit| @index[hit.doc][:message_id] } }
      debug "found #{p1.size} results for subject query #{q}"

      p2 = @index_mutex.synchronize { @index.search(q.to_s, :limit => :all).hits.map { |hit| @index[hit.doc][:message_id] } }
      debug "found #{p2.size} results in string form"

      pending = (pending + p1 + p2).uniq
    end

    until pending.empty? || (opts[:limit] && messages.size >= opts[:limit])
      q = Ferret::Search::BooleanQuery.new true
      # this disappeared in newer ferrets... wtf.
      # q.max_clause_count = 2048

      lim = [MAX_CLAUSES / 2, pending.length].min
      pending[0 ... lim].each do |id|
        searched[id] = true
        q.add_query Ferret::Search::TermQuery.new(:message_id, id), :should
        q.add_query Ferret::Search::TermQuery.new(:refs, id), :should
      end
      pending = pending[lim .. -1]

      q = build_ferret_query :qobj => q

      num_queries += 1
      killed = false
      @index_mutex.synchronize do
        @index.search_each(q, :limit => :all) do |docid, score|
          break if opts[:limit] && messages.size >= opts[:limit]
          if @index[docid][:label].split(/\s+/).include?("killed") && opts[:skip_killed]
            killed = true
            break
          end
          mid = @index[docid][:message_id]
          unless messages.member?(mid)
            #debug "got #{mid} as a child of #{id}"
            messages[mid] ||= lambda { build_message docid }
            refs = @index[docid][:refs].split
            pending += refs.select { |id| !searched[id] }
          end
        end
      end
    end

    if killed
      #debug "thread for #{m.id} is killed, ignoring"
      false
    else
      #debug "ran #{num_queries} queries to build thread of #{messages.size} messages for #{m.id}: #{m.subj}" if num_queries > 0
      messages.each { |mid, builder| yield mid, builder }
      true
    end
  end