MAJOR REFACTOR(START)