public function insertAt($index, $items)
    {
        $items = \is_array($items) || $items instanceof self ? $items : [$items];
        $itemsCnt = \count($items);

        if (0 === $itemsCnt) {
            return;
        }

        $oldSize = \count($this);
        $this->changed = true;
        $this->blockEndCache = [];
        $this->setSize($oldSize + $itemsCnt);

        // since we only move already existing items around, we directly call into SplFixedArray::offset* methods.
        // that way we get around additional overhead this class adds with overridden offset* methods.
        for ($i = $oldSize + $itemsCnt - 1; $i >= $index; --$i) {
            $oldItem = parent::offsetExists($i - $itemsCnt) ? parent::offsetGet($i - $itemsCnt) : new Token('');
            parent::offsetSet($i, $oldItem);
        }

        for ($i = 0; $i < $itemsCnt; ++$i) {
            if ('' === $items[$i]->getContent()) {
                throw new \InvalidArgumentException('Must not add empty token to collection.');
            }

            $this->registerFoundToken($items[$i]);
            parent::offsetSet($i + $index, $items[$i]);
        }
    }