public static SpecificationResult ParseSpecification(SymbolTable symbolTable, SpecificationContext context, Expression body)
        {
            if (body is MethodCallExpression methodCall)
            {
                var method = methodCall.Method;

                if (method.DeclaringType == typeof(FactRepository) &&
                    method.Name == nameof(FactRepository.OfType))
                {
                    var type     = method.GetGenericArguments()[0];
                    var factType = type.FactTypeName();

                    var set = FactsOfType(factType, type);
                    var sourceSymbolValue = new SymbolValueSetDefinition(set);
                    var source            = SpecificationResult.FromValue(sourceSymbolValue)
                                            .WithTarget(set);

                    if (methodCall.Arguments.Count == 0)
                    {
                        return(source);
                    }
                    else
                    {
                        return(ParseWhere(source, symbolTable, context, methodCall.Arguments[0]));
                    }
                }
                else if (method.DeclaringType == typeof(Queryable))
                {
                    if (method.Name == nameof(Queryable.Where) && methodCall.Arguments.Count == 2)
                    {
                        var source = ParseSpecification(symbolTable, context, methodCall.Arguments[0]);
                        return(ParseWhere(source, symbolTable, context, methodCall.Arguments[1]));
                    }
                    else if (method.Name == nameof(Queryable.Select) && methodCall.Arguments.Count == 2)
                    {
                        var source = ParseSpecification(symbolTable, context, methodCall.Arguments[0]);
                        return(ParseSelect(source, symbolTable, context, methodCall.Arguments[1]));
                    }
                    else if (method.Name == nameof(Queryable.SelectMany) && methodCall.Arguments.Count == 3)
                    {
                        var source = ParseSpecification(symbolTable, context, methodCall.Arguments[0]);
                        return(ParseSelectMany(source, symbolTable, context, methodCall.Arguments[1], methodCall.Arguments[2]));
                    }
                    else
                    {
                        throw new SpecificationException($"You cannot use {method.Name} in a Jinaga specification.");
                    }
                }
                else
                {
                    throw new SpecificationException($"You cannot use {method.DeclaringType.Name}.{method.Name} in a Jinaga specification.");
                }
            }
            else
            {
                throw new SpecificationException($"You cannot use the syntax {body} in a Jinaga specification.");
            }
        }
 public static SpecificationResult ParseValue(SymbolValue symbolValue)
 {
     return(InferPathsFromValue(SpecificationResult.FromValue(symbolValue), symbolValue));
 }