this is refactored and last version