more robust but messy