public ICollection <IComparatorResultInternal> CompareSides(ISideRunner sideA, ISideRunner sideB, bool runInverted, IPrinter printer) { return(printer.Indent($"Comparing sides '{sideA?.Definition.Name}' == '{sideB?.Definition.Name}' {(runInverted ? "INVERTED" : "")}", () => { var res = new List <IComparatorResultInternal>(); Dictionary <TKey, Tuple <LoadedItem, LoadedItem> > dic = new Dictionary <TKey, Tuple <LoadedItem, LoadedItem> >(); if (sideA?.Entries != null) { foreach (var item in sideA?.Entries) { var tup = new Tuple <LoadedItem, LoadedItem>(item, new LoadedItem { Item = null, //Sides = sideB.SubSides?.Select(side => //{ // var clon = side.Clone(); // clon.Source = null; // clon.Definition.Name = $"{clon.Definition.Name} ({sideA.GetItemName(item.Item)})"; // return clon; //}).ToList() ?? Enumerable.Empty<ISideRunner>().ToList() Sides = Enumerable.Empty <ISideRunner>().ToList() }); if (sideB?.SubSides != null) { foreach (var subSide in (runInverted ? sideA : sideB).SubSides) { var clon = subSide.Clone(); clon.Source = null; //clon.Definition.Name = $"{clon.Definition.Name} ({sideA.GetItemName(item.Item)})"; clon.Definition.Name = $"{clon.Definition.Name.Replace("%sourceName%", sideA.GetItemName(item.Item))}"; var sides = runInverted ? tup.Item1.Sides : tup.Item2.Sides; if (!sides.Any(s => s.Definition.Name == clon.Definition.Name)) { printer.WriteLine($"Creating side-clon '{clon.Definition.Name}-{clon.Definition.IsMaster}' with source '{sideA.GetItemName(item.Item)}'"); if (runInverted) { tup.Item1.Sides.Add(clon); } else { tup.Item2.Sides.Add(clon); } } } } dic.Add(definition.OnSelectKeyA.Invoke((TItemA)item.Item), tup); } } if (sideB?.Entries != null) { foreach (var item in sideB?.Entries) { var key = definition.OnSelectKeyB.Invoke((TItemB)item.Item); if (dic.ContainsKey(key)) { dic[key] = new Tuple <LoadedItem, LoadedItem>(dic[key].Item1, item); } else { var tup = new Tuple <LoadedItem, LoadedItem>(new LoadedItem { Item = null, //Sides = sideA.SubSides Sides = Enumerable.Empty <ISideRunner>().ToList() }, item); if (sideA?.SubSides != null) { foreach (var subSide in (runInverted ? sideA : sideB).SubSides) { var clon = subSide.Clone(); clon.Source = null; clon.Definition.Name = $"{clon.Definition.Name} ({sideB.GetItemName(item.Item)})"; printer.WriteLine($"Creating side-clon '{clon.Definition.Name}-{clon.Definition.IsMaster}' with source '{sideB.GetItemName(item.Item)}'"); if (runInverted) { tup.Item1.Sides.Add(clon); } else { tup.Item2.Sides.Add(clon); } } } dic.Add(key, tup); } } } foreach (var tup in dic.Values) { var r = CompareItems(tup.Item1, tup.Item2, runInverted, printer);//tup.Item2.Sides.Any(s => s.Definition.IsMaster)); if (r != null) { res.Add(r); } } return res; })); }