def get_annotations(
            cls, target,
            exclude=None, ctx=None, select=lambda *p: True,
            mindepth=0, maxdepth=0, followannotated=True, public=True,
            _history=None
    ):
        result = []
        if mindepth <= 0:
            try:
                annotations_by_ctx = get_property(
                    elt=target, key=Annotation.__ANNOTATIONS_KEY__, ctx=ctx
                )
            except TypeError:
                annotations_by_ctx = {}
            if not annotations_by_ctx:
                if ismethod(target):
                    func = get_method_function(target)
                    annotations_by_ctx = get_property(
                        elt=func,
                        key=Annotation.__ANNOTATIONS_KEY__,
                        ctx=ctx
                    )
                    if not annotations_by_ctx:
                        annotations_by_ctx = get_property(
                            elt=func, key=Annotation.__ANNOTATIONS_KEY__
                        )
                elif isfunction(target):
                    annotations_by_ctx = get_property(
                        elt=target,
                        key=Annotation.__ANNOTATIONS_KEY__
                    )
            exclude = () if exclude is None else exclude
            for elt, annotations in annotations_by_ctx:
                for annotation in annotations:
                    if isinstance(annotation, StopPropagation):
                        exclude += annotation.annotation_types
                    if elt is not target and not annotation.propagate:
                        continue
                    if annotation.override:
                        exclude += (annotation.__class__, )
                    if (isinstance(annotation, cls)
                            and not isinstance(annotation, exclude)
                            and select(target, ctx, annotation)):
                        result.append(annotation)
        if mindepth >= 0 or (maxdepth > 0 and (result or not followannotated)):
            if _history is None:
                _history = [target]
            else:
                _history.append(target)
            for name, member in getmembers(target):
                if (name[0] != '_' or not public) and member not in _history:
                    if ismethod(target) and name.startswith('im_'):
                        continue
                    result += cls.get_annotations(
                        target=member, exclude=exclude, ctx=ctx, select=select,
                        mindepth=mindepth - 1, maxdepth=maxdepth - 1,
                        followannotated=followannotated, _history=_history
                    )
        return result