static async Task BetriebsmittelAbgleichen(
            IStammApi quellStammApi,
            IStammApi zielStammApi,
            AbgleichInfo abgleichInfo,
            Betriebsmittel quellGruppe,
            Betriebsmittel zielGruppe,
            Action <BetriebsmittelStammKopierEventArgs> messageCallback)
        {
            var quellChildren = quellGruppe.GruppeDetails.BetriebsmittelList.Where(b => b.Nummer != null).ToList();

            var zielChildrenByNumber = zielGruppe.GruppeDetails.BetriebsmittelList.Where(b => b.Nummer != null).ToDictionary(b => b.Nummer);

            foreach (var quellChildItem in quellChildren)
            {
                // Lade Quell-Betriebsmittel inkl. Details
                var quellChild = await quellStammApi.GetBetriebsmittel(quellChildItem.Id, quellChildItem.Art);

                messageCallback?.Invoke(new BetriebsmittelStammKopierEventArgs($"Abgleich des Betriebsmittels {quellChild.GetBetriebsmittelDescription()}"));

                zielChildrenByNumber.TryGetValue(quellChild.Nummer, out var zielChild);

                // Falls das Betriebsmittel noch keine Entsprechung im Ziel hat => neu erzeugen (gilt auch für Gruppen)
                if (zielChild == null)
                {
                    zielChild = await zielStammApi.CreateBetriebsmittel(abgleichInfo.ZielStamm.Id, new NewBetriebsmittelInfo
                    {
                        Art            = quellChild.Art,
                        Bezeichnung    = quellChild.Bezeichnung,
                        Nummer         = quellChild.Nummer,
                        ParentGruppeId = zielGruppe.Id
                    });

                    if (zielChild.GruppeDetails != null)
                    {
                        zielChild.GruppeDetails.BetriebsmittelList = new List <Betriebsmittel>();
                    }
                }

                abgleichInfo.QuellToZielBetriebsmittel.Add(quellChild, zielChild);

                zielChild.Bezeichnung    = quellChild.Bezeichnung;
                zielChild.Leistungsfähig = quellChild.Leistungsfähig;
                zielChild.Einheit        = quellChild.Einheit;

                zielChild.Kosten = quellChild.Kosten?.Select(k => new BetriebsmittelKosten
                {
                    KostenebeneId          = abgleichInfo.KatalogIdMap[k.KostenebeneId],
                    LohnDetails            = Clone(k.LohnDetails),
                    GerätDetails           = Clone(k.GerätDetails),
                    MaterialDetails        = Clone(k.MaterialDetails),
                    SonstigeKostenDetails  = Clone(k.SonstigeKostenDetails),
                    NachunternehmerDetails = Clone(k.NachunternehmerDetails)
                }).ToList();

                zielChild.Zuschläge = quellChild.Zuschläge?.Select(bz => new BetriebsmittelZuschlag
                {
                    ArtIndex = bz.ArtIndex,
                    ZuschlagsgruppenNummer = bz.ZuschlagsgruppenNummer,
                    ZuschlagsebeneId       = abgleichInfo.KatalogIdMap[bz.ZuschlagsebeneId],
                }).ToList();

                zielChild.Details = Clone(quellChild.Details);

                zielChild.LohnDetails            = Clone(quellChild.LohnDetails);
                zielChild.MaterialDetails        = Clone(quellChild.MaterialDetails);
                zielChild.GerätDetails           = Clone(quellChild.GerätDetails);
                zielChild.SonstigeKostenDetails  = Clone(quellChild.SonstigeKostenDetails);
                zielChild.NachunternehmerDetails = Clone(quellChild.NachunternehmerDetails);
                zielChild.BausteinDetails        = Clone(quellChild.BausteinDetails);

                zielChild.WeitereKosten = null;

                await zielStammApi.UpdateBetriebsmittel(zielChild.Id, zielChild);

                // Falls das zielChild eine Gruppe ist => rekursiv die Kinder abgleichen
                if (zielChild.GruppeDetails != null)
                {
                    await BetriebsmittelAbgleichen(quellStammApi, zielStammApi, abgleichInfo, quellChildItem, zielChild, messageCallback);
                }
            }
        }
 static string GetBetriebsmittelDescription(this Betriebsmittel betriebsmittel)
 {
     return(string.IsNullOrEmpty(betriebsmittel.Bezeichnung) ? betriebsmittel.NummerKomplett : $"{betriebsmittel.NummerKomplett} ('{betriebsmittel.Bezeichnung}')");
 }