implemented with blocks for elegant async and predicates