work for  all cases, need refactoring