public static Model.Expression ResolvePath(string path, string scope)
        {
            if (String.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException("path");
            }

            Model.Expression result = null;

            // Path may contain any number of member accessors and indexers
            // e.g. code.coding[1]

            while (true)
            {
                int firstIndex = path.IndexOfAny(new[] { '.', '[' });
                if (firstIndex >= 0)
                {
                    var memberName = path.Substring(0, firstIndex);
                    if (memberName != String.Empty)
                    {
                        result = BuildMemberAccessor(result, memberName, scope);
                    }

                    if (path[firstIndex] == '[')
                    {
                        var indexOfMatchingBracket = IndexOfMatchingBracket(path, firstIndex);
                        var indexPath       = path.Substring(firstIndex + 1, indexOfMatchingBracket - (firstIndex + 1));
                        var indexExpression = ResolvePath(indexPath, scope);
                        // The use of .Get() here assumes the existence of appropriate list types with a Get method.
                        // This is a T-SQL specific solution to the representation of FHIR within SQL.
                        // Oracle would likely use a VARRAY, and PostgreSQL would use an array.
                        // Both those syntaxes would use an Indexer expression here, rather than a Get.
                        result = new Model.QualifierExpression(result, new Model.CallExpression("Get", new Model.Expression[] { indexExpression }));
                        if (indexOfMatchingBracket >= (path.Length - 1))
                        {
                            break;
                        }

                        path = path.Substring(indexOfMatchingBracket + 1);
                    }
                    else
                    {
                        path = path.Substring(firstIndex + 1);
                    }
                }
                else
                {
                    result = BuildMemberAccessor(result, path, scope);
                    break;
                }
            }

            return(result);
        }
        private static Model.Expression BuildMemberAccessor(Model.Expression current, string path, string scope)
        {
            if (path.IsDigit())
            {
                if (current != null)
                {
                    throw new InvalidOperationException("Only index expressions can be integer literals.");
                }

                return(new Model.ValueExpression(Int32.Parse(path)));
            }
            else
            {
                if (current != null)
                {
                    return(new Model.QualifierExpression(current, new SQLModel.QualifiedFieldExpression(path)));
                }
                else
                {
                    return(new SQLModel.QualifiedFieldExpression(path, scope));
                }
            }
        }
 public static Model.Expression DemoteBooleanValuedExpression(Model.Expression expression)
 {
     // Although the traditional test for true is "<> 0", we use "= 1" here because A) we have control over how boolean are translated to integers,
     // so we know they will always be represented as a 1 or 0, and the use of "=" rather than "<>" is more likely to be optimizable if it hits a sargable scenario. (we stay conjunctive).
     return(new Model.BinaryExpression(expression, "iEqual", new Model.ValueExpression(1)));
 }