Edited much of the code for clarity, and made some changes to the API.