public async Task <RedactedCriminalFileDetailResponse> FileIdAsync(string fileId) { async Task <CriminalFileDetailResponse> FileDetails() => await _filesClient.FilesCriminalGetAsync(_requestAgencyIdentifierId, _requestPartId, _applicationCode, fileId); async Task <CriminalFileContent> FileContent() => await _filesClient.FilesCriminalFilecontentAsync(_requestAgencyIdentifierId, _requestPartId, _applicationCode, null, null, null, null, fileId); async Task <CriminalFileAppearances> FileAppearances() => await PopulateDetailsAppearancesAsync(fileId, FutureYN.Y, HistoryYN.Y); var fileDetailTask = _cache.GetOrAddAsync($"CriminalFileDetail-{fileId}-{_requestAgencyIdentifierId}", FileDetails); var fileContentTask = _cache.GetOrAddAsync($"CriminalFileContent-{fileId}-{_requestAgencyIdentifierId}", FileContent); var appearancesTask = _cache.GetOrAddAsync($"CriminalAppearancesFull-{fileId}-{_requestAgencyIdentifierId}", FileAppearances); var fileDetail = await fileDetailTask; var fileContent = await fileContentTask; var appearances = await appearancesTask; //CriminalFileContent can return null when an invalid fileId is inserted. if (fileDetail == null || fileContent == null) { return(null); } var detail = _mapper.Map <RedactedCriminalFileDetailResponse>(fileDetail); var documents = PopulateDetailDocuments(fileContent); detail = await PopulateBaseDetail(detail); detail.Appearances = appearances; detail.Witness = await PopulateDetailWitnesses(detail); detail.Participant = await PopulateDetailParticipants(detail, documents, fileContent.AccusedFile); detail.HearingRestriction = await PopulateDetailHearingRestrictions(detail); detail.Crown = PopulateDetailCrown(detail); return(detail); }