class TypeElements {

    @Nonnull
    public static List<TypeName> findGenericTypes(@Nonnull TypeElement element, @Nonnull String className) {
        TypeElement currentElement = element;
        while (currentElement != null) {
            for (final TypeMirror interfaceType : currentElement.getInterfaces()) {
                final DeclaredType declaredType = (DeclaredType) interfaceType;
                final TypeElement interfaceElement = TypeElements.toElement(declaredType);
                if (interfaceElement.getSimpleName().toString().equals(className)) {
                    return declaredType.getTypeArguments()
                            .stream()
                            .map(TypeName::get)
                            .collect(toList());
                }

                final List<TypeName> found = findGenericTypes(interfaceElement, className);
                if (!found.isEmpty()) {
                    return found;
                }
            }

            final TypeMirror superClassType = currentElement.getSuperclass();
            if (superClassType.getKind() == TypeKind.DECLARED) {
                currentElement = TypeElements.toElement(superClassType);
            } else {
                currentElement = null;
            }
        }
        return Collections.emptyList();
    }

    private  TypeElements();

}