public function buildDomainFields(
        array $spiFields,
        $contentType,
        array $prioritizedLanguages = [],
        string $alwaysAvailableLanguage = null
    ) {
        if (!$contentType instanceof SPIType && !$contentType instanceof ContentType) {
            throw new InvalidArgumentType('$contentType', 'SPI ContentType | API ContentType');
        }

        $fieldDefinitionsMap = [];
        foreach ($contentType->fieldDefinitions as $fieldDefinition) {
            $fieldDefinitionsMap[$fieldDefinition->id] = $fieldDefinition;
        }

        $fieldInFilterLanguagesMap = array();
        if (!empty($prioritizedLanguages) && $alwaysAvailableLanguage !== null) {
            foreach ($spiFields as $spiField) {
                if (in_array($spiField->languageCode, $prioritizedLanguages)) {
                    $fieldInFilterLanguagesMap[$spiField->fieldDefinitionId] = true;
                }
            }
        }

        $fields = array();
        foreach ($spiFields as $spiField) {
            // We ignore fields in content not part of the content type
            if (!isset($fieldDefinitionsMap[$spiField->fieldDefinitionId])) {
                continue;
            }

            $fieldDefinition = $fieldDefinitionsMap[$spiField->fieldDefinitionId];

            if (!empty($prioritizedLanguages) && !in_array($spiField->languageCode, $prioritizedLanguages)) {
                // If filtering is enabled we ignore fields in other languages then $prioritizedLanguages, if:
                if ($alwaysAvailableLanguage === null) {
                    // Ignore field if we don't have $alwaysAvailableLanguageCode fallback
                    continue;
                } elseif (!empty($fieldInFilterLanguagesMap[$spiField->fieldDefinitionId])) {
                    // Ignore field if it exists in one of the filtered languages
                    continue;
                } elseif ($spiField->languageCode !== $alwaysAvailableLanguage) {
                    // Also ignore if field is not in $alwaysAvailableLanguageCode
                    continue;
                }
            }

            $fields[$fieldDefinition->position][] = new Field(
                array(
                    'id' => $spiField->id,
                    'value' => $this->fieldTypeRegistry->getFieldType($spiField->type)
                        ->fromPersistenceValue($spiField->value),
                    'languageCode' => $spiField->languageCode,
                    'fieldDefIdentifier' => $fieldDefinition->identifier,
                    'fieldTypeIdentifier' => $spiField->type,
                )
            );
        }

        // Sort fields by content type field definition priority
        ksort($fields, SORT_NUMERIC);

        // Flatten array
        return array_merge(...$fields);
    }