Pretty much final code, could use testing for exceptions and special cases