split implementation for better clarity