mostly working, need to refactor