public static IXor2 <IPropertyDescription, IPropertyDescriptionChain, IPropertyOrChainDescription> FromPath(IReadOnlyList <string> path, Type accessingType, Type valueType) { var firstPropName = path.First(); var rest = path.Skip(1); if (!rest.Any()) { var firstPropDesc = new PropertyDescription(accessingType, valueType, firstPropName); return(new Xor2 <IPropertyDescription, IPropertyDescriptionChain, IPropertyOrChainDescription>(firstPropDesc)); } else { var firstPropDesc = new PropertyDescription(accessingType, TypeOf.Property(firstPropName, accessingType), firstPropName); var firstFromRest = rest.First(); var restOfNodes = rest.SelectWithHistory ( oxStart: xStr => new PropertyDescription(firstPropDesc.ValueType, TypeOf.Property(firstFromRest, firstPropDesc.ValueType), firstFromRest), oxOnLast: (xStr, xPrevNode) => new PropertyDescription(xPrevNode.ValueType, valueType, xStr), oxNext: (xStr, xPrevNode) => new PropertyDescription(xPrevNode.ValueType, TypeOf.Property(xStr, xPrevNode.ValueType), xStr) ) .ToList(); var chain = new PropertyDescriptionChain(firstPropDesc, restOfNodes); return(new Xor2 <IPropertyDescription, IPropertyDescriptionChain, IPropertyOrChainDescription>(chain)); } }