public function getInheritedElement()
    {
        if ($this->inheritedElement !== null) {
            return $this->inheritedElement;
        }

        /** @var ClassDescriptor|InterfaceDescriptor|null $associatedClass */
        $associatedClass = $this->getParent();
        if (!$associatedClass instanceof ClassDescriptor && !$associatedClass instanceof InterfaceDescriptor) {
            return null;
        }

        /** @var ClassDescriptor|InterfaceDescriptor $parentClass|null */
        $parentClass = $associatedClass->getParent();
        if ($parentClass instanceof ClassDescriptor || $parentClass instanceof Collection) {
            // the parent of a class is always a class, but the parent of an interface is a collection of interfaces.
            $parents = $parentClass instanceof ClassDescriptor ? array($parentClass) : $parentClass->getAll();
            foreach ($parents as $parent) {
                if ($parent instanceof ClassDescriptor || $parent instanceof InterfaceDescriptor) {
                    $parentMethod = $parent->getMethods()->get($this->getName());
                    if ($parentMethod) {
                        $this->inheritedElement = $parentMethod;

                        return $this->inheritedElement;
                    }
                }
            }
        }

        // also check all implemented interfaces next if the parent is a class and not an interface
        if ($associatedClass instanceof ClassDescriptor) {
            /** @var InterfaceDescriptor $interface */
            foreach ($associatedClass->getInterfaces() as $interface) {
                if (!$interface instanceof InterfaceDescriptor) {
                    continue;
                }

                $parentMethod = $interface->getMethods()->get($this->getName());
                if ($parentMethod) {
                    $this->inheritedElement = $parentMethod;

                    return $this->inheritedElement;
                }
            }
        }

        return null;
    }