Back in early August we wrote about pulling Mail out of PIM core into its own pimi module — the same pattern every other app was moving to, loaded dynamically at runtime instead of compiled in. That post treated the extraction as done. It wasn’t.
The test we used to decide what stayed in the pimi module was “would a different mail source —
Gmail, IMAP, whatever comes later — replace this code, or reuse it?” ThunderbirdReader, the mbox
parser, failed that test: a Gmail variant would obviously replace it, not extend it, so it stayed in
the pimi jar along with the rest of Mail’s actual reading and conversation logic. Reasonable-
sounding, and wrong.
The test missed PIM’s own “no pimi can depend on another pimi” rule. PIM is meant to eventually
support more than one mail source at once — Thunderbird’s mbox format today, Gmail or IMAP later —
and any of those future variants would need the same thread-grouping, the same hand-off-only send
policy, the same catch-up walk that DefaultMailConversationService already implemented. None of
that is actually Thunderbird-specific. But it was sitting inside the one pimi module gated on
Thunderbird support being loaded at all — permanently unreachable to a hypothetical Gmail pimi the
moment one existed, since pimi modules can never see each other. “Specific to one mail format” and
“specific to this one pimi” turned out to be two different questions, and we’d been treating them
as the same one.
The actual test is activation versus support: does this code decide whether Mail is active at all
(stays pimi-gated), or does it just do useful work once Mail is active (belongs in PIM core,
available to whatever pimi eventually activates it)? Under that test, almost everything moved — the
1,600-line DefaultMailConversationService, the mbox/eml readers, the converter, the thread-key
resolver — all of it went into comm.mail, a genre-foundation module every mail pimi can depend on
directly. What’s left in the pimi jar itself is eight small classes: a component-scan trigger, a
handful of thin Default* subclasses, and the one class that’s pimi-gated for a real reason
(MailFileIndex hard-depends on a bean only Mail’s activation provides). The jar went from roughly
1.6 megabytes and 17 classes down to 9.3 kilobytes and 8.
Applying the corrected test to the other twelve pimi apps caught five more of the same mistake — RSS’s feed-fetching code, Contacts’ vCard importer, IM’s protocol connectors, all format- or protocol-specific in exactly the same “wrong test” way. Same fix, same result: smaller pimi jars, and PIM core actually ready for a second mail source, a second chat protocol, a second feed backend, whenever one shows up.