public @CheckForNull R search(final int n, final Direction d) {
        switch (d) {
        case EXACT:
            return getByNumber(n);
        case ASC:
            for (int m : numberOnDisk) {
                if (m < n) {
                    // TODO could be made more efficient with numberOnDisk.find
                    continue;
                }
                R r = getByNumber(m);
                if (r != null) {
                    return r;
                }
            }
            return null;
        case DESC:
            // TODO again could be made more efficient
            ListIterator<Integer> iterator = numberOnDisk.listIterator(numberOnDisk.size());
            while (iterator.hasPrevious()) {
                int m = iterator.previous();
                if (m > n) {
                    continue;
                }
                R r = getByNumber(m);
                if (r != null) {
                    return r;
                }
            }
            return null;
        default:
            throw new AssertionError();
        }
    }
@Issue("JENKINS-22681")
    @Test public void exactSearchShouldNotReload() throws Exception {
        FakeMap m = localBuilder.add(1).add(2).make();
        assertNull(m.search(0, Direction.EXACT));
        Build a = m.search(1, Direction.EXACT);
        a.asserts(1);
        Build b = m.search(2, Direction.EXACT);
        b.asserts(2);
        assertNull(m.search(0, Direction.EXACT));
        assertSame(a, m.search(1, Direction.EXACT));
        assertSame(b, m.search(2, Direction.EXACT));
        assertNull(m.search(3, Direction.EXACT));
        assertNull(m.search(0, Direction.EXACT));
        assertSame(a, m.search(1, Direction.EXACT));
        assertSame("#2 should not have been reloaded by searching for #3", b, m.search(2, Direction.EXACT));
        assertNull(m.search(3, Direction.EXACT));
    }