Large rewrite. See changelog for details.