@Override
    public Optional<Track<T>> clean(Track<T> track) {

        TreeSet<Point<T>> points = new TreeSet<>(track.points());

        Iterator<Point<T>> iter = points.iterator();

        Long tau = null;
        while (iter.hasNext()) {
            Point point = iter.next();

            //the 1st time through this loop set tau and ensure the 1st point isn't removed
            if (tau == null) {
                tau = point.time().toEpochMilli();
                continue;
            }

            long t = point.time().toEpochMilli();
            if ((t - tau) < minAllowableTimeDelta) {
                iter.remove();
            } else {
                tau = t;
            }
        }

        return Optional.of(Track.of(points));
    }
@Test
    public void testDownSampling() {

        Duration maxTimeDelta = Duration.ofSeconds(5);
        TimeDownSampler<String> smoother = new TimeDownSampler<>(maxTimeDelta);

        Track<String> cleanedTrack = smoother.clean(testTrack()).get();

        Point last = null;
        for (Point point : cleanedTrack.points()) {
            if (last != null) {
                Duration timeDelta = durationBtw(last.time(), point.time());
                assertTrue(timeDelta.toMillis() <= maxTimeDelta.toMillis());
            }
        }

        assertEquals(2, cleanedTrack.size());
        assertEquals(EPOCH, cleanedTrack.points().first().time());
        assertEquals(EPOCH.plusSeconds(5), cleanedTrack.points().last().time());
    }