- raise SourceError, broken_msg if broken?
- imap_id = @imap_ids[id] or die_from "Unknown message id #{id}.", :suggest_rebuild => true
-
- retried = false
- results = safely { @imap.fetch imap_id, (fields + ['RFC822.SIZE', 'INTERNALDATE']).uniq }.first
- got_id = make_id results
- die_from "IMAP message mismatch: requested #{id}, got #{got_id}.", :suggest_rebuild => true unless got_id == id
-
- fields.map { |f| results.attr[f] }
+ raise OutOfSyncSourceError, "Unknown message id #{id}" unless @imap_state[id]
+
+ imap_id = @imap_state[id][:id]
+ result = fetch(imap_id, (fields + ['RFC822.SIZE', 'INTERNALDATE']).uniq).first
+ got_id = make_id result
+
+ ## I've turned off the following sanity check because Microsoft
+ ## Exchange fails it. Exchange actually reports two different
+ ## INTERNALDATEs for the exact same message when queried at different
+ ## points in time.
+ ##
+ ## RFC2060 defines the semantics of INTERNALDATE for messages that
+ ## arrive via SMTP for via various IMAP commands, but states that
+ ## "All other cases are implementation defined.". Great, thanks guys,
+ ## yet another useless field.
+ ##
+ ## Of course no OTHER imap server I've encountered returns DIFFERENT
+ ## values for the SAME message. But it's Microsoft; what do you
+ ## expect? If their programmers were any good they'd be working at
+ ## Google.
+
+ # raise OutOfSyncSourceError, "IMAP message mismatch: requested #{id}, got #{got_id}." unless got_id == id
+
+ fields.map { |f| result.attr[f] or raise FatalSourceError, "empty response from IMAP server: #{f}" }