Most of the credit for this large patch goes to Anssi Kääriäinen. Many thanks to all the people who contributed to the discussion.