Full rewrite

See commit messages for details.