Beware of bugs in the above code; I have only proved it correct, not tried it.
Computers are good at following instructions, but not at reading your mind.