Done, might need heavy refactoring