class Reflections {

    public Set<Field> getFieldsAnnotatedWith(Class<? extends Annotation> annotation) {
        ensureScan();
        synchronized (MONITOR) {
            Set<Field> result = annotationClassToField.get(annotation);
            if (result != null) {
                return result;
            }
            /* not tried before... */
            Set<Field> newResult = new LinkedHashSet<>();
            visitEveryClass(new Visitor() {

                @Override
                public void visit(Class<?> clazz) {
                    for (Field field : clazz.getDeclaredFields()) {
                        if (field.getAnnotation(annotation) != null) {
                            newResult.add(field);
                        }
                    }
                }
            });
            annotationClassToField.put(annotation, newResult);
            return newResult;
        }
    }

    public  Reflections();

}