public static <T> List<T> visitPeriods(long startEpochMillis , long endEpochMillis , long duration , TimeUnit units , Optional<Predicate<ProfilePeriod>> inclusionPredicate , Function<ProfilePeriod,T> transformation ) { ProfilePeriod period = ProfilePeriod.fromTimestamp(startEpochMillis, duration, units); List<T> ret = new ArrayList<>(); while(period.getStartTimeMillis() <= endEpochMillis) { if(!inclusionPredicate.isPresent() || inclusionPredicate.get().test(period)) { ret.add(transformation.apply(period)); } period = period.next(); } return ret; } }