public function generateVieSchema()
    {
        if ($this->configuration !== null) {
            return $this->configuration;
        }

        $nodeTypes = $this->nodeTypeManager->getNodeTypes();
        foreach ($nodeTypes as $nodeTypeName => $nodeType) {
            $this->readNodeTypeConfiguration($nodeTypeName, $nodeType);
        }

        unset($this->types['typo3:unstructured']);

        foreach ($this->types as $nodeTypeName => $nodeTypeDefinition) {
            $this->types[$nodeTypeName]->subtypes = $this->getAllSubtypes($nodeTypeName);
            $this->types[$nodeTypeName]->ancestors = $this->getAllAncestors($nodeTypeName);

            $this->removeUndeclaredTypes($this->types[$nodeTypeName]->supertypes);
            $this->removeUndeclaredTypes($this->types[$nodeTypeName]->ancestors);
        }

        foreach ($this->properties as $property => $propertyConfiguration) {
            if (isset($propertyConfiguration->domains) && is_array($propertyConfiguration->domains)) {
                foreach ($propertyConfiguration->domains as $domain) {
                    if (preg_match('/TYPO3\.Neos\.NodeTypes:.*Column/', $domain)) {
                        $this->properties[$property]->ranges = array_keys($this->types);
                    }
                }
            }
        }

        // Convert the Neos.Neos:ContentCollection element to support content-collection
        // TODO Move to node type definition
        if (isset($this->types['typo3:Neos.Neos:ContentCollection'])) {
            $this->addProperty('typo3:Neos.Neos:ContentCollection', 'typo3:content-collection', []);
            $this->types['typo3:Neos.Neos:ContentCollection']->specific_properties[] = 'typo3:content-collection';
            $this->properties['typo3:content-collection']->ranges = array_keys($this->types);
        }

        $this->configuration = (object) [
            'types' => (object) $this->types,
            'properties' => (object) $this->properties,
        ];
        return $this->configuration;
    }