refactored, see 1a5aded for more details