need major refactoring