revised to use smart pointers