Fix Trac #3640, plus associated refactoring