Merge upstream

Includes some rewrites of the upstream code. See my commits at the end of the history.