Lots of refactoring (reverted from commit e9364332f08d04e8fe9f7dad4cbdd9b21bb35ff9)
Please don't break.
Please don't break 2.