protected NodeUpdaterBase(IParseTreeRule <TokenType, ParserRuleType> node)
            {
                // Handle property name
                if (node.RuleType == ParserRuleType.TNode)
                {
                    // The property name is defined in the first element
                    this.propertyName = new KnownPropertyName(node.Elements[0].Token().Value);
                }
                else if (node.RuleType == ParserRuleType.TIndexedNode)
                {
                    // The property name is defined as a series of
                    // tokens where some or all are variables
                    this.propertyName = new IndexedPropertyName(
                        node.Elements
                        .OfType <IParseTreeRule <TokenType, ParserRuleType> >()
                        .Where(o => o.RuleType == ParserRuleType.TIndexedNodeContent)
                        .Select(o => o.Token())
                        .ToList());
                }

                // Find whether this should be an array node
                this.IsArray = node.Elements
                               .Any(
                    o => o is IParseTreeToken <TokenType, ParserRuleType> token &&
                    token.Token.Type == TokenType.Array);

                // Handle property value assignment
                var assignments = node.Rule(ParserRuleType.TPropertyValue);

                if (assignments != null)
                {
                    this.propertySetters = new List <PropertyValueUpdaterBase>();
                    foreach (IParseTreeRule <TokenType, ParserRuleType> assignment in assignments.Elements)
                    {
                        var path = ((IParseTreeRule <TokenType, ParserRuleType>)assignment.Elements[0]).Elements;
                        PropertyValueUpdaterBase setter = new PropertyValueUpdater(
                            path.Last().Token(),
                            assignment.Elements[1].Token());

                        for (int i = path.Count - 2; i >= 0; --i)
                        {
                            setter = new PropertyValueNodeUpdater(path[i].Token(), setter);
                        }

                        this.propertySetters.Add(setter);
                    }
                }

                // Handle conditional modifier
                var conditionalModifier = node.Rule(ParserRuleType.TConditionalModifier);

                this.when = conditionalModifier == null
                    ? Conditional.Always
                    : conditionalModifier.Token().Type == TokenType.ExclaimationMark
                        ? Conditional.IfNotExists
                        : Conditional.IfExists;
            }
                public VariableHandler(IParseTreeRule <TokenType, ParserRuleType> indexedNode)
                {
                    this.variableName = indexedNode.Elements[0].Token().Value;

                    var valueCapture = indexedNode.Rule(ParserRuleType.SPropertyValueCapture);

                    if (valueCapture != null)
                    {
                        this.valueCapturePath = valueCapture.Elements.Select(o => o.Token().Value).ToList();
                        this.variableCapture  = this.ValueCapture;
                    }
                    else
                    {
                        this.variableCapture = NameCapture;
                    }

                    var filterNode = indexedNode.Rule(ParserRuleType.SFilter);

                    if (filterNode != null)
                    {
                        this.filter = BuildFilter(
                            (IParseTreeRule <TokenType, ParserRuleType>)filterNode.Elements.Single());
                    }
                }