Updated with some improvements after code review.