finished refactoring, haven't tested