completed; need a refactoring