def subclasses(base_cls):
    """
    Discovers the inheritance tree of a given class. The class must have an abstract() method. A class of the
    hierarchy will only be the part of the returned classes, if it's abstract() method returns False.
    :param base_cls: type, root of the inheritance hierarchy.
    :return: dict, classes that are part of the hierarchy, with their str names as keys, and type references as values.
    """
    def get_hierarchy(cls):
        sub_classes = {sub_cls.__name__: sub_cls for sub_cls in cls.__subclasses__()}
        hierarchy = {}
        for sub_cls_name in sub_classes:
            hierarchy = {**hierarchy, **get_hierarchy(sub_classes[sub_cls_name])}

        return {**hierarchy, **{name: sub_classes[name] for name in sub_classes if not sub_classes[name].abstract}}

    return get_hierarchy(base_cls)