protected function _generateFiles() {
        foreach ($this->getRegisteredArtifacts() as $artifact) {
            $featureName = $artifact->getFeature()->getName();
            if (array_search($featureName, $this->featureOrder) === false)
                throw new CollaborationGeneratorException("no feature order supplied for \"$featureName\"");
        }
        
        parent::_generateFiles();

        $rolePartition = fphp\Helper\Partition::fromObjects($this->collaborations, "getRoles")->partitionBy("correspondsTo");
        foreach ($rolePartition as $roleEquivalenceClass) {
            // sort the roles by their feature order (because role composition is not commutative)
            $roleEquivalenceClass = fphp\Helper\_Array::schwartzianTransform($roleEquivalenceClass, function($role) {
                return array_search($role->getCollaboration()->getArtifact()->getFeature()->getName(), $this->featureOrder);
            });
            
            // take any representative from the equivalence class to extract the file target
            $fileTarget = $roleEquivalenceClass[0]->getFileSpecification()->getTarget();
            $this->files[] = new fphp\File\RefinedFile($fileTarget, $roleEquivalenceClass);
            $this->logFile->log(null, "added file \"$fileTarget\"");
        }
    }