refactor into slower but cleaner implementation