slightly enhanced and refactored