de-archived messages should be auto-added to inbox
 drafts sometimes not loaded
-bugfix: first time viewing a message only gets the first to:;
-   subsequent views get them all (wtf)
 add a flag to sup-import to force the creation of a new source (see http://rubyforge.org/forum/forum.php?thread_id=10973&forum_id=10340)
 fix bug: when returning from a shelling out, ncurses is crazy 
 batch deletion
 be able to mark individual messages as spam in thread-view-mode
 toggle wrapping
 
+x bugfix: first time viewing a message only gets the first to:; subsequent views get them all (wtf)
 x search for other messages from author in thread-view-mode
 x resuming of arbitrary messages
 x alias authors in thread-view-mode
 
 
       ## TODO: handle unknown mime-types
       system "/usr/bin/run-mailcap --action=view #{@content_type}:#{@file.path}"
+      $? == 0
     end
 
     def to_s; @part.decode; end
 
   attr_reader :id, :date, :from, :subj, :refs, :replytos, :to, :source,
               :cc, :bcc, :labels, :list_address, :recipient_email, :replyto,
-              :source_info
+              :source_info, :chunks
 
   bool_reader :dirty, :source_marked_read
 
     @have_snippet = !opts[:snippet].nil?
     @labels = opts[:labels] || []
     @dirty = false
+    @chunks = nil
 
-    read_header(opts[:header] || @source.load_header(@source_info))
+    raise ArgumentError, "need a header" unless opts[:header]
+    read_header opts[:header]
+    #read_header(opts[:header] || @source.load_header(@source_info))
   end
 
   def read_header header
   end
 
   ## this is called when the message body needs to actually be loaded.
-  def chunks
+  def load_from_source!
     @chunks ||=
       if @source.broken?
         [Text.new(error_message(@source.broken_msg.split("\n")))]
           ## i could just store that in the index, but i think there might
           ## be other things like that in the future, and i'd rather not
           ## bloat the index.
+          ## actually, it's also the differentiation between to/cc/bcc,
+          ## so i will keep this.
           read_header @source.load_header(@source_info)
           message_to_chunks @source.load_message(@source_info)
         rescue SourceError, SocketError, MessageFormatError => e
 
   def select t=nil
     t ||= @threads[curpos]
 
+    t = t.clone # XXXX highly experimental
+
     ## TODO: don't regen text completely
     Redwood::reporting_thread do
+      BufferManager.say("Loading message bodies...") do |sid|
+        t.each { |m, *o| m.load_from_source! }
+      end
       mode = ThreadViewMode.new t, @hidden_labels
       BufferManager.spawn t.subj, mode
       BufferManager.draw_screen
 
     @layout[latest].state = :open if @layout[latest].state == :closed
     @layout[earliest].state = :detailed if earliest.has_label?(:unread) || @thread.size == 1
 
-    BufferManager.say("Loading message bodies...") { update }
+    regen_text
   end
 
   def draw_line ln, opts={}
         @text += chunk_to_lines m, nil, @text.length, depth, parent
         next
       end
-
-      ## we're occasionally called on @threads that have had messages
-      ## added to them since initialization. luckily we regen_text on
-      ## the entire thread every time the user does anything besides
-      ## scrolling (basically), so we can just slap this on here.
-      ##
-      ## to pick nits, the niceness that i do in the constructor with
-      ## 'latest' etc. (for automatically opening just the latest
-      ## message if everything's been read) will not be valid, but
-      ## that's just a nicety and hopefully this won't happen too
-      ## often.
-
-      unless @layout.member? m
-        l = @layout[m] = Layout.new
-        l.state = initial_state_for m
-        l.color = prevm && @layout[prevm].color == :message_patina_color ? :alternate_patina_color : :message_patina_color
-      end
       l = @layout[m]
 
       ## build the patina
 
   def view_attachment a
     BufferManager.flash "viewing #{a.content_type} attachment..."
-    a.view!
+    success = a.view!
     BufferManager.erase_flash
     BufferManager.completely_redraw_screen
+    BufferManager.flash "Couldn't execute view command." unless success
   end
 
 end