code: private static <T extends Annotation> Optional<T> findFirstEncounteredAnnotationsOnAllHierarchy( RebindConfiguration configuration,
                                                                                                      JClassType type, Class<T> annotation,
                                                                                                      Optional<JClassType> ignoreType ) {
          JClassType currentType = type;
          while ( null != currentType ) {
              Optional<JClassType> mixin = configuration.getMixInAnnotations( currentType );
              if ( mixin.isPresent() && mixin.get().isAnnotationPresent( annotation ) ) {
                  return Optional.of( mixin.get().getAnnotation( annotation ) );
              }
              if ( currentType.isAnnotationPresent( annotation ) ) {
                  return Optional.of( currentType.getAnnotation( annotation ) );
              }
              for ( JClassType interf : currentType.getImplementedInterfaces() ) {
                  if (!ignoreType.isPresent() || !ignoreType.get().equals( interf )) {
                      Optional<T> annot = findFirstEncounteredAnnotationsOnAllHierarchy( configuration, interf, annotation );
                      if ( annot.isPresent() ) {
                          return annot;
                      }
                  }
              }
              currentType = currentType.getSuperclass();
              if ( ignoreType.isPresent() && ignoreType.get().equals( currentType ) ) {
                  currentType = null;
              }
          }
          return Optional.absent();
      }
docs: Browse all the hierarchy of the type and return the first corresponding annotation it found
  
  @param type type
  @param annotation annotation to find
  @param <T> type of the annotation
  @param ignoreType type to ignore when browsing the hierarchy
  
  @return the annotation if found, null otherwise