private function collectDataFromMultipleFiles($fileNames, WorkflowMessage $workflowMessage, FileTypeAdapter $fileHandler)
 {
     $metadata = $workflowMessage->metadata();
     $fileDataType = isset($metadata[self::META_FILE_DATA_TYPE]) ? $metadata[self::META_FILE_DATA_TYPE] : $workflowMessage->payload()->getTypeClass();
     Assertion::implementsInterface($fileDataType, 'Prooph\\Processing\\Type\\Type');
     $fileDataPrototype = $fileDataType::prototype();
     $fileDataCollection = [];
     $collectedData = null;
     $typeClass = $workflowMessage->payload()->getTypeClass();
     foreach ($fileNames as $filename) {
         $fileDataCollection[] = $fileHandler->readDataForType($filename, $fileDataPrototype, $metadata);
     }
     if (isset($metadata[self::META_MERGE_FILES]) && $metadata[self::META_MERGE_FILES]) {
         $mergedFileData = [];
         foreach ($fileDataCollection as $fileData) {
             if (!is_array($fileData)) {
                 $fileData = [$fileData];
             }
             $mergedFileData = ArrayUtils::merge($mergedFileData, $fileData);
         }
         $collectedData = $typeClass::fromNativeValue($mergedFileData);
     } else {
         if ($typeClass::prototype()->typeDescription()->nativeType() !== NativeType::COLLECTION) {
             throw new \InvalidArgumentException(sprintf("Filename pattern %s matches multiple files but the requested processing type %s is not a collection.", $metadata['filename_pattern'], $typeClass));
         }
         $metadata[self::META_TOTAL_ITEMS] = count($fileDataCollection);
         $collectedData = $typeClass::fromNativeValue($fileDataCollection);
     }
     return $workflowMessage->answerWith($collectedData, $metadata);
 }
 private function collectResultSet(WorkflowMessage $workflowMessage)
 {
     /** @var $collectionType AbstractCollection */
     $collectionType = $workflowMessage->payload()->getTypeClass();
     $itemType = $collectionType::prototype()->typeProperties()['item']->typePrototype()->of();
     if (!method_exists($itemType, 'fromDatabaseRow')) {
         throw new \InvalidArgumentException(sprintf("Item type %s does not provide a static fromDatabaseRow factory method", $itemType));
     }
     if (!method_exists($itemType, 'toDbColumnName')) {
         throw new \InvalidArgumentException(sprintf("Item type %s does not provide a static toDbColumnName method", $itemType));
     }
     $count = $this->countRows($itemType, $workflowMessage->metadata());
     $query = $this->buildQueryFromMetadata($itemType, $workflowMessage->metadata());
     if ($this->triggerActions) {
         $action = $this->actions->getNewActionEvent('collect_result_set', $this, ['workflow_message' => $workflowMessage, 'item_type' => $itemType, 'collection_type' => $collectionType, 'query' => $query]);
         $this->actions->dispatch($action);
         //Maybe item/collection type or query were changed by a listener?
         $itemType = $action->getParam('item_type');
         $collectionType = $action->getParam('collection_type');
         $query = $action->getParam('query', $query);
     }
     $stmt = $query->execute();
     //Premap row, so that factory fromDatabaseRow is used to construct the TableRow type
     $mapIterator = new MapIterator($stmt, function ($item) use($itemType) {
         return $itemType::fromDatabaseRow($item);
     });
     $collection = $collectionType::fromNativeValue($mapIterator);
     return $workflowMessage->answerWith($collection, [MessageMetadata::TOTAL_ITEMS => $count]);
 }