Major refactoring (the code is currently broken)