protected function doGetReachableRoles(array $roles, $suffix = '')
    {
        if (0 === \count($roles)) {
            return $roles;
        }

        $item = null;
        $roles = $this->formatRoles($roles);
        $id = $this->getUniqueId($roles);

        if (null !== ($reachableRoles = $this->getCachedReachableRoles($id, $item))) {
            return $reachableRoles;
        }

        // build hierarchy
        /** @var string[] $reachableRoles */
        $reachableRoles = RoleUtil::formatNames(parent::getReachableRoles(RoleUtil::formatRoles($roles)));
        $isPermEnabled = true;

        if (null !== $this->eventDispatcher) {
            $event = new PreReachableRoleEvent($reachableRoles);
            $this->eventDispatcher->dispatch(ReachableRoleEvents::PRE, $event);
            $reachableRoles = $event->getReachableRoles();
            $isPermEnabled = $event->isPermissionEnabled();
        }

        return $this->getAllRoles($reachableRoles, $roles, $id, $item, $isPermEnabled, $suffix);
    }