use smart pointers and fail-early to avoid nesting