first draft (needs to be refactored and tested)