Generalize joinDups optimization

Lots of other optimizations follow that pattern, and it will help cleanly implement #111  and fix #115.