Refactor

@maronin 

Sorry for the gigantic pr.