private static Chain GetChainFromBox( IReadOnlyCollection <LaboriousDetail> sortedBox, Func <LaboriousDetail, LaboriousDetail, bool> conflictPredicate) { if (sortedBox.Count == 1) { return(new Chain(sortedBox)); } var chain = new Chain(); foreach (var detailFromSortedBox in sortedBox) { //chain have elements if (chain.Any()) { //last element from chain var lastElement = chain.Last; if (lastElement.Value.Type == ChainType.Conflict) { var conflict = lastElement.Value as Conflict; var isConflict = conflict.Details.Values.Any(detail => conflictPredicate.Invoke(detail, detailFromSortedBox)); if (isConflict) { conflict.Details.Add(detailFromSortedBox.Number, detailFromSortedBox); } else { chain.AddLast(detailFromSortedBox); } } else { var lastDetail = lastElement.Value as LaboriousDetail; if (conflictPredicate.Invoke(lastDetail, detailFromSortedBox)) { //it's conflict var conflict = new Conflict(); conflict.Details.Add(lastDetail.Number, lastDetail); conflict.Details.Add(detailFromSortedBox.Number, detailFromSortedBox); chain.RemoveLast(); chain.AddLast(conflict); } else { chain.AddLast(detailFromSortedBox); } } } //chain doesn't have elements else { chain.AddLast(detailFromSortedBox); } } return(chain); }