big refactored version