public function getNextSets(Grammar $grammar): array
    {
        $next_map = [];
        foreach ($this->items as $item) {
            $symbol = $item->getExpected();
            if (!$symbol) {
                continue;
            }
            $name = $symbol->getName();
            $next_item = $item->shift();
            if (isset($next_map[$name])) {
                foreach ($next_map[$name] as $known_item) {
                    if (0 === Item::compare($next_item, $known_item)) {
                        goto NEXT_ITEM;
                    }
                }
                $next_map[$name][] = $next_item;
            } else {
                $next_map[$name] = [$next_item];
            }

            NEXT_ITEM:
        }

        $sets = [];
        foreach ($next_map as $name => $items) {
            $sets[$name] = static::createFromItems($items, $grammar);
        }
        return $sets;
    }