Final version; major refactoring