Final working version, need refactoring