public LogicalGroup(ConditionGroup group) { List <LogicalItem> subItems = new List <LogicalItem>(); Group = group; foreach (ExpressionTreeBase current in group.Children) { foreach (LogicalItem next in ConditionGroup.Convert(current)) { subItems.Add(next); } } SubItems = subItems.ToArray(); IEnumerable <SelectorTypes> types = SubItems.Select(x => x.SingleSelector).Distinct(); if (IsSingleSelector = types.Count() == 1 && !SubItems.OfType <LogicalGroup>().Any(x => !x.IsSingleSelector)) { SingleSelector = types.First(); } List <List <LogicalItem> > chains = GetChains(subItems); List <SelectorGroup> groups = new List <SelectorGroup>(); foreach (List <LogicalItem> chain in chains) { List <LogicalItem> unknownItems = new List <LogicalItem>(); SelectorTypes[] newTypes = chain.Select(x => x is LogicalGroup ? (((LogicalGroup)x).IsSingleSelector ? x.SingleSelector : SelectorTypes.Invalid) : x.SingleSelector).Distinct().ToArray(); foreach (SelectorTypes current in newTypes) { List <LogicalItem> items = new List <LogicalItem>(); for (int i = chain.Count - 1; i >= 0; i--) { LogicalItem item = chain[i]; SelectorTypes?selector = item is LogicalGroup ? (((LogicalGroup)item).IsSingleSelector ? (SelectorTypes?)item.SingleSelector : null) : item.SingleSelector; if (selector == null) { unknownItems.Insert(0, item); chain.RemoveAt(i); } else if (selector == current) { items.Insert(0, item); } } if (items.Count > 0) { groups.Add(new SelectorGroup(items, current)); } } if (unknownItems.Count > 0) { groups.Add(new SelectorGroup(unknownItems, null)); } } for (int i = groups.Count - 1; i >= 0; i--) { if (i > 0) { if (groups[i].Selector == groups[i - 1].Selector) { SelectorGroup upperGroup = groups[i]; SelectorGroup lowerGroup = groups[i - 1]; groups.RemoveAt(i); groups.RemoveAt(i - 1); List <LogicalItem> items = new List <LogicalItem>(); items.AddRange(lowerGroup.Children); items.AddRange(upperGroup.Children); SelectorGroup joinedGroup = new SelectorGroup(items, upperGroup.Selector); groups.Insert(i - 1, joinedGroup); } } } SelectorGroups = groups.ToArray(); }