passes all unit tests. needs speed up.