BufferManager.flash "#{threads.size.pluralize 'Thread'} killed."
        end
      
---- -  def save
---  -    BufferManager.say("Saving contacts...") { ContactManager.instance.save }
---- -    dirty_threads = @mutex.synchronize { (@threads + @hidden_threads.keys).select { |t| t.dirty? } }
---- -    return if dirty_threads.empty?
++++ +  def save background=true
++++ +    if background
++++ +      Redwood::reporting_thread("saving thread") { actually_save }
++++ +    else
++++ +      actually_save
++++ +    end
++++ +  end
++ + +
  -       BufferManager.say("Saving threads...") do |say_id|
  -         dirty_threads.each_with_index do |t, i|
  -           BufferManager.say "Saving modified thread #{i + 1} of #{dirty_threads.length}...", say_id
  -           t.save Index
++++ +  def actually_save
++++ +    @save_thread_mutex.synchronize do
++++ +      BufferManager.say("Saving contacts...") { ContactManager.instance.save }
++++ +      dirty_threads = @mutex.synchronize { (@threads + @hidden_threads.keys).select { |t| t.dirty? } }
++++ +      next if dirty_threads.empty?
  +   
-- - -    BufferManager.say("Saving threads...") do |say_id|
-- - -      dirty_threads.each_with_index do |t, i|
-- - -        BufferManager.say "Saving modified thread #{i + 1} of #{dirty_threads.length}...", say_id
-- - -        t.save Index
++++ +      BufferManager.say("Saving threads...") do |say_id|
++++ +        dirty_threads.each_with_index do |t, i|
++++ +          BufferManager.say "Saving modified thread #{i + 1} of #{dirty_threads.length}...", say_id
++++ +          t.save Index
++++ +        end
            end
          end
        end