refactor complete, using smart pointers