This library handles all of that in ~500 lines of code.