private function generateHeaderName(array &$data, NodePath $nodePath, string $parentName, string $baseType)
    {
        if (empty($data['headerNames'])) {
            // write only once, because generateHeaderName may be called repeatedly
            if ($parentName != self::ARRAY_NAME) {
                // do not generate headers for arrays
                $headerName = $this->getSafeName($parentName);
                $headerName = $this->getUniqueName($baseType, $headerName);
                $data['headerNames'] = $headerName;
            } else {
                $data['headerNames'] = self::DATA_COLUMN;
            }
        }
        if ($data['nodeType'] == 'array') {
            // array node creates a new type and does not nest deeper
            $baseType = $baseType . '.' . $parentName;
            $parentName = '';
        }
        foreach ($data as $key => &$value) {
            if (is_array($value)) {
                $key = $this->decodeNodeName($key);
                if (!$parentName || (!empty($data[$key]['type']) && $data[$key]['type'] == 'parent')) {
                    // skip nesting if there is nowhere to nest (array or parent-type child)
                    $childName = $key;
                } else {
                    $childName = $parentName . '.' . $key;
                }
                $this->generateHeaderName($value, $nodePath->addChild($key), $childName, $baseType);
            }
        }
    }