public function createIniParts(string $content) : \Generator
    {
        // get all patterns from the ini file in the correct order,
        // so that we can calculate with index number of the resulting array,
        // which part to use when the ini file is splitted into its sections.
        preg_match_all('/(?<=\[)(?:[^\r\n]+)(?=\])/m', $content, $patternPositions);
        $patternPositions = $patternPositions[0];

        // split the ini file into sections and save the data in one line with a hash of the beloging
        // pattern (filtered in the previous step)
        $iniParts = preg_split('/\[[^\r\n]+\]/', $content);
        if (false === $iniParts) {
            throw new \UnexpectedValueException('an error occured while splitting content into parts');
        }

        $contents = [];

        $propertyFormatter = new PropertyFormatter(new PropertyHolder());

        foreach ($patternPositions as $position => $pattern) {
            $pattern = strtolower($pattern);
            $patternhash = Pattern::getHashForParts($pattern);
            $subkey = SubKey::getIniPartCacheSubKey($patternhash);

            if (! isset($contents[$subkey])) {
                $contents[$subkey] = [];
            }

            if (!array_key_exists($position + 1, $iniParts)) {
                throw new \OutOfRangeException(sprintf('could not find position %d inside iniparts', $position + 1));
            }

            $browserProperties = parse_ini_string($iniParts[($position + 1)], false, INI_SCANNER_RAW);

            if (false === $browserProperties) {
                throw new \UnexpectedValueException(sprintf('could ini parse position %d inside iniparts', $position + 1));
            }

            foreach (array_keys($browserProperties) as $property) {
                $browserProperties[$property] = $propertyFormatter->formatPropertyValue(
                    $browserProperties[$property],
                    $property
                );
            }

            try {
                // the position has to be moved by one, because the header of the ini file
                // is also returned as a part
                $contents[$subkey][] = $patternhash . "\t" . \ExceptionalJSON\encode(
                    $browserProperties,
                    JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP
                );
            } catch (EncodeErrorException $e) {
                throw new \UnexpectedValueException('json encoding content failed', 0, $e);
            }
        }

        unset($patternPositions, $iniParts);

        $subkeys = array_flip(SubKey::getAllIniPartCacheSubKeys());
        foreach ($contents as $subkey => $cacheContent) {
            yield $subkey => $cacheContent;

            unset($subkeys[$subkey]);
        }

        foreach (array_keys($subkeys) as $subkey) {
            $subkey = (string) $subkey;

            yield $subkey => '';
        }
    }