completed #1, some refactoring