class DownloaderController extends DataBridgeController {

    protected DownloaderOutputManifestDto createDownloaderOutputManifestDto(BusinessObjectData businessObjectData, StorageUnit storageUnit, String s3KeyPrefix)
    {
        DownloaderOutputManifestDto downloaderOutputManifestDto = new DownloaderOutputManifestDto();

        // Populate basic fields.
        downloaderOutputManifestDto.setNamespace(businessObjectData.getNamespace());
        downloaderOutputManifestDto.setBusinessObjectDefinitionName(businessObjectData.getBusinessObjectDefinitionName());
        downloaderOutputManifestDto.setBusinessObjectFormatUsage(businessObjectData.getBusinessObjectFormatUsage());
        downloaderOutputManifestDto.setBusinessObjectFormatFileType(businessObjectData.getBusinessObjectFormatFileType());
        downloaderOutputManifestDto.setBusinessObjectFormatVersion(String.valueOf(businessObjectData.getBusinessObjectFormatVersion()));
        downloaderOutputManifestDto.setPartitionKey(businessObjectData.getPartitionKey());
        downloaderOutputManifestDto.setPartitionValue(businessObjectData.getPartitionValue());
        downloaderOutputManifestDto.setSubPartitionValues(businessObjectData.getSubPartitionValues());
        downloaderOutputManifestDto.setBusinessObjectDataVersion(String.valueOf(businessObjectData.getVersion()));
        downloaderOutputManifestDto.setStorageName(storageUnit.getStorage().getName());

        // Build a list of manifest files with paths relative to the S3 key prefix.
        List<ManifestFile> manifestFiles = new ArrayList<>();
        downloaderOutputManifestDto.setManifestFiles(manifestFiles);
        if (!CollectionUtils.isEmpty(storageUnit.getStorageFiles()))
        {
            for (StorageFile storageFile : storageUnit.getStorageFiles())
            {
                ManifestFile manifestFile = new ManifestFile();
                manifestFiles.add(manifestFile);
                manifestFile.setFileName(storageFile.getFilePath().replace(s3KeyPrefix, ""));
                manifestFile.setFileSizeBytes(storageFile.getFileSizeBytes());
                manifestFile.setRowCount(storageFile.getRowCount());
            }
        }

        // Populate the attributes.
        HashMap<String, String> attributes = new HashMap<>();
        if (!CollectionUtils.isEmpty(businessObjectData.getAttributes()))
        {
            for (Attribute attribute : businessObjectData.getAttributes())
            {
                attributes.put(attribute.getName(), attribute.getValue());
            }
        }
        downloaderOutputManifestDto.setAttributes(attributes);

        // Populate the business object data parents and children.
        downloaderOutputManifestDto.setBusinessObjectDataParents(businessObjectData.getBusinessObjectDataParents());
        downloaderOutputManifestDto.setBusinessObjectDataChildren(businessObjectData.getBusinessObjectDataChildren());

        return downloaderOutputManifestDto;
    }

}