func (v *evalVisitor) VisitBlock(node *ast.BlockStatement) interface{} {
	v.at(node)
	v.pushBlock(node)
	var result interface{}
	expr := node.Expression.Accept(v)
	if v.isHelperCall(node.Expression) || v.wasFuncCall(node.Expression) {
		result = expr
	} else {
		val := reflect.ValueOf(expr)
		truth, _ := isTrueValue(val)
		if truth {
			if node.Program != nil {
				switch val.Kind() {
				case reflect.Array, reflect.Slice:
					concat := ""
					for i := 0; i < val.Len(); i++ {
						frame := v.dataFrame.newIterDataFrame(val.Len(), i, nil)
						concat += v.evalProgram(node.Program, val.Index(i).Interface(), frame, i)
					}
					result = concat
				default:
					result = v.evalProgram(node.Program, expr, nil, nil)
				}
			}
		} else if node.Inverse != nil {
			result, _ = node.Inverse.Accept(v).(string)
		}
	}
	v.popBlock()
	return result
}
VisitBlock implements corresponding Visitor interface method
package raymond
import (
	"bytes"
	"fmt"
	"reflect"
	"strconv"
	"strings"
	"github.com/aymerick/raymond/ast"
)
var (
	errorType       = reflect.TypeOf((*error)(nil)).Elem()
	fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
	zero reflect.Value
)
type evalVisitor struct {
	tpl *Template
	ctx []reflect.Value
	dataFrame *DataFrame
	blockParams []map[string]interface{}
	blocks []*ast.BlockStatement
	exprs []*ast.Expression
	exprFunc map[*ast.Expression]bool
	curNode ast.Node
}
func newEvalVisitor(tpl *Template, ctx interface{}, privData *DataFrame) *evalVisitor {
	frame := privData
	if frame == nil {
		frame = NewDataFrame()
	}
	return &evalVisitor{
		tpl:       tpl,
		ctx:       []reflect.Value{reflect.ValueOf(ctx)},
		dataFrame: frame,
		exprFunc:  make(map[*ast.Expression]bool),
	}
}
func (v *evalVisitor) at(node ast.Node) {
	v.curNode = node
}
func (v *evalVisitor) pushCtx(ctx reflect.Value) {
	v.ctx = append(v.ctx, ctx)
}
func (v *evalVisitor) popCtx() reflect.Value {
	if len(v.ctx) == 0 {
		return zero
	}
	var result reflect.Value
	result, v.ctx = v.ctx[len(v.ctx)-1], v.ctx[:len(v.ctx)-1]
	return result
}
func (v *evalVisitor) rootCtx() reflect.Value {
	return v.ctx[0]
}
func (v *evalVisitor) curCtx() reflect.Value {
	return v.ancestorCtx(0)
}
func (v *evalVisitor) ancestorCtx(depth int) reflect.Value {
	index := len(v.ctx) - 1 - depth
	if index < 0 {
		return zero
	}
	return v.ctx[index]
}
func (v *evalVisitor) setDataFrame(frame *DataFrame) {
	v.dataFrame = frame
}
func (v *evalVisitor) popDataFrame() {
	v.dataFrame = v.dataFrame.parent
}
func (v *evalVisitor) pushBlockParams(params map[string]interface{}) {
	v.blockParams = append(v.blockParams, params)
}
func (v *evalVisitor) popBlockParams() map[string]interface{} {
	var result map[string]interface{}
	if len(v.blockParams) == 0 {
		return result
	}
	result, v.blockParams = v.blockParams[len(v.blockParams)-1], v.blockParams[:len(v.blockParams)-1]
	return result
}
func (v *evalVisitor) blockParam(name string) interface{} {
	for i := len(v.blockParams) - 1; i >= 0; i-- {
		for k, v := range v.blockParams[i] {
			if name == k {
				return v
			}
		}
	}
	return nil
}
func (v *evalVisitor) pushBlock(block *ast.BlockStatement) {
	v.blocks = append(v.blocks, block)
}
func (v *evalVisitor) popBlock() *ast.BlockStatement {
	if len(v.blocks) == 0 {
		return nil
	}
	var result *ast.BlockStatement
	result, v.blocks = v.blocks[len(v.blocks)-1], v.blocks[:len(v.blocks)-1]
	return result
}
func (v *evalVisitor) curBlock() *ast.BlockStatement {
	if len(v.blocks) == 0 {
		return nil
	}
	return v.blocks[len(v.blocks)-1]
}
func (v *evalVisitor) pushExpr(expression *ast.Expression) {
	v.exprs = append(v.exprs, expression)
}
func (v *evalVisitor) popExpr() *ast.Expression {
	if len(v.exprs) == 0 {
		return nil
	}
	var result *ast.Expression
	result, v.exprs = v.exprs[len(v.exprs)-1], v.exprs[:len(v.exprs)-1]
	return result
}
func (v *evalVisitor) curExpr() *ast.Expression {
	if len(v.exprs) == 0 {
		return nil
	}
	return v.exprs[len(v.exprs)-1]
}
func (v *evalVisitor) errPanic(err error) {
	panic(fmt.Errorf("Evaluation error: %s\nCurrent node:\n\t%s", err, v.curNode))
}
func (v *evalVisitor) errorf(format string, args ...interface{}) {
	v.errPanic(fmt.Errorf(format, args...))
}
func (v *evalVisitor) evalProgram(program *ast.Program, ctx interface{}, data *DataFrame, key interface{}) string {
	blockParams := make(map[string]interface{})
	if len(program.BlockParams) > 0 {
		blockParams[program.BlockParams[0]] = ctx
	}
	if (len(program.BlockParams) > 1) && (key != nil) {
		blockParams[program.BlockParams[1]] = key
	}
	if len(blockParams) > 0 {
		v.pushBlockParams(blockParams)
	}
	ctxVal := reflect.ValueOf(ctx)
	if ctxVal.IsValid() {
		v.pushCtx(ctxVal)
	}
	if data != nil {
		v.setDataFrame(data)
	}
	result, _ := program.Accept(v).(string)
	if data != nil {
		v.popDataFrame()
	}
	if ctxVal.IsValid() {
		v.popCtx()
	}
	if len(blockParams) > 0 {
		v.popBlockParams()
	}
	return result
}
func (v *evalVisitor) evalPath(ctx reflect.Value, parts []string, exprRoot bool) (reflect.Value, bool) {
	partResolved := false
	for i := 0; i < len(parts); i++ {
		part := parts[i]
		if (len(part) >= 2) && (part[0] == '[') && (part[len(part)-1] == ']') {
			part = part[1 : len(part)-1]
		}
		ctx = v.evalField(ctx, part, exprRoot)
		if !ctx.IsValid() {
			break
		}
		partResolved = true
	}
	return ctx, partResolved
}
func (v *evalVisitor) evalField(ctx reflect.Value, fieldName string, exprRoot bool) reflect.Value {
	result := zero
	ctx, _ = indirect(ctx)
	if !ctx.IsValid() {
		return result
	}
	result, isMeth := v.evalMethod(ctx, fieldName, exprRoot)
	if !isMeth {
		switch ctx.Kind() {
		case reflect.Struct:
			expFieldName := strings.Title(fieldName)
			if tField, ok := ctx.Type().FieldByName(expFieldName); ok && (tField.PkgPath == "") {
				result = ctx.FieldByIndex(tField.Index)
				break
			}
			result = v.evalStructTag(ctx, fieldName)
		case reflect.Map:
			nameVal := reflect.ValueOf(fieldName)
			if nameVal.Type().AssignableTo(ctx.Type().Key()) {
				result = ctx.MapIndex(nameVal)
			}
		case reflect.Array, reflect.Slice:
			if i, err := strconv.Atoi(fieldName); (err == nil) && (i < ctx.Len()) {
				result = ctx.Index(i)
			}
		}
	}
	result, _ = indirect(result)
	if result.Kind() == reflect.Func {
		result = v.evalFieldFunc(fieldName, result, exprRoot)
	}
	return result
}
func (v *evalVisitor) evalMethod(ctx reflect.Value, name string, exprRoot bool) (reflect.Value, bool) {
	if ctx.Kind() != reflect.Interface && ctx.CanAddr() {
		ctx = ctx.Addr()
	}
	method := ctx.MethodByName(name)
	if !method.IsValid() {
		method = ctx.MethodByName(strings.Title(name))
	}
	if !method.IsValid() {
		return zero, false
	}
	return v.evalFieldFunc(name, method, exprRoot), true
}
func (v *evalVisitor) evalFieldFunc(name string, funcVal reflect.Value, exprRoot bool) reflect.Value {
	ensureValidHelper(name, funcVal)
	var options *Options
	if exprRoot {
		expr := v.curExpr()
		options = v.helperOptions(expr)
		v.exprFunc[expr] = true
	} else {
		options = newEmptyOptions(v)
	}
	return v.callFunc(name, funcVal, options)
}
func (v *evalVisitor) evalStructTag(ctx reflect.Value, name string) reflect.Value {
	val := reflect.ValueOf(ctx.Interface())
	for i := 0; i < val.NumField(); i++ {
		field := val.Type().Field(i)
		tag := field.Tag.Get("handlebars")
		if tag == name {
			return val.Field(i)
		}
	}
	return zero
}
func (v *evalVisitor) findBlockParam(node *ast.PathExpression) (string, interface{}) {
	if len(node.Parts) > 0 {
		name := node.Parts[0]
		if value := v.blockParam(name); value != nil {
			return name, value
		}
	}
	return "", nil
}
func (v *evalVisitor) evalPathExpression(node *ast.PathExpression, exprRoot bool) interface{} {
	var result interface{}
	if name, value := v.findBlockParam(node); value != nil {
		newCtx := map[string]interface{}{name: value}
		v.pushCtx(reflect.ValueOf(newCtx))
		result = v.evalCtxPathExpression(node, exprRoot)
		v.popCtx()
	} else {
		ctxTried := false
		if node.IsDataRoot() {
			result = v.evalCtxPathExpression(node, exprRoot)
			ctxTried = true
		}
		if (result == nil) && node.Data {
			result = v.evalDataPathExpression(node, exprRoot)
		}
		if (result == nil) && !ctxTried {
			result = v.evalCtxPathExpression(node, exprRoot)
		}
	}
	return result
}
func (v *evalVisitor) evalDataPathExpression(node *ast.PathExpression, exprRoot bool) interface{} {
	frame := v.dataFrame
	for i := node.Depth; i > 0; i-- {
		if frame.parent == nil {
			return nil
		}
		frame = frame.parent
	}
	result, _ := v.evalCtxPath(reflect.ValueOf(frame.data), node.Parts, exprRoot)
	return result
}
func (v *evalVisitor) evalCtxPathExpression(node *ast.PathExpression, exprRoot bool) interface{} {
	v.at(node)
	if node.IsDataRoot() {
		parts := node.Parts[1:len(node.Parts)]
		result, _ := v.evalCtxPath(v.rootCtx(), parts, exprRoot)
		return result
	}
	return v.evalDepthPath(node.Depth, node.Parts, exprRoot)
}
func (v *evalVisitor) evalDepthPath(depth int, parts []string, exprRoot bool) interface{} {
	var result interface{}
	partResolved := false
	ctx := v.ancestorCtx(depth)
	for (result == nil) && ctx.IsValid() && (depth <= len(v.ctx) && !partResolved) {
		result, partResolved = v.evalCtxPath(ctx, parts, exprRoot)
		if !partResolved && (result == nil) {
			depth++
			ctx = v.ancestorCtx(depth)
		}
	}
	return result
}
func (v *evalVisitor) evalCtxPath(ctx reflect.Value, parts []string, exprRoot bool) (interface{}, bool) {
	var result interface{}
	partResolved := false
	switch ctx.Kind() {
	case reflect.Array, reflect.Slice:
		var results []interface{}
		for i := 0; i < ctx.Len(); i++ {
			value, _ := v.evalPath(ctx.Index(i), parts, exprRoot)
			if value.IsValid() {
				results = append(results, value.Interface())
			}
		}
		result = results
	default:
		var value reflect.Value
		value, partResolved = v.evalPath(ctx, parts, exprRoot)
		if value.IsValid() {
			result = value.Interface()
		}
	}
	return result, partResolved
}
func (v *evalVisitor) isHelperCall(node *ast.Expression) bool {
	if helperName := node.HelperName(); helperName != "" {
		return v.findHelper(helperName) != zero
	}
	return false
}
func (v *evalVisitor) findHelper(name string) reflect.Value {
	if h := v.tpl.findHelper(name); h != zero {
		return h
	}
	return findHelper(name)
}
func (v *evalVisitor) callFunc(name string, funcVal reflect.Value, options *Options) reflect.Value {
	params := options.Params()
	funcType := funcVal.Type()
	strType := reflect.TypeOf("")
	boolType := reflect.TypeOf(true)
	addOptions := false
	numIn := funcType.NumIn()
	if numIn == len(params)+1 {
		lastArgType := funcType.In(numIn - 1)
		if reflect.TypeOf(options).AssignableTo(lastArgType) {
			addOptions = true
		}
	}
	if !addOptions && (len(params) != numIn) {
		v.errorf("Helper '%s' called with wrong number of arguments, needed %d but got %d", name, numIn, len(params))
	}
	args := make([]reflect.Value, numIn)
	for i, param := range params {
		arg := reflect.ValueOf(param)
		argType := funcType.In(i)
		if !arg.IsValid() {
			if canBeNil(argType) {
				arg = reflect.Zero(argType)
			} else if argType.Kind() == reflect.String {
				arg = reflect.ValueOf("")
			} else {
				return reflect.Zero(strType)
			}
		}
		if !arg.Type().AssignableTo(argType) {
			if strType.AssignableTo(argType) {
				arg = reflect.ValueOf(strValue(arg))
			} else if boolType.AssignableTo(argType) {
				val, _ := isTrueValue(arg)
				arg = reflect.ValueOf(val)
			} else {
				v.errorf("Helper %s called with argument %d with type %s but it should be %s", name, i, arg.Type(), argType)
			}
		}
		args[i] = arg
	}
	if addOptions {
		args[numIn-1] = reflect.ValueOf(options)
	}
	result := funcVal.Call(args)
	return result[0]
}
func (v *evalVisitor) callHelper(name string, helper reflect.Value, node *ast.Expression) interface{} {
	result := v.callFunc(name, helper, v.helperOptions(node))
	if !result.IsValid() {
		return nil
	}
	return result.Interface()
}
func (v *evalVisitor) helperOptions(node *ast.Expression) *Options {
	var params []interface{}
	var hash map[string]interface{}
	for _, paramNode := range node.Params {
		param := paramNode.Accept(v)
		params = append(params, param)
	}
	if node.Hash != nil {
		hash, _ = node.Hash.Accept(v).(map[string]interface{})
	}
	return newOptions(v, params, hash)
}
func (v *evalVisitor) findPartial(name string) *partial {
	if p := v.tpl.findPartial(name); p != nil {
		return p
	}
	return findPartial(name)
}
func (v *evalVisitor) partialContext(node *ast.PartialStatement) reflect.Value {
	if nb := len(node.Params); nb > 1 {
		v.errorf("Unsupported number of partial arguments: %d", nb)
	}
	if (len(node.Params) > 0) && (node.Hash != nil) {
		v.errorf("Passing both context and named parameters to a partial is not allowed")
	}
	if len(node.Params) == 1 {
		return reflect.ValueOf(node.Params[0].Accept(v))
	}
	if node.Hash != nil {
		hash, _ := node.Hash.Accept(v).(map[string]interface{})
		return reflect.ValueOf(hash)
	}
	return zero
}
func (v *evalVisitor) evalPartial(p *partial, node *ast.PartialStatement) string {
	partialTpl, err := p.template()
	if err != nil {
		v.errPanic(err)
	}
	ctx := v.partialContext(node)
	if ctx.IsValid() {
		v.pushCtx(ctx)
	}
	result, _ := partialTpl.program.Accept(v).(string)
	result = indentLines(result, node.Indent)
	if ctx.IsValid() {
		v.popCtx()
	}
	return result
}
func indentLines(str string, indent string) string {
	if indent == "" {
		return str
	}
	var indented []string
	lines := strings.Split(str, "\n")
	for i, line := range lines {
		if (i == (len(lines) - 1)) && (line == "") {
			indented = append(indented, line)
		} else {
			indented = append(indented, indent+line)
		}
	}
	return strings.Join(indented, "\n")
}
func (v *evalVisitor) wasFuncCall(node *ast.Expression) bool {
	return v.exprFunc[node]
}
func (v *evalVisitor) VisitProgram(node *ast.Program) interface{} {
	v.at(node)
	buf := new(bytes.Buffer)
	for _, n := range node.Body {
		if str := Str(n.Accept(v)); str != "" {
			if _, err := buf.Write([]byte(str)); err != nil {
				v.errPanic(err)
			}
		}
	}
	return buf.String()
}
func (v *evalVisitor) VisitMustache(node *ast.MustacheStatement) interface{} {
	v.at(node)
	expr := node.Expression.Accept(v)
	isSafe := isSafeString(expr)
	str := Str(expr)
	if !isSafe && !node.Unescaped {
		str = Escape(str)
	}
	return str
}