a little messy, but interfaces work