Final version. Refactoring needed.