Re-wrote most of the code