private async Task <(string, int[])[]> GetBusinessAccounts(CancellationToken ct)
        {
            var wrapper = await JsonFileCacheManager.Instance
                          .ReadFromCacheOrSaveAsync <BusinessAccountWrapper[]>(
                ContactsForCasesGenerationCacheName,
                async() =>
            {
                var accounts = await CrossEntityGenerationHelper.GetBusinessAccountsWithContacts(ApiConnectionConfig, ct);

                return(accounts
                       .GroupBy(a => a.Type)
                       .First(g => g.Key == "Customer")
                       .Where(a => !a.Contacts.IsNullOrEmpty())
                       .ToArray());
            });

            // also create cache for Case as IComplexQueryCachedEntity
            JsonFileCacheManager.Instance.SaveCache(
                nameof(Case) + '.' + nameof(IComplexQueryCachedEntity),
                wrapper
                .SelectMany(a => a.Contacts)
                .Select(c => new { ContactID = c.ContactId, Email = c.Email }));

            // no nulls in THIS cache
            return(wrapper.Select(w => (w.AccountId, w.Contacts.Select(c => (int)c.ContactId).ToArray())).ToArray());
        }
        private async Task <IDictionary <OpportunityAccountType, BusinessAccountWrapper[]> > GetBusinessAccounts(CancellationToken ct)
        {
            return(await JsonFileCacheManager.Instance
                   .ReadFromCacheOrSaveAsync <IDictionary <OpportunityAccountType, BusinessAccountWrapper[]> >(
                       BusinessAccountCacheName,
                       async() =>
            {
                var accounts = await CrossEntityGenerationHelper
                               .GetBusinessAccountsWithContacts(ApiConnectionConfig, ct);
                return accounts
                .GroupBy(a => a.Type)
                .Select(g =>
                {
                    BusinessAccountWrapper[] accs;
                    OpportunityAccountType type;
                    switch (g.Key)
                    {
                    case "Customer":
                        {
                            type = OpportunityAccountType.WithCustomerAccount;
                            accs = g.Where(a => !a.Contacts.IsNullOrEmpty())
                                   .ToArray();
                            break;
                        }

                    case "Prospect":
                        {
                            type = OpportunityAccountType.WithProspectAccount;
                            accs = g.ToArray();

                            break;
                        }

                    default:
                        {
                            type = OpportunityAccountType.WithoutAccount;
                            accs = null;

                            break;
                        }
                    }

                    return (type, accs);
                })
                .Where(t => t.type != OpportunityAccountType.WithoutAccount)
                .ToDictionary(
                    t => t.type,
                    t => t.accs
                    );
            }));