public static <T> NavigableSet<Point<T>> slowKNearestPoints(Collection<? extends Point<T>> points, Instant time, int k) {
        checkNotNull(points, "The input collection of Points cannot be null");
        checkNotNull(time, "The input time cannot be null");
        checkArgument(k >= 0, "k (" + k + ") must be non-negative");

        if (k >= points.size()) {
            return newTreeSet(points);
        }
        if (k == 0) {
            return newTreeSet();
        }

        TreeSet<Point<T>> bestSoFar = new TreeSet<>();
        Iterator<? extends Point<T>> iter = points.iterator();

        //seed with k pieces of data
        while (bestSoFar.size() < k) {
            bestSoFar.add(iter.next());
        }

        //the "next point" must be closer than this to go into the working solution
        Duration upperDelta = durationBtw(time, bestSoFar.first().time());
        Duration lowerDelta = durationBtw(time, bestSoFar.last().time());
        Duration addThreshold = max(upperDelta, lowerDelta);

        while (iter.hasNext()) {
            Point<T> next = iter.next();

            Duration delta = durationBtw(time, next.time());

            if (theDuration(delta).isLessThan(addThreshold)) {
                /* This element improves the working result. So Add it */
                bestSoFar.add(next);
                /* Recompute the upper and lower thresholds so we know which Point gets removed. */
                upperDelta = durationBtw(time, bestSoFar.first().time());
                lowerDelta = durationBtw(time, bestSoFar.last().time());

                //remove the k+1 element
                if (theDuration(upperDelta).isGreaterThanOrEqualTo(lowerDelta)) {
                    bestSoFar.pollFirst();
                    upperDelta = durationBtw(time, bestSoFar.first().time());
                } else {
                    bestSoFar.pollLast();
                    lowerDelta = durationBtw(time, bestSoFar.last().time());
                }
                addThreshold = max(upperDelta, lowerDelta);
            }
        }

        return newTreeSet(bestSoFar);
    }
@Test
    public void testKNearestPointsWithGenericInputs() {
        /*
         * This test confirms that the signature of kNearestPoints will accept any Collection<T>
         * where T is some arbitrary class that implements Point
         */
        List<Point<NopHit>> listOfPoints = newArrayList();

        NavigableSet<Point<NopHit>> neighbors = slowKNearestPoints(listOfPoints, Instant.EPOCH, 2);

        assertTrue(
            neighbors.isEmpty(),
            "There should be no neighbors because the input list was empty"
        );
    }