Finished code. Needs testing.