Updated with improvements (thanks Zach!)