protected function inferField($fieldName, $fieldTypesPopularity)
    {
        // the $fieldTypesPopularity array is already sorted with most popular fields first
        $inferredField = null;
        foreach (array_keys($fieldTypesPopularity) as $inferredFieldType) {
            /** @var BaseField $inferredField */
            $inferredField = $this->fieldsPopularityObjects[$fieldName][$inferredFieldType];
            try {
                $rowNum = 0;
                foreach ($this->inputRows as $inputRow) {
                    if (!array_key_exists($rowNum, $this->castRows)) {
                        $this->castRows[$rowNum] = [];
                    }
                    $this->castRows[$rowNum][$fieldName] = $inferredField->castValue($inputRow[$fieldName]);
                    ++$rowNum;
                }
                break;
            } catch (FieldValidationException $e) {
                // a row failed validation for this field type, will continue to the next one according to popularity
                continue;
            }
        }

        return $inferredField;
    }