/// <summary> /// Actually perform the copy /// </summary> /// <param name="src"></param> /// <returns></returns> public int CopyRecordsTo(BaseRecord[] src) { int count = 0; PrepMasters(src); var dstRec = this.Clone(src.Where(x => !LooseGroups.Contains(x.Name)), true).ToArray(); if (dstRec.All(x => x is Record)) { // put records into appropriate groups var groups = plugin.Records.OfType <GroupRecord>().ToList(); var lookup = dstRec.GroupBy(r => r.Name) .Select(g => new { key = g.Key, value = g.ToArray() }) .ToLookup(k => k.key, v => v.value); foreach (var kvp in lookup) { if (LooseGroups.Contains(kvp.Key)) { plugin.AddRecords(dstRec); } else { var gr = groups.FirstOrDefault(x => x.ContentsType == kvp.Key); if (gr == null) { gr = new GroupRecord(kvp.Key); plugin.AddRecord(gr); } foreach (var list in kvp) { gr.AddRecords(list); } } } } else { plugin.AddRecords(dstRec); } // handle loose groups by creating copy of parent groups foreach (var srcRec in src.Where(x => LooseGroups.Contains(x.Name))) { var dstnodes = new Stack <BaseRecord>(); dstnodes.Push(this.Clone(srcRec, true)); for (var n = srcRec.Parent; n is GroupRecord; n = n.Parent) { dstnodes.Push(n.Clone(recursive: false)); } var par = plugin as IGroupRecord; foreach (var baseRecord in dstnodes) { if (par == null) { break; } if (baseRecord is GroupRecord) { var gr = baseRecord as GroupRecord; var pargr = par.Records.OfType <GroupRecord>().FirstOrDefault(x => x.IsEquivalent(gr)); if (pargr != null) { par = pargr; continue; } } par.AddRecord(baseRecord); par = baseRecord as IGroupRecord; } count += dstnodes.Count; } return(count); }