/** <summary>
         *  To write out the value of a condition expr, invoke the evaluator in eval.g
         *  to walk the condition tree computing the boolean value.  If result
         *  is true, then write subtemplate.
         *  </summary>
         */
        public override int Write(StringTemplate self, IStringTemplateWriter @out)
        {
            if (AST == null || self == null || @out == null)
            {
                return(0);
            }
            //System.Console.Out.WriteLine( "evaluating conditional tree: " + AST.ToStringTree() );
#if !COMPILE_EXPRESSIONS
            ActionEvaluator eval = null;
#endif
            int n = 0;
            try
            {
                bool testedTrue = false;
                // get conditional from tree and compute result
#if COMPILE_EXPRESSIONS
                if (EvaluateCondition == null)
                {
                    EvaluateCondition = GetEvaluator(this, AST.GetChild(0));
                }
                bool includeSubtemplate = EvaluateCondition(self, @out);   // eval and write out tree
#else
                ITree cond = AST.GetChild(0);
                eval = new ActionEvaluator(self, this, @out, cond);
                // eval and write out trees
                bool includeSubtemplate = eval.ifCondition();
#endif
                //System.Console.Out.WriteLine( "subtemplate " + _subtemplate );
                // IF
                if (includeSubtemplate)
                {
                    n          = WriteSubTemplate(self, @out, _subtemplate);
                    testedTrue = true;
                }
                // ELSEIF
                else if (_elseIfSubtemplates != null && _elseIfSubtemplates.Count > 0)
                {
                    for (int i = 0; i < _elseIfSubtemplates.Count; i++)
                    {
                        ElseIfClauseData elseIfClause = _elseIfSubtemplates[i];
#if COMPILE_EXPRESSIONS
                        if (elseIfClause.EvaluateCondition == null)
                        {
                            elseIfClause.EvaluateCondition = GetEvaluator(this, elseIfClause.expr.AST);
                        }
                        includeSubtemplate = elseIfClause.EvaluateCondition(self, @out);
#else
                        eval = new ActionEvaluator(self, this, @out, elseIfClause.expr.AST);
                        includeSubtemplate = eval.ifCondition();
#endif
                        if (includeSubtemplate)
                        {
                            WriteSubTemplate(self, @out, elseIfClause.st);
                            testedTrue = true;
                            break;
                        }
                    }
                }
                // ELSE
                if (!testedTrue && _elseSubtemplate != null)
                {
                    // evaluate ELSE clause if present and IF condition failed
                    StringTemplate s = _elseSubtemplate.GetInstanceOf();
                    s.EnclosingInstance = self;
                    s.Group             = self.Group;
                    s.NativeGroup       = self.NativeGroup;
                    n = s.Write(@out);
                }
                // cond==false and no else => Missing output not empty
                if (!testedTrue && _elseSubtemplate == null)
                {
                    n = Missing;
                }
            }
            catch (RecognitionException re)
            {
                self.Error("can't evaluate tree: " + AST.ToStringTree(), re);
            }
            return(n);
        }