Coding standards
----------------
-- Wrap code at 99999 characters. The days of 80-column displays are
- long over. Wrap comments and other text at whatever Emacs meta-Q
- does.
+- Don't wrap code unless it really benefits from it. The days of
+ 80-column displays are long over. But do wrap comments and other
+ text at whatever Emacs meta-Q does.
- Use as few parentheses as possible.
- Use {} for one-liner blocks and do/end for multi-line blocks.
-- For one-line functions, put a semicolon before "end", like this:
- def bool_writer *args; attr_writer(*args); end
- (I just started doing this for no real reason, and now I kinda like
- it.)
+
+How messages are updated in the index
+-------------------------------------
+
+Ferret doesn't have any concept of updating; to change message state
+it must be deleted then re-added to the index.
+
+Thus there are a couple situations where we'll have a message to be
+"added", but it already exists in the index, and we need to decide
+which parts of which version to keep:
+
+1. The user has changed the state of the message, e.g. read it or
+ added a user label. In this case we want to use the state of the
+ version in memory, but keep everything else on disk.
+
+ This is the behavior of Index#update_message
+
+2. We've received a new copy of the message. Crucially, this can
+ happen for two different reasons:
+
+ a. The message was sent to a mailing list to which the user is
+ subscribed, and we're now getting that message back, possibly
+ with altered content (subject mangling, signature adding, etc.)
+
+ b. The user has moved the message between sources. E.g. if the
+ primary inbox has a quota, and other sources are on local,
+ quota-less disk, the user may regularly move messages from the
+ inbox to the sources on disk.
+
+ In both of these cases, the solution is to keep the state from the
+ index, but use the new message contents.
+
+ This is the behavior of Index#update_or_add_message, which can be
+ also be called for new message.
+