Big refactor, this needs tidying up