Credits for changes by @nedbat.