package org.apache.velocity.runtime;

/*
 * 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 java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.Writer;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.collections.ExtendedProperties;
import org.apache.commons.lang.text.StrBuilder;
import org.apache.velocity.Template;
import org.apache.velocity.app.event.EventCartridge;
import org.apache.velocity.app.event.EventHandler;
import org.apache.velocity.app.event.IncludeEventHandler;
import org.apache.velocity.app.event.InvalidReferenceEventHandler;
import org.apache.velocity.app.event.MethodExceptionEventHandler;
import org.apache.velocity.app.event.NullSetEventHandler;
import org.apache.velocity.app.event.ReferenceInsertionEventHandler;
import org.apache.velocity.context.Context;
import org.apache.velocity.context.InternalContextAdapterImpl;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.exception.TemplateInitException;
import org.apache.velocity.exception.VelocityException;
import org.apache.velocity.runtime.directive.Directive;
import org.apache.velocity.runtime.log.Log;
import org.apache.velocity.runtime.log.LogManager;
import org.apache.velocity.runtime.parser.ParseException;
import org.apache.velocity.runtime.parser.Parser;
import org.apache.velocity.runtime.parser.node.Node;
import org.apache.velocity.runtime.parser.node.SimpleNode;
import org.apache.velocity.runtime.resource.ContentResource;
import org.apache.velocity.runtime.resource.ResourceManager;
import org.apache.velocity.util.ClassUtils;
import org.apache.velocity.util.RuntimeServicesAware;
import org.apache.velocity.util.StringUtils;
import org.apache.velocity.util.introspection.Introspector;
import org.apache.velocity.util.introspection.Uberspect;
import org.apache.velocity.util.introspection.UberspectLoggable;
import org.apache.velocity.util.introspection.ChainableUberspector;
import org.apache.velocity.util.introspection.LinkingUberspector;

/**
 * This is the Runtime system for Velocity. It is the
 * single access point for all functionality in Velocity.
 * It adheres to the mediator pattern and is the only
 * structure that developers need to be familiar with
 * in order to get Velocity to perform.
 *
 * The Runtime will also cooperate with external
 * systems like Turbine. Runtime properties can
 * set and then the Runtime is initialized.
 *
 * Turbine, for example, knows where the templates
 * are to be loaded from, and where the Velocity
 * log file should be placed.
 *
 * So in the case of Velocity cooperating with Turbine
 * the code might look something like the following:
 *
 * <blockquote><code><pre>
 * ri.setProperty(Runtime.FILE_RESOURCE_LOADER_PATH, templatePath);
 * ri.setProperty(Runtime.RUNTIME_LOG, pathToVelocityLog);
 * ri.init();
 * </pre></code></blockquote>
 *
 * <pre>
 * -----------------------------------------------------------------------
 * N O T E S  O N  R U N T I M E  I N I T I A L I Z A T I O N
 * -----------------------------------------------------------------------
 * init()
 *
 * If init() is called by itself the RuntimeInstance will initialize
 * with a set of default values.
 * -----------------------------------------------------------------------
 * init(String/Properties)
 *
 * In this case the default velocity properties are layed down
 * first to provide a solid base, then any properties provided
 * in the given properties object will override the corresponding
 * default property.
 * -----------------------------------------------------------------------
 * </pre>
 *
 * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
 * @author <a href="mailto:jlb@houseofdistraction.com">Jeff Bowden</a>
 * @author <a href="mailto:geirm@optonline.net">Geir Magusson Jr.</a>
 * @version $Id$
 */
public class RuntimeInstance implements RuntimeConstants, RuntimeServices
{
    /**
     *  VelocimacroFactory object to manage VMs
     */
    private  VelocimacroFactory vmFactory = null;

    /**
     * The Runtime logger.  We start with an instance of
     * a 'primordial logger', which just collects log messages
     * then, when the log system is initialized, all the
     * messages get dumpted out of the primordial one into the real one.
     */
    private Log log = new Log();

    /**
     * The Runtime parser pool
     */
    private  ParserPool parserPool;

    /**
     * Indicate whether the Runtime is in the midst of initialization.
     */
    private boolean initializing = false;

    /**
     * Indicate whether the Runtime has been fully initialized.
     */
    private boolean initialized = false;

    /**
     * These are the properties that are laid down over top
     * of the default properties when requested.
     */
    private  ExtendedProperties overridingProperties = null;

    /**
     * This is a hashtable of initialized directives.
     * The directives that populate this hashtable are
     * taken from the RUNTIME_DEFAULT_DIRECTIVES
     * property file. This hashtable is passed
     * to each parser that is created.
     */
    private Hashtable runtimeDirectives;

    /**
     * Object that houses the configuration options for
     * the velocity runtime. The ExtendedProperties object allows
     * the convenient retrieval of a subset of properties.
     * For example all the properties for a resource loader
     * can be retrieved from the main ExtendedProperties object
     * using something like the following:
     *
     * ExtendedProperties loaderConfiguration =
     *         configuration.subset(loaderID);
     *
     * And a configuration is a lot more convenient to deal
     * with then conventional properties objects, or Maps.
     */
    private  ExtendedProperties configuration = new ExtendedProperties();

    private ResourceManager resourceManager = null;

    /**
     * This stores the engine-wide set of event handlers.  Event handlers for
     * each specific merge are stored in the context.
     */
    private EventCartridge eventCartridge = null;

    /*
     *  Each runtime instance has it's own introspector
     *  to ensure that each instance is completely separate.
     */
    private Introspector introspector = null;


    /*
     *  Opaque reference to something specificed by the
     *  application for use in application supplied/specified
     *  pluggable components
     */
    private Map applicationAttributes = null;
    private Uberspect uberSpect;
    private String encoding;

    /**
     * Creates a new RuntimeInstance object.
     */
    public RuntimeInstance()
    {
        /*
         *  create a VM factory, introspector, and application attributes
         */
        vmFactory = new VelocimacroFactory( this );

        /*
         *  make a new introspector and initialize it
         */
        introspector = new Introspector(getLog());

        /*
         * and a store for the application attributes
         */
        applicationAttributes = new HashMap();
    }

    /**
     * This is the primary initialization method in the Velocity
     * Runtime. The systems that are setup/initialized here are
     * as follows:
     *
     * <ul>
     *   <li>Logging System</li>
     *   <li>ResourceManager</li>
     *   <li>EventHandler</li>
     *   <li>Parser Pool</li>
     *   <li>Global Cache</li>
     *   <li>Static Content Include System</li>
     *   <li>Velocimacro System</li>
     * </ul>
     * @throws Exception When an error occured during initialization.
     */
    public synchronized void init()
        throws Exception
    {
        if (!initialized && !initializing)
        {
            initializing = true;

            log.trace("*******************************************************************");
            log.debug("Starting Apache Velocity v@build.version@ (compiled: @build.time@)");
            log.trace("RuntimeInstance initializing.");

            initializeProperties();
            initializeLog();
            initializeResourceManager();
            initializeDirectives();
            initializeEventHandlers();
            initializeParserPool();

            initializeIntrospection();
            /*
             *  initialize the VM Factory.  It will use the properties
             * accessable from Runtime, so keep this here at the end.
             */
            vmFactory.initVelocimacro();

            log.trace("RuntimeInstance successfully initialized.");

            initialized = true;
            initializing = false;
        }
    }

    /**
     * Returns true if the RuntimeInstance has been successfully initialized.
     * @return True if the RuntimeInstance has been successfully initialized.
     * @since 1.5
     */
    public boolean isInitialized()
    {
        return initialized;
    }

    /**
     * Init or die! (with some log help, of course)
     */
    private void requireInitialization()
    {
        if (!initialized && !initializing)
        {
            log.debug("Velocity was not initialized! Calling init()...");
            try
            {
                init();
            }
            catch (Exception e)
            {
                getLog().error("Could not auto-initialize Velocity", e);
                throw new RuntimeException("Velocity could not be initialized!", e);
            }
        }
    }

    /**
     *  Gets the classname for the Uberspect introspection package and
     *  instantiates an instance.
     */
    private void initializeIntrospection()
        throws Exception
    {
        String[] uberspectors = configuration.getStringArray(RuntimeConstants.UBERSPECT_CLASSNAME);
        for (int i=0; i <uberspectors.length;i++)
        {
            String rm = uberspectors[i];
            Object o = null;

            try
            {
               o = ClassUtils.getNewInstance( rm );
            }
            catch (ClassNotFoundException cnfe)
            {
                String err = "The specified class for Uberspect (" + rm
                    + ") does not exist or is not accessible to the current classloader.";
                log.error(err);
                throw new Exception(err);
            }

            if (!(o instanceof Uberspect))
            {
                String err = "The specified class for Uberspect ("
                    + rm + ") does not implement " + Uberspect.class.getName()
                    + "; Velocity is not initialized correctly.";

                log.error(err);
                throw new Exception(err);
            }

            Uberspect u = (Uberspect)o;

            if (u instanceof UberspectLoggable)
            {
                ((UberspectLoggable)u).setLog(getLog());
            }

            if (u instanceof RuntimeServicesAware)
            {
                ((RuntimeServicesAware)u).setRuntimeServices(this);
            }

            if (uberSpect == null)
            {
                uberSpect = u;
            }
            else
            {
                if (u instanceof ChainableUberspector)
                {
                    ((ChainableUberspector)u).wrap(uberSpect);
                    uberSpect = u;
                }
                else
                {
                    uberSpect = new LinkingUberspector(uberSpect,u);
                }
            }
        }

        if(uberSpect != null)
        {
            uberSpect.init();
        }
        else
        {
           /*
            *  someone screwed up.  Lets not fool around...
            */

           String err = "It appears that no class was specified as the"
           + " Uberspect.  Please ensure that all configuration"
           + " information is correct.";

           log.error(err);
           throw new Exception(err);
        }
    }

    /**
     * Initializes the Velocity Runtime with properties file.
     * The properties file may be in the file system proper,
     * or the properties file may be in the classpath.
     */
    private void setDefaultProperties()
    {
        InputStream inputStream = null;
        try
        {
            inputStream = getClass()
                .getResourceAsStream('/' + DEFAULT_RUNTIME_PROPERTIES);

            configuration.load( inputStream );

            if (log.isDebugEnabled())
            {
                log.debug("Default Properties File: " +
                    new File(DEFAULT_RUNTIME_PROPERTIES).getPath());
            }


        }
        catch (IOException ioe)
        {
            String msg = "Cannot get Velocity Runtime default properties!";
            log.error(msg, ioe);
            throw new RuntimeException(msg, ioe);
        }
        finally
        {
            try
            {
                if (inputStream != null)
                {
                    inputStream.close();
                }
            }
            catch (IOException ioe)
            {
                String msg = "Cannot close Velocity Runtime default properties!";
                log.error(msg, ioe);
                throw new RuntimeException(msg, ioe);
            }
        }
    }

    /**
     * Allows an external system to set a property in
     * the Velocity Runtime.
     *
     * @param key property key
     * @param  value property value
     */
    public void setProperty(String key, Object value)
    {
        if (overridingProperties == null)
        {
            overridingProperties = new ExtendedProperties();
        }

        overridingProperties.setProperty(key, value);
    }

    /**
     * Allow an external system to set an ExtendedProperties
     * object to use. This is useful where the external
     * system also uses the ExtendedProperties class and
     * the velocity configuration is a subset of
     * parent application's configuration. This is
     * the case with Turbine.
     *
     * @param  configuration
     */
    public void setConfiguration( ExtendedProperties configuration)
    {
        if (overridingProperties == null)
        {
            overridingProperties = configuration;
        }
        else
        {
            // Avoid possible ConcurrentModificationException
            if (overridingProperties != configuration)
            {
                overridingProperties.combine(configuration);
            }
        }
    }

    /**
     * Add a property to the configuration. If it already
     * exists then the value stated here will be added
     * to the configuration entry. For example, if
     *
     * resource.loader = file
     *
     * is already present in the configuration and you
     *
     * addProperty("resource.loader", "classpath")
     *
     * Then you will end up with a Vector like the
     * following:
     *
     * ["file", "classpath"]
     *
     * @param  key
     * @param  value
     */
    public void addProperty(String key, Object value)
    {
        if (overridingProperties == null)
        {
            overridingProperties = new ExtendedProperties();
        }

        overridingProperties.addProperty(key, value);
    }

    /**
     * Clear the values pertaining to a particular
     * property.
     *
     * @param key of property to clear
     */
    public void clearProperty(String key)
    {
        if (overridingProperties != null)
        {
            overridingProperties.clearProperty(key);
        }
    }

    /**
     *  Allows an external caller to get a property.  The calling
     *  routine is required to know the type, as this routine
     *  will return an Object, as that is what properties can be.
     *
     *  @param key property to return
     *  @return Value of the property or null if it does not exist.
     */
    public Object getProperty(String key)
    {
        Object o = null;
        
        /**
         * Before initialization, check the user-entered properties first.
         */
        if (!initialized && !initializing && overridingProperties != null) 
        {
            o = overridingProperties.get(key);
        }
        
        /**
         * After initialization, configuration will hold all properties.
         */
        if (o == null) 
        {
            o = configuration.getProperty(key);
        }
        if (o instanceof String)
        {
            return StringUtils.nullTrim((String) o);
        }
        else
        {
            return o;
        }
    }

    /**
     * Initialize Velocity properties, if the default
     * properties have not been laid down first then
     * do so. Then proceed to process any overriding
     * properties. Laying down the default properties
     * gives a much greater chance of having a
     * working system.
     */
    private void initializeProperties()
    {
        /*
         * Always lay down the default properties first as
         * to provide a solid base.
         */
        if (configuration.isInitialized() == false)
        {
            setDefaultProperties();
        }

        if( overridingProperties != null)
        {
            configuration.combine(overridingProperties);
        }
    }

    /**
     * Initialize the Velocity Runtime with a Properties
     * object.
     *
     * @param p
     * @throws Exception When an error occurs during initialization.
     */
    public void init(Properties p) throws Exception
    {
        setProperties(ExtendedProperties.convertProperties(p));
        init();
    }

    private void setProperties(ExtendedProperties p)
    {
        if (overridingProperties == null)
        {
            overridingProperties = p;
        }
        else
        {
            overridingProperties.combine(p);
        }
    }

    /**
     * Initialize the Velocity Runtime with the name of
     * ExtendedProperties object.
     *
     * @param configurationFile
     * @throws Exception When an error occurs during initialization.
     */
    public void init(String configurationFile)
        throws Exception
    {
        setProperties(new ExtendedProperties(configurationFile));
        init();
    }

    private void initializeResourceManager()
        throws Exception
    {
        /*
         * Which resource manager?
         */

        String rm = getString(RuntimeConstants.RESOURCE_MANAGER_CLASS);

        if (rm != null && rm.length() > 0)
        {
            /*
             *  if something was specified, then make one.
             *  if that isn't a ResourceManager, consider
             *  this a huge error and throw
             */

            Object o = null;

            try
            {
               o = ClassUtils.getNewInstance( rm );
            }
            catch (ClassNotFoundException cnfe )
            {
                String err = "The specified class for ResourceManager (" + rm
                    + ") does not exist or is not accessible to the current classloader.";
                log.error(err);
                throw new Exception(err);
            }

            if (!(o instanceof ResourceManager))
            {
                String err = "The specified class for ResourceManager (" + rm
                    + ") does not implement " + ResourceManager.class.getName()
                    + "; Velocity is not initialized correctly.";

                log.error(err);
                throw new Exception(err);
            }

            resourceManager = (ResourceManager) o;

            resourceManager.initialize(this);
         }
         else
         {
            /*
             *  someone screwed up.  Lets not fool around...
             */

            String err = "It appears that no class was specified as the"
            + " ResourceManager.  Please ensure that all configuration"
            + " information is correct.";

            log.error(err);
            throw new Exception( err );
        }
    }

    private void initializeEventHandlers()
        throws Exception
    {

        eventCartridge = new EventCartridge();

        /**
         * For each type of event handler, get the class name, instantiate it, and store it.
         */

        String[] referenceinsertion = configuration.getStringArray(RuntimeConstants.EVENTHANDLER_REFERENCEINSERTION);
        if ( referenceinsertion != null )
        {
            for ( int i=0; i < referenceinsertion.length; i++ )
            {
                EventHandler ev = initializeSpecificEventHandler(referenceinsertion[i],RuntimeConstants.EVENTHANDLER_REFERENCEINSERTION,ReferenceInsertionEventHandler.class);
                if (ev != null)
                    eventCartridge.addReferenceInsertionEventHandler((ReferenceInsertionEventHandler) ev);
            }
        }

        String[] nullset = configuration.getStringArray(RuntimeConstants.EVENTHANDLER_NULLSET);
        if ( nullset != null )
        {
            for ( int i=0; i < nullset.length; i++ )
            {
                EventHandler ev = initializeSpecificEventHandler(nullset[i],RuntimeConstants.EVENTHANDLER_NULLSET,NullSetEventHandler.class);
                if (ev != null)
                    eventCartridge.addNullSetEventHandler((NullSetEventHandler) ev);
            }
        }

        String[] methodexception = configuration.getStringArray(RuntimeConstants.EVENTHANDLER_METHODEXCEPTION);
        if ( methodexception != null )
        {
            for ( int i=0; i < methodexception.length; i++ )
            {
                EventHandler ev = initializeSpecificEventHandler(methodexception[i],RuntimeConstants.EVENTHANDLER_METHODEXCEPTION,MethodExceptionEventHandler.class);
                if (ev != null)
                    eventCartridge.addMethodExceptionHandler((MethodExceptionEventHandler) ev);
            }
        }

        String[] includeHandler = configuration.getStringArray(RuntimeConstants.EVENTHANDLER_INCLUDE);
        if ( includeHandler != null )
        {
            for ( int i=0; i < includeHandler.length; i++ )
            {
                EventHandler ev = initializeSpecificEventHandler(includeHandler[i],RuntimeConstants.EVENTHANDLER_INCLUDE,IncludeEventHandler.class);
                if (ev != null)
                    eventCartridge.addIncludeEventHandler((IncludeEventHandler) ev);
            }
        }

        String[] invalidReferenceSet = configuration.getStringArray(RuntimeConstants.EVENTHANDLER_INVALIDREFERENCES);
        if ( invalidReferenceSet != null )
        {
            for ( int i=0; i < invalidReferenceSet.length; i++ )
            {
                EventHandler ev = initializeSpecificEventHandler(invalidReferenceSet[i],RuntimeConstants.EVENTHANDLER_INVALIDREFERENCES,InvalidReferenceEventHandler.class);
                if (ev != null)
                {
                    eventCartridge.addInvalidReferenceEventHandler((InvalidReferenceEventHandler) ev);
                }
            }
        }


    }

    private EventHandler initializeSpecificEventHandler(String classname, String paramName, Class EventHandlerInterface)
        throws Exception
    {
        if ( classname != null && classname.length() > 0)
        {
            Object o = null;
            try {
                o = ClassUtils.getNewInstance(classname);
            }
            catch (ClassNotFoundException cnfe )
            {
                String err = "The specified class for "
                    + paramName + " (" + classname
                    + ") does not exist or is not accessible to the current classloader.";
                log.error(err);
                throw new Exception(err);
            }

            if (!EventHandlerInterface.isAssignableFrom(EventHandlerInterface))
            {
                String err = "The specified class for " + paramName + " ("
                    + classname + ") does not implement "
                    + EventHandlerInterface.getName()
                    + "; Velocity is not initialized correctly.";

                log.error(err);
                throw new Exception(err);
            }

            EventHandler ev = (EventHandler) o;
            if ( ev instanceof RuntimeServicesAware )
                ((RuntimeServicesAware) ev).setRuntimeServices(this);
            return ev;

        } else
            return null;
    }

    /**
     * Initialize the Velocity logging system.
     *
     * @throws Exception
     */
    private void initializeLog() throws Exception
    {
        // since the Log we started with was just placeholding,
        // let's update it with the real LogChute settings.
        LogManager.updateLog(this.log, this);
    }


    /**
     * This methods initializes all the directives
     * that are used by the Velocity Runtime. The
     * directives to be initialized are listed in
     * the RUNTIME_DEFAULT_DIRECTIVES properties
     * file.
     *
     * @throws Exception
     */
    private void initializeDirectives()
        throws Exception
    {
        /*
         * Initialize the runtime directive table.
         * This will be used for creating parsers.
         */
        runtimeDirectives = new Hashtable();

        Properties directiveProperties = new Properties();

        /*
         * Grab the properties file with the list of directives
         * that we should initialize.
         */

        InputStream inputStream = null;

        try
        {
            inputStream = getClass().getResourceAsStream('/' + DEFAULT_RUNTIME_DIRECTIVES);

            if (inputStream == null)
            {
                throw new Exception("Error loading directive.properties! " +
                                    "Something is very wrong if these properties " +
                                    "aren't being located. Either your Velocity " +
                                    "distribution is incomplete or your Velocity " +
                                    "jar file is corrupted!");
            }

            directiveProperties.load(inputStream);

        }
        catch (IOException ioe)
        {
            String msg = "Error while loading directive properties!";
            log.error(msg, ioe);
            throw new RuntimeException(msg, ioe);
        }
        finally
        {
            try
            {
                if (inputStream != null)
                {
                    inputStream.close();
                }
            }
            catch (IOException ioe)
            {
                String msg = "Cannot close directive properties!";
                log.error(msg, ioe);
                throw new RuntimeException(msg, ioe);
            }
        }


        /*
         * Grab all the values of the properties. These
         * are all class names for example:
         *
         * org.apache.velocity.runtime.directive.Foreach
         */
        Enumeration directiveClasses = directiveProperties.elements();

        while (directiveClasses.hasMoreElements())
        {
            String directiveClass = (String) directiveClasses.nextElement();
            loadDirective(directiveClass);
            log.debug("Loaded System Directive: " + directiveClass);
        }

        /*
         *  now the user's directives
         */

        String[] userdirective = configuration.getStringArray("userdirective");

        for( int i = 0; i < userdirective.length; i++)
        {
            loadDirective(userdirective[i]);
            if (log.isDebugEnabled())
            {
                log.debug("Loaded User Directive: " + userdirective[i]);
            }
        }

    }

    /**
     * Programatically add a directive.
     * @param directive
     */
    public void addDirective(Directive directive) 
    {
        runtimeDirectives.put(directive.getName(), directive);
    }

    /**
     * Retrieve a previously instantiated directive.
     * @param name name of the directive
     * @return the {@link Directive} for that name
     */
    public Directive getDirective(String name) 
    {
        return (Directive) runtimeDirectives.get(name);
    }

    /**
     * Remove a directive.
     * @param name name of the directive.
     */
    public void removeDirective(String name) 
    {
        runtimeDirectives.remove(name);
    }

    /**
     *  instantiates and loads the directive with some basic checks
     *
     *  @param directiveClass classname of directive to load
     */
    private void loadDirective(String directiveClass)
    {
        try
        {
            Object o = ClassUtils.getNewInstance( directiveClass );

            if (o instanceof Directive)
            {
                Directive directive = (Directive) o;
                addDirective(directive);
            }
            else
            {
                String msg = directiveClass + " does not implement "
                    + Directive.class.getName() + "; it cannot be loaded.";
                log.error(msg);
                throw new VelocityException(msg);
            }
        }
        // The ugly threesome:  ClassNotFoundException,
        // IllegalAccessException, InstantiationException.
        // Ignore Findbugs complaint for now.
        catch (Exception e)
        {
            String msg = "Failed to load Directive: " + directiveClass;
            log.error(msg, e);
            throw new VelocityException(msg, e);
        }
    }


    /**
     * Initializes the Velocity parser pool.
     */
    private void initializeParserPool() throws Exception
    {
        /*
         * Which parser pool?
         */
        String pp = getString(RuntimeConstants.PARSER_POOL_CLASS);

        if (pp != null && pp.length() > 0)
        {
            /*
             *  if something was specified, then make one.
             *  if that isn't a ParserPool, consider
             *  this a huge error and throw
             */

            Object o = null;

            try
            {
                o = ClassUtils.getNewInstance( pp );
            }
            catch (ClassNotFoundException cnfe )
            {
                String err = "The specified class for ParserPool ("
                    + pp
                    + ") does not exist (or is not accessible to the current classloader.";
                log.error(err);
                throw new Exception(err);
            }

            if (!(o instanceof ParserPool))
            {
                String err = "The specified class for ParserPool ("
                    + pp + ") does not implement " + ParserPool.class
                    + " Velocity not initialized correctly.";

                log.error(err);
                throw new Exception(err);
            }

            parserPool = (ParserPool) o;

            parserPool.initialize(this);
        }
        else
        {
            /*
             *  someone screwed up.  Lets not fool around...
             */

            String err = "It appears that no class was specified as the"
                + " ParserPool.  Please ensure that all configuration"
                + " information is correct.";

            log.error(err);
            throw new Exception( err );
        }

    }

    /**
     * Returns a JavaCC generated Parser.
     *
     * @return Parser javacc generated parser
     */
    public Parser createNewParser()
    {
        requireInitialization();

        Parser parser = new Parser(this);
        parser.setDirectives(runtimeDirectives);
        return parser;
    }

    /**
     * Parse the input and return the root of
     * AST node structure.
     * <br><br>
     *  In the event that it runs out of parsers in the
     *  pool, it will create and let them be GC'd
     *  dynamically, logging that it has to do that.  This
     *  is considered an exceptional condition.  It is
     *  expected that the user will set the
     *  PARSER_POOL_SIZE property appropriately for their
     *  application.  We will revisit this.
     *
     * @param string String to be parsed
     * @param templateName name of the template being parsed
     * @return A root node representing the template as an AST tree.
     * @throws ParseException When the string could not be parsed as a template.
     * @since 1.6
     */
    public SimpleNode parse(String string, String templateName)
        throws ParseException
    {
        return parse(new StringReader(string), templateName);
    }

    /**
     * Parse the input and return the root of
     * AST node structure.
     * <br><br>
     *  In the event that it runs out of parsers in the
     *  pool, it will create and let them be GC'd
     *  dynamically, logging that it has to do that.  This
     *  is considered an exceptional condition.  It is
     *  expected that the user will set the
     *  PARSER_POOL_SIZE property appropriately for their
     *  application.  We will revisit this.
     *
     * @param reader Reader retrieved by a resource loader
     * @param templateName name of the template being parsed
     * @return A root node representing the template as an AST tree.
     * @throws ParseException When the template could not be parsed.
     */
    public SimpleNode parse(Reader reader, String templateName)
        throws ParseException
    {
        /*
         *  do it and dump the VM namespace for this template
         */
        return parse(reader, templateName, true);
    }

    /**
     *  Parse the input and return the root of the AST node structure.
     *
     * @param reader Reader retrieved by a resource loader
     * @param templateName name of the template being parsed
     * @param dumpNamespace flag to dump the Velocimacro namespace for this template
     * @return A root node representing the template as an AST tree.
     * @throws ParseException When the template could not be parsed.
     */
    public SimpleNode parse(Reader reader, String templateName, boolean dumpNamespace)
        throws ParseException
    {
        requireInitialization();

        Parser parser = (Parser) parserPool.get();
        boolean keepParser = true;
        if (parser == null)
        {
            /*
             *  if we couldn't get a parser from the pool make one and log it.
             */
            if (log.isInfoEnabled())
            {
                log.info("Runtime : ran out of parsers. Creating a new one. "
                      + " Please increment the parser.pool.size property."
                      + " The current value is too small.");
            }
            parser = createNewParser();
            keepParser = false;
        }

        try
        {
            /*
             *  dump namespace if we are told to.  Generally, you want to
             *  do this - you don't in special circumstances, such as
             *  when a VM is getting init()-ed & parsed
             */
            if (dumpNamespace)
            {
                dumpVMNamespace(templateName);
            }
            return parser.parse(reader, templateName);
        }
        finally
        {
            if (keepParser)
            {
                parserPool.put(parser);
            }

        }
    }

    /**
     * Renders the input string using the context into the output writer.
     * To be used when a template is dynamically constructed, or want to use
     * Velocity as a token replacer.
     *
     * @param context context to use in rendering input string
     * @param out  Writer in which to render the output
     * @param logTag  string to be used as the template name for log
     *                messages in case of error
     * @param instring input string containing the VTL to be rendered
     *
     * @return true if successful, false otherwise.  If false, see
     *              Velocity runtime log
     * @throws ParseErrorException The template could not be parsed.
     * @throws MethodInvocationException A method on a context object could not be invoked.
     * @throws ResourceNotFoundException A referenced resource could not be loaded.
     * @throws IOException While rendering to the writer, an I/O problem occured.
     * @since Velocity 1.6
     */
    public boolean evaluate(Context context,  Writer out,
                            String logTag, String instring) throws IOException
    {
        return evaluate(context, out, logTag, new StringReader(instring));
    }

    /**
     * Renders the input reader using the context into the output writer.
     * To be used when a template is dynamically constructed, or want to
     * use Velocity as a token replacer.
     *
     * @param context context to use in rendering input string
     * @param writer  Writer in which to render the output
     * @param logTag  string to be used as the template name for log messages
     *                in case of error
     * @param reader Reader containing the VTL to be rendered
     *
     * @return true if successful, false otherwise.  If false, see
     *              Velocity runtime log
     * @throws ParseErrorException The template could not be parsed.
     * @throws MethodInvocationException A method on a context object could not be invoked.
     * @throws ResourceNotFoundException A referenced resource could not be loaded.
     * @throws IOException While reading from the reader or rendering to the writer,
     *                     an I/O problem occured.
     * @since Velocity 1.6
     */
    public boolean evaluate(Context context, Writer writer,
                            String logTag, Reader reader) throws IOException
    {
        if (logTag == null)
        {
            throw new NullPointerException("logTag (i.e. template name) cannot be null, you must provide an identifier for the content being evaluated");
        }

        SimpleNode nodeTree = null;
        try
        {
            nodeTree = parse(reader, logTag);
        }
        catch (ParseException pex)
        {
            throw new ParseErrorException(pex);
        }
        catch (TemplateInitException pex)
        {
            throw new ParseErrorException(pex);
        }

        if (nodeTree == null)
        {
            return false;
        }
        else
        {
            return render(context, writer, logTag, nodeTree);
        }
    }


    /**
     * Initializes and renders the AST {@link SimpleNode} using the context
     * into the output writer.
     *
     * @param context context to use in rendering input string
     * @param writer  Writer in which to render the output
     * @param logTag  string to be used as the template name for log messages
     *                in case of error
     * @param nodeTree SimpleNode which is the root of the AST to be rendered
     *
     * @return true if successful, false otherwise.  If false, see
     *              Velocity runtime log for errors
     * @throws ParseErrorException The template could not be parsed.
     * @throws MethodInvocationException A method on a context object could not be invoked.
     * @throws ResourceNotFoundException A referenced resource could not be loaded.
     * @throws IOException While rendering to the writer, an I/O problem occured.
     * @since Velocity 1.6
     */
    public boolean render(Context context, Writer writer,
                          String logTag, SimpleNode nodeTree) throws IOException
    {
        /*
         * we want to init then render
         */
        InternalContextAdapterImpl ica =
            new InternalContextAdapterImpl(context);

        ica.pushCurrentTemplateName(logTag);

        try
        {
            try
            {
                nodeTree.init(ica, this);
            }
            catch (TemplateInitException pex)
            {
                throw new ParseErrorException(pex);
            }
            /**
             * pass through application level runtime exceptions
             */
            catch(RuntimeException e)
            {
                throw e;
            }
            catch(Exception e)
            {
                String msg = "RuntimeInstance.render(): init exception for tag = "+logTag;
                getLog().error(msg, e);
                throw new VelocityException(msg, e);
            }

            /*
             *  now render, and let any exceptions fly
             */
            nodeTree.render(ica, writer);
        }
        finally
        {
            ica.popCurrentTemplateName();
        }

        return true;
    }

    /**
     * Invokes a currently registered Velocimacro with the params provided
     * and places the rendered stream into the writer.
     * <br>
     * Note : currently only accepts args to the VM if they are in the context.
     *
     * @param vmName name of Velocimacro to call
     * @param logTag string to be used for template name in case of error. if null,
     *               the vmName will be used
     * @param params keys for args used to invoke Velocimacro, in java format
     *               rather than VTL (eg  "foo" or "bar" rather than "$foo" or "$bar")
     * @param context Context object containing data/objects used for rendering.
     * @param writer  Writer for output stream
     * @return true if Velocimacro exists and successfully invoked, false otherwise.
     * @throws IOException While rendering to the writer, an I/O problem occured.
     * @since 1.6
     */
    public boolean invokeVelocimacro(final String vmName, String logTag,
                                     String[] params, final Context context,
                                     final Writer writer)
        throws IOException
    {
        /* check necessary parameters */
        if (vmName == null || context == null || writer == null)
        {
            String msg = "RuntimeInstance.invokeVelocimacro() : invalid call : vmName, context, and writer must not be null";
            getLog().error(msg);
            throw new NullPointerException(msg);
        }

        /* handle easily corrected parameters */
        if (logTag == null)
        {
            logTag = vmName;
        }
        if (params == null)
        {
            params = new String[0];
        }

        /* does the VM exist? */
        if (!isVelocimacro(vmName, logTag))
        {
            String msg = "RuntimeInstance.invokeVelocimacro() : VM '" + vmName
                         + "' is not registered.";
            getLog().error(msg);
            throw new VelocityException(msg);
        }

        /* now just create the VM call, and use evaluate */
        StrBuilder template = new StrBuilder("#");
        template.append(vmName);
        template.append("(");
        for( int i = 0; i < params.length; i++)
        {
            template.append(" $");
            template.append(params[i]);
        }
        template.append(" )");

        return evaluate(context, writer, logTag, template.toString());
    }

    /**
     * Retrieves and caches the configured default encoding
     * for better performance. (VELOCITY-606)
     */
    private String getDefaultEncoding()
    {
        if (encoding == null)
        {
            encoding = getString(INPUT_ENCODING, ENCODING_DEFAULT);
        }
        return encoding;
    }

    /**
     * Returns a <code>Template</code> from the resource manager.
     * This method assumes that the character encoding of the
     * template is set by the <code>input.encoding</code>
     * property.  The default is "ISO-8859-1"
     *
     * @param name The file name of the desired template.
     * @return     The template.
     * @throws ResourceNotFoundException if template not found
     *          from any available source.
     * @throws ParseErrorException if template cannot be parsed due
     *          to syntax (or other) error.
     * @throws Exception if an error occurs in template initialization
     */
    public Template getTemplate(String name)
        throws ResourceNotFoundException, ParseErrorException, Exception
    {
        return getTemplate(name, getDefaultEncoding());
    }

    /**
     * Returns a <code>Template</code> from the resource manager
     *
     * @param name The  name of the desired template.
     * @param encoding Character encoding of the template
     * @return     The template.
     * @throws ResourceNotFoundException if template not found
     *          from any available source.
     * @throws ParseErrorException if template cannot be parsed due
     *          to syntax (or other) error.
     * @throws Exception if an error occurs in template initialization
     */
    public Template getTemplate(String name, String  encoding)
        throws ResourceNotFoundException, ParseErrorException, Exception
    {
        requireInitialization();

        return (Template)
                resourceManager.getResource(name,
                    ResourceManager.RESOURCE_TEMPLATE, encoding);
    }

    /**
     * Returns a static content resource from the
     * resource manager.  Uses the current value
     * if INPUT_ENCODING as the character encoding.
     *
     * @param name Name of content resource to get
     * @return parsed ContentResource object ready for use
     * @throws ResourceNotFoundException if template not found
     *          from any available source.
     * @throws ParseErrorException When the template could not be parsed.
     * @throws Exception Any other error.
     */
    public ContentResource getContent(String name)
        throws ResourceNotFoundException, ParseErrorException, Exception
    {
        /*
         *  the encoding is irrelvant as we don't do any converstion
         *  the bytestream should be dumped to the output stream
         */

        return getContent(name, getDefaultEncoding());
    }

    /**
     * Returns a static content resource from the
     * resource manager.
     *
     * @param name Name of content resource to get
     * @param encoding Character encoding to use
     * @return parsed ContentResource object ready for use
     * @throws ResourceNotFoundException if template not found
     *          from any available source.
     * @throws ParseErrorException When the template could not be parsed.
     * @throws Exception Any other error.
     */
    public ContentResource getContent(String name, String encoding)
        throws ResourceNotFoundException, ParseErrorException, Exception
    {
        requireInitialization();

        return (ContentResource)
                resourceManager.getResource(name,
                        ResourceManager.RESOURCE_CONTENT, encoding);
    }


    /**
     *  Determines if a template exists and returns name of the loader that
     *  provides it.  This is a slightly less hokey way to support
     *  the Velocity.resourceExists() utility method, which was broken
     *  when per-template encoding was introduced.  We can revisit this.
     *
     *  @param resourceName Name of template or content resource
     *  @return class name of loader than can provide it
     */
    public String getLoaderNameForResource(String resourceName)
    {
        requireInitialization();

        return resourceManager.getLoaderNameForResource(resourceName);
    }

    /**
     * Returns a convenient Log instance that wraps the current LogChute.
     * Use this to log error messages. It has the usual methods.
     *
     * @return A convenience Log instance that wraps the current LogChute.
     * @since 1.5
     */
    public Log getLog()
    {
        return log;
    }

    /**
     * @deprecated Use getLog() and call warn() on it.
     * @see Log#warn(Object)
     * @param message The message to log.
     */
    public void warn(Object message)
    {
        getLog().warn(message);
    }

    /**
     * @deprecated Use getLog() and call info() on it.
     * @see Log#info(Object)
     * @param message The message to log.
     */
    public void info(Object message)
    {
        getLog().info(message);
    }

    /**
     * @deprecated Use getLog() and call error() on it.
     * @see Log#error(Object)
     * @param message The message to log.
     */
    public void error(Object message)
    {
        getLog().error(message);
    }

    /**
     * @deprecated Use getLog() and call debug() on it.
     * @see Log#debug(Object)
     * @param message The message to log.
     */
    public void debug(Object message)
    {
        getLog().debug(message);
    }

    /**
     * String property accessor method with default to hide the
     * configuration implementation.
     *
     * @param key property key
     * @param defaultValue  default value to return if key not
     *               found in resource manager.
     * @return value of key or default
     */
    public String getString( String key, String defaultValue)
    {
        return configuration.getString(key, defaultValue);
    }

    /**
     * Returns the appropriate VelocimacroProxy object if vmName
     * is a valid current Velocimacro.
     *
     * @param vmName Name of velocimacro requested
     * @param templateName Name of the template that contains the velocimacro.
     * @return The requested VelocimacroProxy.
     * @since 1.6
     */
    public Directive getVelocimacro(String vmName, String templateName)
    {
        return vmFactory.getVelocimacro( vmName, templateName );
    }

    /**
     * Returns the appropriate VelocimacroProxy object if vmName
     * is a valid current Velocimacro.
     *
     * @param vmName  Name of velocimacro requested
     * @param templateName Name of the namespace.
     * @param renderingTemplate Name of the template we are currently rendering. This
     *    information is needed when VM_PERM_ALLOW_INLINE_REPLACE_GLOBAL setting is true
     *    and template contains a macro with the same name as the global macro library.
     * 
     * @since Velocity 1.6
     * 
     * @return VelocimacroProxy
     */
    public Directive getVelocimacro(String vmName, String templateName, String renderingTemplate)
    {
        return vmFactory.getVelocimacro( vmName, templateName, renderingTemplate );
    }
    
    
   /**
    * Adds a new Velocimacro. Usually called by Macro only while parsing.
    *
    * @param name Name of velocimacro
    * @param macro String form of macro body
    * @param argArray Array of strings, containing the
    *                         #macro() arguments.  the 0th is the name.
    * @param sourceTemplate Name of the template that contains the velocimacro.
    * 
    * @deprecated Use addVelocimacro(String, Node, String[], String) instead
    * 
    * @return True if added, false if rejected for some
    *                  reason (either parameters or permission settings)
    */
    public boolean addVelocimacro( String name,
                                          String macro,
                                          String argArray[],
                                          String sourceTemplate )
    {
        return vmFactory.addVelocimacro(name, macro,  argArray,  sourceTemplate);
    }

    /**
     * Adds a new Velocimacro. Usually called by Macro only while parsing.
     * 
     * Called by org.apache.velocity.runtime.directive.processAndRegister
     *
     * @param name  Name of velocimacro
     * @param macro  root AST node of the parsed macro
     * @param argArray  Array of strings, containing the
     *                         #macro() arguments.  the 0th is the name.
     * @param sourceTemplate
     * 
     * @since Velocity 1.6
     *                   
     * @return boolean  True if added, false if rejected for some
     *                  reason (either parameters or permission settings)
     */
    public boolean addVelocimacro( String name,
                                          Node macro,
                                          String argArray[],
                                          String sourceTemplate )
    {
        return vmFactory.addVelocimacro(name, macro,  argArray,  sourceTemplate);
    }
    
    
    /**
     *  Checks to see if a VM exists
     *
     * @param vmName Name of the Velocimacro.
     * @param templateName Template on which to look for the Macro.
     * @return True if VM by that name exists, false if not
     */
    public boolean isVelocimacro( String vmName, String templateName )
    {
        return vmFactory.isVelocimacro(vmName, templateName);
    }

    /**
     * tells the vmFactory to dump the specified namespace.  This is to support
     * clearing the VM list when in inline-VM-local-scope mode
     * @param namespace Namespace to dump.
     * @return True if namespace was dumped successfully.
     */
    public boolean dumpVMNamespace(String namespace)
    {
        return vmFactory.dumpVMNamespace( namespace );
    }

    /* --------------------------------------------------------------------
     * R U N T I M E  A C C E S S O R  M E T H O D S
     * --------------------------------------------------------------------
     * These are the getXXX() methods that are a simple wrapper
     * around the configuration object. This is an attempt
     * to make a the Velocity Runtime the single access point
     * for all things Velocity, and allow the Runtime to
     * adhere as closely as possible the the Mediator pattern
     * which is the ultimate goal.
     * --------------------------------------------------------------------
     */

    /**
     * String property accessor method to hide the configuration implementation
     * @param key  property key
     * @return   value of key or null
     */
    public String getString(String key)
    {
        return StringUtils.nullTrim(configuration.getString(key));
    }

    /**
     * Int property accessor method to hide the configuration implementation.
     *
     * @param key Property key
     * @return value
     */
    public int getInt(String key)
    {
        return configuration.getInt(key);
    }

    /**
     * Int property accessor method to hide the configuration implementation.
     *
     * @param key  property key
     * @param defaultValue The default value.
     * @return value
     */
    public int getInt(String key, int defaultValue)
    {
        return configuration.getInt(key, defaultValue);
    }

    /**
     * Boolean property accessor method to hide the configuration implementation.
     *
     * @param key property key
     * @param def The default value if property not found.
     * @return value of key or default value
     */
    public boolean getBoolean(String key, boolean def)
    {
        return configuration.getBoolean(key, def);
    }

    /**
     * Return the velocity runtime configuration object.
     *
     * @return Configuration object which houses the Velocity runtime
     * properties.
     */
    public ExtendedProperties getConfiguration()
    {
        return configuration;
    }

    /**
     *  Return the Introspector for this instance
     * @return The Introspector for this instance
     */
    public Introspector getIntrospector()
    {
        return introspector;
    }

    /**
     * Returns the event handlers for the application.
     * @return The event handlers for the application.
     * @since 1.5
     */
    public EventCartridge getApplicationEventCartridge()
    {
        return eventCartridge;
    }


    /**
     *  Gets the application attribute for the given key
     *
     * @param key
     * @return The application attribute for the given key.
     */
    public Object getApplicationAttribute(Object key)
    {
        return applicationAttributes.get(key);
    }

    /**
     *   Sets the application attribute for the given key
     *
     * @param key
     * @param o The new application attribute.
     * @return The old value of this attribute or null if it hasn't been set before.
     */
    public Object setApplicationAttribute(Object key, Object o)
    {
        return applicationAttributes.put(key, o);
    }

    /**
     * Returns the Uberspect object for this Instance.
     *
     * @return The Uberspect object for this Instance.
     */
    public Uberspect getUberspect()
    {
        return uberSpect;
    }

}
