code: public <A extends Annotation> A getAnnotation(Class<A> annotationClass, AnnotatedElement element) {
          A annotation;
          Map<AnnotatedElement, Annotation> cacheMap = cache.get(annotationClass);
          if (cacheMap == null) {
              cacheMap = new HashMap<AnnotatedElement, Annotation>();
              cache.put(annotationClass, cacheMap);
          }
          if (cacheMap.containsKey(element)) {
              annotation = (A) cacheMap.get(element);
          } else {
              annotation = element.getAnnotation(annotationClass);
              if (annotation == null && element instanceof Method) {
                  annotation = getOverriddenAnnotation(annotationClass, (Method) element);
              }
              cacheMap.put(element, annotation);
          }
  
          return annotation;
      }
docs: Finds the supplied annotation if present on the element, or on its parents.
  The parents in this sense are the super types and interfaces if the element is a class.
  Or, in case of a Method, the (overridden) method declaration by its super types or interfaces.
  @param annotationClass class of annotation looked for.
  @param element element (class or method) to look for the annotation on.
  @param <A> type of annotation.
  @return annotation if present, <code>null</code> otherwise.