package org.apache.velocity.runtime.parser.node;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import org.apache.velocity.app.event.EventHandlerUtil;
import org.apache.velocity.context.InternalContextAdapter;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.TemplateInitException;
import org.apache.velocity.exception.VelocityException;
import org.apache.velocity.io.Filter;
import org.apache.velocity.runtime.Renderable;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.directive.Block.Reference;
import org.apache.velocity.runtime.parser.LogContext;
import org.apache.velocity.runtime.parser.Parser;
import org.apache.velocity.runtime.parser.Token;
import org.apache.velocity.util.ClassUtils;
import org.apache.velocity.util.DuckType;
import org.apache.velocity.util.StringUtils;
import org.apache.velocity.util.introspection.Info;
import org.apache.velocity.util.introspection.VelMethod;
import org.apache.velocity.util.introspection.VelPropertySet;

import java.io.IOException;
import java.io.Writer;
import java.lang.reflect.InvocationTargetException;

/**
 * This class is responsible for handling the references in
 * VTL ($foo).
 *
 * Please look at the Parser.jjt file which is
 * what controls the generation of this class.
 *
 * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
 * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
 * @author <a href="mailto:Christoph.Reck@dlr.de">Christoph Reck</a>
 * @author <a href="mailto:kjohnson@transparent.com">Kent Johnson</a>
 * @version $Id$
*/
public class ASTReference extends SimpleNode
{
    /* Reference types */
    private static final int NORMAL_REFERENCE = 1;
    private static final int FORMAL_REFERENCE = 2;
    private static final int QUIET_REFERENCE = 3;
    private static final int RUNT = 4;

    private int referenceType;
    private String nullString;
    private String rootString;
    private boolean escaped = false;
    private boolean computableReference = true;
    private boolean logOnNull = true;
    private boolean lookupAlternateLiteral = false;
    private String escPrefix = "";
    private String morePrefix = "";
    private String identifier = "";

    private boolean checkEmpty;

    private String literal = null;

    /**
     * Indicates if we are running in strict reference mode.
     */
    public boolean strictRef = false;

    /**
     * non null Indicates if we are setting an index reference e.g, $foo[2], which basically
     * means that the last syntax of the reference are brackets.
     */
    private ASTIndex astIndex = null;

    /**
     * non null Indicates that an alternate value has been provided
     */
    private ASTExpression astAlternateValue = null;

    /**
     * Indicates if we are using modified escape behavior in strict mode.
     * mainly we allow \$abc -&gt; to render as $abc
     */
    public boolean strictEscape = false;

    private int numChildren = 0;

    /**
     * Whether to trigger an event for invalid quiet references
     * @since 2.2
     */
    private boolean warnInvalidQuietReferences = false;

    /**
     * Whether to trigger an event for invalid null references, that is when a value
     * is present in the context or parent object but is null
     * @since 2.2
     */
    private boolean warnInvalidNullReferences = false;

    /**
     * Whether to trigger an event for invalid tested references - as in #if($foo)
     * @since 2.2
     */
    private boolean warnInvalidTestedReferences = false;

    protected Info uberInfo;

    /**
     * @param id
     */
    public ASTReference(int id)
    {
        super(id);
    }

    /**
     * @param p
     * @param id
     */
    public ASTReference(Parser p, int id)
    {
        super(p, id);
    }

    /**
     * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object)
     */
    public Object jjtAccept(ParserVisitor visitor, Object data)
    {
        return visitor.visit(this, data);
    }

    /**
     * @see org.apache.velocity.runtime.parser.node.SimpleNode#init(org.apache.velocity.context.InternalContextAdapter, java.lang.Object)
     */
    public Object init(InternalContextAdapter context, Object data)
    throws TemplateInitException
    {
        super.init(context, data);

        strictEscape = rsvc.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT_ESCAPE, false);
        strictRef = rsvc.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT, false);
        lookupAlternateLiteral = rsvc.getBoolean(RuntimeConstants.VM_PRESERVE_ARGUMENTS_LITERALS, false);

        /*
         *  the only thing we can do in init() is getRoot()
         *  as that is template based, not context based,
         *  so it's thread- and context-safe
         */

        rootString = rsvc.useStringInterning() ? getRoot().intern() : getRoot();

        numChildren = jjtGetNumChildren();

        // This is an expensive call, so get it now.
        literal = literal();

        /*
         * and if appropriate...
         */
        if (numChildren > 0 )
        {
            Node lastNode = jjtGetChild(numChildren-1);
            if (lastNode instanceof ASTIndex)
            {
                /*
                 * only used in SetValue, where alternate value is forbidden
                 */
                astIndex = (ASTIndex) lastNode;
            }
            else if (lastNode instanceof ASTExpression)
            {
                astAlternateValue = (ASTExpression) lastNode;
                --numChildren;
            }
            else
            {
                identifier = lastNode.getFirstTokenImage();
            }
        }


        /*
         * make an uberinfo - saves new's later on
         */
        uberInfo = new Info(getTemplateName(), getLine(),getColumn());

        /*
         * track whether we log invalid references
         */
        logOnNull =
            rsvc.getBoolean(RuntimeConstants.RUNTIME_LOG_REFERENCE_LOG_INVALID, true);

        /*
         * whether to check for emptiness when evaluatingnumChildren
         */
        checkEmpty =
            rsvc.getBoolean(RuntimeConstants.CHECK_EMPTY_OBJECTS, true);

        /* invalid references special cases */

        warnInvalidQuietReferences =
            rsvc.getBoolean(RuntimeConstants.EVENTHANDLER_INVALIDREFERENCES_QUIET, false);
        warnInvalidNullReferences =
            rsvc.getBoolean(RuntimeConstants.EVENTHANDLER_INVALIDREFERENCES_NULL, false);
        warnInvalidTestedReferences =
            rsvc.getBoolean(RuntimeConstants.EVENTHANDLER_INVALIDREFERENCES_TESTED, false);


        /**
         * In the case we are referencing a variable with #if($foo) or
         * #if( ! $foo) then we allow variables to be undefined and we
         * set strictRef to false so that if the variable is undefined
         * an exception is not thrown.
         */
        if (strictRef && numChildren == 0)
        {
            logOnNull = false; // Strict mode allows nulls

            Node node = this.jjtGetParent();
            if (node instanceof ASTNotNode     // #if( ! $foo)
             || node instanceof ASTExpression  // #if( $foo )
             || node instanceof ASTOrNode      // #if( $foo || ...
             || node instanceof ASTAndNode)    // #if( $foo && ...
            {
                // Now scan up tree to see if we are in an If statement
                while (node != null)
                {
                    if (node instanceof ASTIfStatement)
                    {
                       strictRef = false;
                       break;
                    }
                    node = node.jjtGetParent();
                }
            }
        }
        saveTokenImages();
        cleanupParserAndTokens();

        return data;
    }

    /**
     *  Returns the 'root string', the reference key
     * @return the root string.
     */
     public String getRootString()
     {
        return rootString;
     }

    /**
     *   gets an Object that 'is' the value of the reference
     *
     *   @param o Object parameter, unused per se, but non-null by convention inside an #if/#elseif evaluation
     *   @param context context used to generate value
     * @return The execution result.
     * @throws MethodInvocationException
     */
    public Object execute(Object o, InternalContextAdapter context)
        throws MethodInvocationException
    {
        try
        {
            rsvc.getLogContext().pushLogContext(this, uberInfo);

            /*
             *  The only case where 'o' is not null is when this method is called by evaluate().
             *  Its value is not used, but it is a convention meant to allow statements like
             *  #if($invalidReference) *not* to trigger an invalid reference event.
             *  Statements like #if($invalidReference.prop) should *still* trigger an invalid reference event.
             *  Statements like #if($validReference.invalidProp) should not.
             */
            boolean onlyTestingReference = (o != null);

            if (referenceType == RUNT)
                return null;

            /*
             *  get the root object from the context
             */

            Object result = getRootVariableValue(context);

            /* a reference which has been provided an alternate value
             * is *knowingly* potentially null and should be accepted
             * in strict mode (except if the alternate value is null)
             */
            if (astAlternateValue != null && (result == null || !DuckType.asBoolean(result, false)))
            {
                result = astAlternateValue.value(context);
            }

            if (result == null && !strictRef)
            {
                /*
                 * do not trigger an invalid reference if the reference is present, but with a null value
                 * don't either for a quiet reference or inside an #if/#elseif evaluation context
                 */
                if ((referenceType != QUIET_REFERENCE || warnInvalidQuietReferences) &&
                    (numChildren > 0 ||
                        (!context.containsKey(rootString) || warnInvalidNullReferences) &&
                            (!onlyTestingReference || warnInvalidTestedReferences)))
                {
                    result = EventHandlerUtil.invalidGetMethod(rsvc, context,
                        "$" + rootString, null, null, uberInfo);
                }

                return result;
            }

            /*
             * Iteratively work 'down' (it's flat...) the reference
             * to get the value, but check to make sure that
             * every result along the path is valid. For example:
             *
             * $hashtable.Customer.Name
             *
             * The $hashtable may be valid, but there is no key
             * 'Customer' in the hashtable so we want to stop
             * when we find a null value and return the null
             * so the error gets logged.
             */

            try
            {
                Object previousResult = result;
                int failedChild = -1;

                for (int i = 0; i < numChildren; i++)
                {
                    if (strictRef && result == null)
                    {
                        /**
                         * At this point we know that an attempt is about to be made
                         * to call a method or property on a null value.
                         */
                        String name = jjtGetChild(i).getFirstTokenImage();
                        throw new VelocityException("Attempted to access '"
                            + name + "' on a null value at "
                            + StringUtils.formatFileString(uberInfo.getTemplateName(),
                            + jjtGetChild(i).getLine(), jjtGetChild(i).getColumn()));
                    }
                    previousResult = result;
                    result = jjtGetChild(i).execute(result,context);
                    if (astAlternateValue != null && (result == null || !DuckType.asBoolean(result, checkEmpty)))
                    {
                        result = astAlternateValue.value(context);
                    }
                    if (result == null && !strictRef)  // If strict and null then well catch this
                                                       // next time through the loop
                    {
                        failedChild = i;
                        break;
                    }
                }

                if (result == null)
                {
                    if (failedChild == -1)
                    {
                        /*
                         * do not trigger an invalid reference if the reference is present, but with a null value
                         * don't either for a quiet reference,
                         * or inside an #if/#elseif evaluation context when there's no child
                         */
                        if ((!context.containsKey(rootString) || warnInvalidNullReferences) &&
                            (referenceType != QUIET_REFERENCE || warnInvalidQuietReferences) &&
                            (!onlyTestingReference || warnInvalidTestedReferences || numChildren > 0))
                        {
                            result = EventHandlerUtil.invalidGetMethod(rsvc, context,
                                    "$" + rootString, previousResult, null, uberInfo);
                        }
                    }
                    else
                    {
                        Node child = jjtGetChild(failedChild);
                        // do not call bad reference handler if the getter is present
                        // (it means the getter has been called and returned null)
                        // do not either for a quiet reference or if the *last* child failed while testing the reference
                        Object getter = context.icacheGet(child);
                        if ((getter == null || warnInvalidNullReferences) &&
                            (referenceType != QUIET_REFERENCE || warnInvalidQuietReferences) &&
                            (!onlyTestingReference || warnInvalidTestedReferences || failedChild < numChildren - 1))
                        {
                            StringBuilder name = new StringBuilder("$").append(rootString);
                            for (int i = 0; i <= failedChild; i++)
                            {
                                Node node = jjtGetChild(i);
                                if (node instanceof ASTMethod)
                                {
                                    name.append(".").append(((ASTMethod) node).getMethodName()).append("()");
                                }
                                else
                                {
                                    name.append(".").append(node.getFirstTokenImage());
                                }
                            }

                            if (child instanceof ASTMethod)
                            {
                                String methodName = ((ASTMethod) jjtGetChild(failedChild)).getMethodName();
                                result = EventHandlerUtil.invalidMethod(rsvc, context,
                                    name.toString(), previousResult, methodName, uberInfo);
                            }
                            else
                            {
                                String property = jjtGetChild(failedChild).getFirstTokenImage();
                                result = EventHandlerUtil.invalidGetMethod(rsvc, context,
                                    name.toString(), previousResult, property, uberInfo);
                            }
                        }
                    }
                }

                return result;
            }
            catch(MethodInvocationException mie)
            {
                mie.setReferenceName(rootString);
                throw mie;
            }
        }
        finally
        {
            rsvc.getLogContext().popLogContext();
        }
    }

    /**
     *  gets the value of the reference and outputs it to the
     *  writer.
     *
     *  @param context  context of data to use in getting value
     *  @param writer   writer to render to
     * @return True if rendering was successful.
     * @throws IOException
     * @throws MethodInvocationException
     */
    public boolean render(InternalContextAdapter context, Writer writer) throws IOException,
            MethodInvocationException
    {
        try
        {
            rsvc.getLogContext().pushLogContext(this, uberInfo);

            if (referenceType == RUNT)
            {
                writer.write(literal);
                return true;
            }

            Object value = null;
            if (escaped && strictEscape)
            {
              /**
               * If we are in strict mode and the variable is escaped, then don't bother to
               * retrieve the value since we won't use it. And if the var is not defined
               * it will throw an exception.  Set value to TRUE to fall through below with
               * simply printing $foo, and not \$foo
               */
              value = Boolean.TRUE;
            }
            else
            {
              value = execute(null, context);
            }

            String localNullString = null;

            /*
             * if this reference is escaped (\$foo) then we want to do one of two things: 1) if this is
             * a reference in the context, then we want to print $foo 2) if not, then \$foo (its
             * considered schmoo, not VTL)
             */

            if (escaped)
            {
                localNullString = getNullString(context);

                if (value == null)
                {
                    writer.write(escPrefix);
                    writer.write("\\");
                    writer.write(localNullString);
                }
                else
                {
                    writer.write(escPrefix);
                    writer.write(localNullString);
                }
                return true;
            }

            /*
             * the normal processing
             *
             * if we have an event cartridge, get a new value object
             */

            value = EventHandlerUtil.referenceInsert(rsvc, context, literal, value);

            String toString = null;
            if (value != null)
            {
                if (value instanceof Renderable)
                {
                    Renderable renderable = (Renderable)value;
                    try
                    {
                        writer.write(escPrefix);
                        writer.write(morePrefix);
                        if (renderable.render(context,writer))
                        {
                          return true;
                        }
                    }
                    catch(RuntimeException e)
                    {
                        // We commonly get here when an error occurs within a block reference.
                        // We want to log where the reference is at so that a developer can easily
                        // know where the offending call is located.  This can be seen
                        // as another element of the error stack we report to log.
                        log.error("Exception rendering "
                            + ((renderable instanceof Reference)? "block ":"Renderable ")
                            + rootString + " at " + StringUtils.formatFileString(this));
                        throw e;
                    }
                }

                toString = DuckType.asString(value);
            }

            if (value == null || toString == null)
            {
                if (strictRef)
                {
                    if (referenceType != QUIET_REFERENCE)
                    {
                      log.error("Prepend the reference with '$!' e.g., $!{}" +
                                " if you want Velocity to ignore the reference when it evaluates to null",
                                literal().substring(1));
                      if (value == null)
                      {
                        throw new VelocityException("Reference " + literal()
                            + " evaluated to null when attempting to render at "
                            + StringUtils.formatFileString(this));
                      }
                      else  // toString == null
                      {
                        // This will probably rarely happen, but when it does we want to
                        // inform the user that toString == null so they don't pull there
                        // hair out wondering why Velocity thinks the value is null.
                        throw new VelocityException("Reference " + literal()
                            + " evaluated to object " + value.getClass().getName()
                            + " whose toString() method returned null at "
                            + StringUtils.formatFileString(this));
                      }
                    }
                    return true;
                }

                /*
                 * write prefix twice, because it's schmoo, so the \ don't escape each
                 * other...
                 */
                localNullString = getNullString(context);
                if (!strictEscape)
                {
                    // If in strict escape mode then we only print escape once.
                    // Yea, I know.. brittle stuff
                    writer.write(escPrefix);
                }
                writer.write(escPrefix);
                writer.write(morePrefix);
                writer.write(localNullString);

                if (logOnNull && referenceType != QUIET_REFERENCE)
                {
                    log.debug("Null reference [template '{}', line {}, column {}]: {} cannot be resolved.",
                              getTemplateName(), this.getLine(), this.getColumn(), this.literal());
                }
                return true;
            }
            else
            {
                /*
                 * non-null processing
                 */
                writer.write(escPrefix);
                writer.write(morePrefix);
                if (writer instanceof Filter)
                {
                    ((Filter)writer).writeReference(toString);
                }
                else
                {
                    writer.write(toString);
                }

                return true;
            }
        }
        finally
        {
            rsvc.getLogContext().popLogContext();
        }
    }

    /**
     * This method helps to implement the "render literal if null" functionality.
     *
     * VelocimacroProxy saves references to macro arguments (AST nodes) so that if we have a macro
     * #foobar($a $b) then there is key "$a.literal" which points to the literal presentation of the
     * argument provided to variable $a. If the value of $a is null, we render the string that was
     * provided as the argument.
     *
     * @param context
     * @return
     */
    private String getNullString(InternalContextAdapter context)
    {
        String ret = nullString;

        if (lookupAlternateLiteral)
        {
            Node callingArgument = (Node)context.get(".literal." + nullString);
            if (callingArgument != null)
            {
                ret = ((Node) callingArgument).literal();
            }
        }
        return ret;
    }

    /**
     *   Computes boolean value of this reference
     *   Returns the actual value of reference return type
     *   boolean, and 'true' if value is not null
     *
     *   @param context context to compute value with
     * @return True if evaluation was ok.
     * @throws MethodInvocationException
     */
    public boolean evaluate(InternalContextAdapter context)
        throws MethodInvocationException
    {
        Object value = execute(this, context); // non-null object as first parameter by convention for 'evaluate'
        if (value == null)
        {
            return false;
        }
        try
        {
            rsvc.getLogContext().pushLogContext(this, uberInfo);
            return DuckType.asBoolean(value, checkEmpty);
        }
        catch(Exception e)
        {
            throw new VelocityException("Reference evaluation threw an exception at "
                + StringUtils.formatFileString(this), e);
        }
        finally
        {
            rsvc.getLogContext().popLogContext();
        }
    }

    /**
     * @see org.apache.velocity.runtime.parser.node.SimpleNode#value(org.apache.velocity.context.InternalContextAdapter)
     */
    public Object value(InternalContextAdapter context)
        throws MethodInvocationException
    {
        return (computableReference ? execute(null, context) : null);
    }


    /**
     * Utility class to handle nulls when printing a class type
     * @param clazz
     * @return class name, or the string "null"
     */
    public static String printClass(Class clazz)
    {
      return clazz == null ? "null" : clazz.getName();
    }


    /**
     *  Sets the value of a complex reference (something like $foo.bar)
     *  Currently used by ASTSetReference()
     *
     *  @see ASTSetDirective
     *
     *  @param context context object containing this reference
     *  @param value Object to set as value
     *  @return true if successful, false otherwise
     * @throws MethodInvocationException
     */
    public boolean setValue(InternalContextAdapter context, Object value)
      throws MethodInvocationException
    {
        try
        {
            rsvc.getLogContext().pushLogContext(this, uberInfo);

            if (astAlternateValue != null)
            {
                log.error("reference set cannot have a default value {}",
                    StringUtils.formatFileString(uberInfo));
                return false;
            }

            if (numChildren == 0)
            {
                context.put(rootString, value);
                return true;
            }

            /*
             *  The rootOfIntrospection is the object we will
             *  retrieve from the Context. This is the base
             *  object we will apply reflection to.
             */

            Object result = getRootVariableValue(context);

            if (result == null)
            {
                log.error("reference set is not a valid reference at {}",
                          StringUtils.formatFileString(uberInfo));
                return false;
            }

            /*
             * How many child nodes do we have?
             */

            for (int i = 0; i < numChildren - 1; i++)
            {
                result = jjtGetChild(i).execute(result, context);

                if (result == null)
                {
                    if (strictRef)
                    {
                        String name = jjtGetChild(i+1).getFirstTokenImage();
                        throw new MethodInvocationException("Attempted to access '"
                            + name + "' on a null value", null, name, uberInfo.getTemplateName(),
                            jjtGetChild(i+1).getLine(), jjtGetChild(i+1).getColumn());
                    }

                    log.error("reference set is not a valid reference at {}",
                              StringUtils.formatFileString(uberInfo));
                    return false;
                }
            }

            if (astIndex != null)
            {
                // If astIndex is not null then we are actually setting an index reference,
                // something of the form $foo[1] =, or in general any reference that ends with
                // the brackets.  This means that we need to call a more general method
                // of the form set(Integer, <something>), or put(Object, <something), where
                // the first parameter is the index value and the second is the LHS of the set.

                Object argument = astIndex.jjtGetChild(0).value(context);
                // If negative, turn -1 into (size - 1)
                argument = ASTIndex.adjMinusIndexArg(argument, result, context, astIndex);
                Object [] params = {argument, value};
                Class[] paramClasses = {params[0] == null ? null : params[0].getClass(),
                                        params[1] == null ? null : params[1].getClass()};

                String methodName = "set";
                VelMethod method = ClassUtils.getMethod(methodName, params, paramClasses,
                    result, context, astIndex, false);

                if (method == null)
                {
                    // If we can't find a 'set' method, lets try 'put',  This warrents a little
                    // investigation performance wise... if the user is using the hash
                    // form $foo["blaa"], then it may be expensive to first try and fail on 'set'
                    // then go to 'put'?  The problem is that getMethod will try the cache, then
                    // perform introspection on 'result' for 'set'
                    methodName = "put";
                    method = ClassUtils.getMethod(methodName, params, paramClasses,
                          result, context, astIndex, false);
                }

                if (method == null)
                {
                    // couldn't find set or put method, so bail
                    if (strictRef)
                    {
                        throw new VelocityException(
                            "Found neither a 'set' or 'put' method with param types '("
                            + printClass(paramClasses[0]) + "," + printClass(paramClasses[1])
                            + ")' on class '" + result.getClass().getName()
                            + "' at " + StringUtils.formatFileString(astIndex));
                    }
                    return false;
                }

                try
                {
                    method.invoke(result, params);
                }
                catch(RuntimeException e)
                {
                    // Kludge since invoke throws Exception, pass up Runtimes
                    throw e;
                }
                catch(Exception e)
                {
                    throw new MethodInvocationException(
                      "Exception calling method '"
                      + methodName + "("
                      + printClass(paramClasses[0]) + "," + printClass(paramClasses[1])
                      + ")' in  " + result.getClass(),
                      e.getCause(), identifier, astIndex.getTemplateName(), astIndex.getLine(),
                        astIndex.getColumn());
                }

                return true;
            }


            /*
             *  We support two ways of setting the value in a #set($ref.foo = $value ):
             *  1) ref.setFoo( value )
             *  2) ref,put("foo", value ) to parallel the get() map introspection
             */

            try
            {
                VelPropertySet vs =
                        rsvc.getUberspect().getPropertySet(result, identifier,
                                value, uberInfo);

                if (vs == null)
                {
                    if (strictRef)
                    {
                        throw new MethodInvocationException("Object '" + result.getClass().getName() +
                           "' does not contain property '" + identifier + "'", null, identifier,
                           uberInfo.getTemplateName(), uberInfo.getLine(), uberInfo.getColumn());
                    }
                    else
                    {
                      return false;
                    }
                }

                vs.invoke(result, value);
            }
            catch(InvocationTargetException ite)
            {
                /*
                 *  this is possible
                 */

                throw  new MethodInvocationException(
                    "ASTReference: Invocation of method '"
                    + identifier + "' in  " + result.getClass()
                    + " threw exception "
                    + ite.getTargetException().toString(),
                   ite.getTargetException(), identifier, getTemplateName(), this.getLine(), this.getColumn());
            }
            /**
             * pass through application level runtime exceptions
             */
            catch( RuntimeException e )
            {
                throw e;
            }
            catch(Exception e)
            {
                /*
                 *  maybe a security exception?
                 */
                String msg = "ASTReference setValue(): exception: " + e
                              + " template at " + StringUtils.formatFileString(uberInfo);
                log.error(msg, e);
                throw new VelocityException(msg, e);
            }

            return true;
        }
        finally
        {
            rsvc.getLogContext().popLogContext();
        }
    }

    private String getRoot()
    {
        Token t = getFirstToken();

        /*
         *  we have a special case where something like
         *  $(\\)*!, where the user want's to see something
         *  like $!blargh in the output, but the ! prevents it from showing.
         *  I think that at this point, this isn't a reference.
         */

        /* so, see if we have "\\!" */

        int slashbang = t.image.indexOf("\\!");

        if (slashbang != -1)
        {
            if (strictEscape)
            {
                // If we are in strict escape mode, then we consider this type of
                // pattern a non-reference, and we print it out as schmoo...
                nullString = literal();
                escaped = true;
                return nullString;
            }

            /*
             *  lets do all the work here.  I would argue that if this occurs,
             *  it's not a reference at all, so preceding \ characters in front
             *  of the $ are just schmoo.  So we just do the escape processing
             *  trick (even | odd) and move on.  This kind of breaks the rule
             *  pattern of $ and # but '!' really tosses a wrench into things.
             */

             /*
              *  count the escapes: even # -> not escaped, odd -> escaped
              */

            int i = 0;
            int len = t.image.length();

            i = t.image.indexOf('$');

            if (i == -1)
            {
                /* yikes! */
                log.error("ASTReference.getRoot(): internal error: "
                            + "no $ found for slashbang.");
                computableReference = false;
                nullString = t.image;
                return nullString;
            }

            while (i < len && t.image.charAt(i) != '\\')
            {
                i++;
            }

            /*  ok, i is the first \ char */

            int start = i;
            int count = 0;

            while (i < len && t.image.charAt(i++) == '\\')
            {
                count++;
            }

            /*
             *  now construct the output string.  We really don't care about
             *  leading  slashes as this is not a reference.  It's quasi-schmoo
             */

            nullString = t.image.substring(0,start); // prefix up to the first
            nullString += t.image.substring(start, start + count-1 ); // get the slashes
            nullString += t.image.substring(start+count); // and the rest, including the

            /*
             *  this isn't a valid reference, so lets short circuit the value
             *  and set calcs
             */

            computableReference = false;

            return nullString;
        }

        /*
         *  we need to see if this reference is escaped.  if so
         *  we will clean off the leading \'s and let the
         *  regular behavior determine if we should output this
         *  as \$foo or $foo later on in render(). Laziness..
         */

        escaped = false;

        if (t.image.startsWith("\\"))
        {
            /*
             *  count the escapes: even # -> not escaped, odd -> escaped
             */

            int i = 0;
            int len = t.image.length();

            while (i < len && t.image.charAt(i) == '\\')
            {
                i++;
            }

            if ((i % 2) != 0)
                escaped = true;

            if (i > 0)
                escPrefix = t.image.substring(0, i / 2 );

            t.image = t.image.substring(i);
        }

        /*
         *  Look for preceding stuff like '#' and '$'
         *  and snip it off, except for the
         *  last $
         */

        int loc1 = t.image.lastIndexOf('$');

        /*
         *  if we have extra stuff, loc > 0
         *  ex. '#$foo' so attach that to
         *  the prefix.
         */
        if (loc1 > 0)
        {
            morePrefix = morePrefix + t.image.substring(0, loc1);
            t.image = t.image.substring(loc1);
        }

        /*
         *  Now it should be clean. Get the literal in case this reference
         *  isn't backed by the context at runtime, and then figure out what
         *  we are working with.
         */

        // FIXME: this is the key to render nulls as literals, we need to look at context(refname+".literal")
        nullString = literal();

        if (t.image.startsWith("$!"))
        {
            referenceType = QUIET_REFERENCE;

            /*
             *  only if we aren't escaped do we want to null the output
             */

            if (!escaped)
                nullString = "";

            if (t.image.startsWith("$!{"))
            {
                /*
                 *  ex: $!{provider.Title}
                 */

                return t.next.image;
            }
            else
            {
                /*
                 *  ex: $!provider.Title
                 */

                return t.image.substring(2);
            }
        }
        else if (t.image.equals("${"))
        {
            /*
             *  ex: ${provider.Title}
             */

            referenceType = FORMAL_REFERENCE;
            return t.next.image;
        }
        else if (t.image.startsWith("$"))
        {
            /*
             *  just nip off the '$' so we have
             *  the root
             */

            referenceType = NORMAL_REFERENCE;
            return t.image.substring(1);
        }
        else
        {
            /*
             * this is a 'RUNT', which can happen in certain circumstances where
             *  the parser is fooled into believing that an IDENTIFIER is a real
             *  reference.  Another 'dreaded' MORE hack :).
             */
            referenceType = RUNT;
            return t.image;
        }

    }

    /**
     * @param context
     * @return The evaluated value of the variable.
     * @throws MethodInvocationException
     */
    public Object getRootVariableValue(InternalContextAdapter context)
    {
        Object obj = null;
        try
        {
            obj = context.get(rootString);
        }
        catch(RuntimeException e)
        {
            log.error("Exception calling reference ${} at {}",
                      rootString, StringUtils.formatFileString(uberInfo));
            throw e;
        }

        if (obj == null && strictRef && astAlternateValue == null)
        {
          if (!context.containsKey(rootString))
          {
              log.error("Variable ${} has not been set at {}",
                        rootString, StringUtils.formatFileString(uberInfo));
              throw new MethodInvocationException("Variable $" + rootString +
                  " has not been set", null, identifier,
                  uberInfo.getTemplateName(), uberInfo.getLine(), uberInfo.getColumn());
          }
        }
        return obj;
    }
}
