public static function fixText(string $text, int $delta = 0, bool $relocateOrphans = false) : TextWithHeader
    {
        $headers = self::find($text);
        $headers->fix($delta, $relocateOrphans);

        foreach ($headers->getRecursiveReverseIterator() as $header) {
            $realLevel = $header->getRealLevel();
            $id = $header->getId();

            // Use a substring to ensure that if the string length change, we do
            // not squash existing text around or leave cruft in text.
            $substring = \strtr(
                \substr($text, $header->offset, $header->length),
                [
                    '<h'.$header->userLevel.'>' => '<h'.$realLevel.' id="'.$id.'">',
                    '</h'.$header->userLevel.'>' => '</h'.$realLevel.'>'
                ]
            );

            $text = substr_replace($text, $substring, $header->offset, $header->length);
        }

        return new TextWithHeader($headers, $text);
    }