messy, but working version