Needs refactoring but all unit tests are finally passing.