Major refactoring. Probably final version