internal static void ExtractPostingLines(this AccountingModel accountingModel, IReadOnlyCollection <PostingLineModel> postingLineModelCollection)
        {
            NullGuard.NotNull(accountingModel, nameof(accountingModel))
            .NotNull(postingLineModelCollection, nameof(postingLineModelCollection));

            accountingModel.PostingLines = postingLineModelCollection.Where(postingLineModel => postingLineModel.AccountingIdentifier == accountingModel.AccountingIdentifier).ToList();
        }
        internal static void ExtractContactAccounts(this AccountingModel accountingModel, IReadOnlyCollection <ContactAccountModel> contactAccountModelCollection)
        {
            NullGuard.NotNull(accountingModel, nameof(accountingModel))
            .NotNull(contactAccountModelCollection, nameof(contactAccountModelCollection));

            accountingModel.ContactAccounts = contactAccountModelCollection.Where(contactAccountModel => contactAccountModel.AccountingIdentifier == accountingModel.AccountingIdentifier).ToList();
        }
        internal static void ExtractBudgetAccounts(this AccountingModel accountingModel, IReadOnlyCollection <BudgetAccountModel> budgetAccountModelCollection)
        {
            NullGuard.NotNull(accountingModel, nameof(accountingModel))
            .NotNull(budgetAccountModelCollection, nameof(budgetAccountModelCollection));

            accountingModel.BudgetAccounts = budgetAccountModelCollection.Where(budgetAccountModel => budgetAccountModel.AccountingIdentifier == accountingModel.AccountingIdentifier).ToList();
        }
        internal static IAccounting ToDomain(this AccountingModel accountingModel, MapperCache mapperCache, IConverter accountingModelConverter, IConverter commonModelConverter)
        {
            NullGuard.NotNull(accountingModel, nameof(accountingModel))
            .NotNull(mapperCache, nameof(mapperCache))
            .NotNull(accountingModelConverter, nameof(accountingModelConverter))
            .NotNull(commonModelConverter, nameof(commonModelConverter));

            lock (mapperCache.SyncRoot)
            {
                if (mapperCache.AccountingDictionary.TryGetValue(accountingModel.AccountingIdentifier, out IAccounting accounting))
                {
                    return(accounting);
                }

                ILetterHead letterHead = commonModelConverter.Convert <LetterHeadModel, ILetterHead>(accountingModel.LetterHead);

                accounting = new Domain.Accounting.Accounting(accountingModel.AccountingIdentifier, accountingModel.Name, letterHead, accountingModel.BalanceBelowZero, accountingModel.BackDating);
                accounting.AddAuditInformation(accountingModel.CreatedUtcDateTime, accountingModel.CreatedByIdentifier, accountingModel.ModifiedUtcDateTime, accountingModel.ModifiedByIdentifier);
                accounting.SetDeletable(accountingModel.Deletable);

                mapperCache.AccountingDictionary.Add(accounting.Number, accounting);

                if (accountingModel.Accounts != null)
                {
                    accounting.AccountCollection.Add(accountingModel.Accounts
                                                     .Where(accountModel => accountModel.Convertible())
                                                     .Select(accountModel => accountModel.ToDomain(accounting, mapperCache, accountingModelConverter))
                                                     .Where(account => accounting.AccountCollection.Contains(account) == false)
                                                     .ToArray());
                }

                if (accountingModel.BudgetAccounts != null)
                {
                    accounting.BudgetAccountCollection.Add(accountingModel.BudgetAccounts
                                                           .Where(budgetAccountModel => budgetAccountModel.Convertible())
                                                           .Select(budgetAccountModel => budgetAccountModel.ToDomain(accounting, mapperCache, accountingModelConverter))
                                                           .Where(budgetAccount => accounting.BudgetAccountCollection.Contains(budgetAccount) == false)
                                                           .ToArray());
                }

                if (accountingModel.ContactAccounts != null)
                {
                    accounting.ContactAccountCollection.Add(accountingModel.ContactAccounts
                                                            .Where(contactAccountModel => contactAccountModel.Convertible())
                                                            .Select(contactAccountModel => contactAccountModel.ToDomain(accounting, mapperCache, accountingModelConverter))
                                                            .Where(contactAccount => accounting.ContactAccountCollection.Contains(contactAccount) == false)
                                                            .ToArray());
                }

                return(accounting);
            }
        }
        private static Task <AccountingModel> OnReadAsync(PostingLineModel postingLineModel, AccountingModel accountModel)
        {
            NullGuard.NotNull(postingLineModel, nameof(postingLineModel));

            return(accountModel == null
                ? Task.FromResult(postingLineModel.Accounting)
                : Task.FromResult(postingLineModel.Accounting ?? accountModel));
        }
        internal static bool Convertible(this AccountingModel accountingModel)
        {
            NullGuard.NotNull(accountingModel, nameof(accountingModel));

            return(accountingModel.LetterHead != null);
        }