move caching a bit higher
aggregate uses visitor