You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by cf...@apache.org on 2012/05/29 17:35:15 UTC

svn commit: r1343781 [5/17] - in /incubator/flex/trunk/modules: ./ thirdparty/velocity/ thirdparty/velocity/build/ thirdparty/velocity/build/lib/ thirdparty/velocity/build/xsl/ thirdparty/velocity/src/java/org/apache/velocity/anakia/ thirdparty/velocit...

Added: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/configuration/Configuration.java
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/configuration/Configuration.java?rev=1343781&view=auto
==============================================================================
--- incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/configuration/Configuration.java (added)
+++ incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/configuration/Configuration.java Tue May 29 15:35:01 2012
@@ -0,0 +1,1885 @@
+package org.apache.velocity.runtime.configuration;
+
+/*
+ * Copyright (c) 2001 The Java Apache Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the Java Apache
+ *    Project for use in the Apache JServ servlet engine project
+ *    <http://java.apache.org/>."
+ *
+ * 4. The names "Apache JServ", "Apache JServ Servlet Engine", "Turbine",
+ *    "Apache Turbine", "Turbine Project", "Apache Turbine Project" and
+ *    "Java Apache Project" must not be used to endorse or promote products
+ *    derived from this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called "Apache JServ"
+ *    nor may "Apache" nor "Apache JServ" appear in their names without
+ *    prior written permission of the Java Apache Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the Java Apache
+ *    Project for use in the Apache JServ servlet engine project
+ *    <http://java.apache.org/>."
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE JAVA APACHE PROJECT "AS IS" AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE JAVA APACHE PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Java Apache Group. For more information
+ * on the Java Apache Project and the Apache JServ Servlet Engine project,
+ * please see <http://java.apache.org/>.
+ *
+ */
+
+import java.io.IOException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.LineNumberReader;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.Reader;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import org.apache.commons.collections.ExtendedProperties;
+
+/**
+ * This class extends normal Java properties by adding the possibility
+ * to use the same key many times concatenating the value strings
+ * instead of overwriting them.
+ *
+ * <p>The Extended Properties syntax is explained here:
+ *
+ * <ul>
+ *  <li>
+ *   Each property has the syntax <code>key = value</code>
+ *  </li>
+ *  <li>
+ *   The <i>key</i> may use any character but the equal sign '='.
+ *  </li>
+ *  <li>
+ *   <i>value</i> may be separated on different lines if a backslash
+ *   is placed at the end of the line that continues below.
+ *  </li>
+ *  <li>
+ *   If <i>value</i> is a list of strings, each token is separated
+ *   by a comma ','.
+ *  </li>
+ *  <li>
+ *   Commas in each token are escaped placing a backslash right before
+ *   the comma.
+ *  </li>
+ *  <li>
+ *   If a <i>key</i> is used more than once, the values are appended
+ *   like if they were on the same line separated with commas.
+ *  </li>
+ *  <li>
+ *   Blank lines and lines starting with character '#' are skipped.
+ *  </li>
+ *  <li>
+ *   If a property is named "include" (or whatever is defined by
+ *   setInclude() and getInclude() and the value of that property is
+ *   the full path to a file on disk, that file will be included into
+ *   the ConfigurationsRepository. You can also pull in files relative
+ *   to the parent configuration file. So if you have something
+ *   like the following:
+ *
+ *   include = additional.properties
+ *
+ *   Then "additional.properties" is expected to be in the same
+ *   directory as the parent configuration file.
+ * 
+ *   Duplicate name values will be replaced, so be careful.
+ *
+ *  </li>
+ * </ul>
+ *
+ * <p>Here is an example of a valid extended properties file:
+ *
+ * <p><pre>
+ *      # lines starting with # are comments
+ *
+ *      # This is the simplest property
+ *      key = value
+ *
+ *      # A long property may be separated on multiple lines
+ *      longvalue = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \
+ *                  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ *
+ *      # This is a property with many tokens
+ *      tokens_on_a_line = first token, second token
+ *
+ *      # This sequence generates exactly the same result
+ *      tokens_on_multiple_lines = first token
+ *      tokens_on_multiple_lines = second token
+ *
+ *      # commas may be escaped in tokens
+ *      commas.excaped = Hi\, what'up?
+ * </pre>
+ *
+ * <p><b>NOTE</b>: this class has <b>not</b> been written for
+ * performance nor low memory usage.  In fact, it's way slower than it
+ * could be and generates too much memory garbage.  But since
+ * performance is not an issue during intialization (and there is not
+ * much time to improve it), I wrote it this way.  If you don't like
+ * it, go ahead and tune it up!
+ *
+ *
+ * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
+ * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
+ * @author <a href="mailto:daveb@miceda-data">Dave Bryson</a>
+ * @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:leon@opticode.co.za">Leon Messerschmidt</a>
+ * @author <a href="mailto:kjohnson@transparent.com>Kent Johnson</a>
+ * @version $Id: Configuration.java,v 1.34 2003/05/04 17:14:37 geirm Exp $
+ *
+ * @deprecated As of version 1.1, please use ExtendedProperties from
+ * the Jakarta Commons Collections component.
+ */
+public class Configuration extends Hashtable
+{
+    // $$$ GMJ : remove post version 1.1
+    // intended to help deprecate this class w/o having to modify 
+    // the jakarta commons collections class which contains
+    // extended properties.  We need this when someone wants to 
+    // configure velocity w/ a Configuration : the strategy is simply
+    // to shadow the Configuration with the EP
+    private ExtendedProperties deprecationCrutch = new ExtendedProperties();
+
+
+    /**
+     * Default configurations repository.
+     */
+    private Configuration defaults;
+
+    /**
+     * The file connected to this repository (holding comments and
+     * such).
+     *
+     * @serial
+     */
+    protected String file;
+
+    /**
+     * Base path of the configuration file used to create
+     * this Configuration object.
+     */
+    protected String basePath;
+
+    /**
+     * File separator.
+     */
+    protected String fileSeparator = System.getProperty("file.separator");
+
+    /**
+     * Has this configuration been intialized.
+     */
+    protected boolean isInitialized = false;
+
+    /**
+     * This is the name of the property that can point to other
+     * properties file for including other properties files.
+     */
+    protected static String include = "include";
+
+    /**
+     * These are the keys in the order they listed
+     * in the configuration file. This is useful when
+     * you wish to perform operations with configuration
+     * information in a particular order.
+     */
+    protected ArrayList keysAsListed = new ArrayList();
+
+    /**
+     * This class is used to read properties lines.  These lines do
+     * not terminate with new-line chars but rather when there is no
+     * backslash sign a the end of the line.  This is used to
+     * concatenate multiple lines for readability.
+     */
+    class PropertiesReader extends LineNumberReader
+    {
+        /**
+         * Constructor.
+         *
+         * @param reader A Reader.
+         */
+        public PropertiesReader(Reader reader)
+        {
+            super(reader);
+        }
+
+        /**
+         * Read a property.
+         *
+         * @return A String.
+         * @exception IOException.
+         */
+        public String readProperty() throws IOException
+        {
+            StringBuffer buffer = new StringBuffer();
+
+            try
+            {
+                while (true)
+                {
+                    String line = readLine().trim();
+                    if ((line.length() != 0) && (line.charAt(0) != '#'))
+                    {
+                        if (line.endsWith("\\"))
+                        {
+                            line = line.substring(0, line.length() - 1);
+                            buffer.append(line);
+                        }
+                        else
+                        {
+                            buffer.append(line);
+                            break;
+                        }
+                    }
+                }
+            }
+            catch (NullPointerException e)
+            {
+                return null;
+            }
+
+            return buffer.toString();
+        }
+    }
+
+    /**
+     * This class divides into tokens a property value.  Token
+     * separator is "," but commas into the property value are escaped
+     * using the backslash in front.
+     */
+    class PropertiesTokenizer extends StringTokenizer
+    {
+        /**
+         * The property delimiter used while parsing (a comma).
+         */
+        static final String DELIMITER = ",";
+
+        /**
+         * Constructor.
+         *
+         * @param string A String.
+         */
+        public PropertiesTokenizer(String string)
+        {
+            super(string, DELIMITER);
+        }
+
+        /**
+         * Check whether the object has more tokens.
+         *
+         * @return True if the object has more tokens.
+         */
+        public boolean hasMoreTokens()
+        {
+            return super.hasMoreTokens();
+        }
+
+        /**
+         * Get next token.
+         *
+         * @return A String.
+         */
+        public String nextToken()
+        {
+            StringBuffer buffer = new StringBuffer();
+
+            while (hasMoreTokens())
+            {
+                String token = super.nextToken();
+                if (token.endsWith("\\"))
+                {
+                    buffer.append(token.substring(0, token.length() - 1));
+                    buffer.append(DELIMITER);
+                }
+                else
+                {
+                    buffer.append(token);
+                    break;
+                }
+            }
+
+            return buffer.toString().trim();
+        }
+    }
+
+    /**
+     * Creates an empty extended properties object.
+     */
+    public Configuration ()
+    {
+        super();
+    }
+
+    /**
+     * Creates and loads the extended properties from the specified
+     * file.
+     *
+     * @param file A String.
+     * @exception IOException.
+     */
+    public Configuration (String file) throws IOException
+    {
+        this(file,null);
+    }
+
+    /**
+     * Creates and loads the extended properties from the specified
+     * file.
+     *
+     * @param file A String.
+     * @exception IOException.
+     */
+    public Configuration (String file, String defaultFile)
+        throws IOException
+    {
+        this.file = file;
+        
+        basePath = new File(file).getAbsolutePath();
+        basePath = basePath.substring(0, basePath.lastIndexOf(fileSeparator) + 1);
+        
+        this.load(new FileInputStream(file));
+        
+        if (defaultFile != null)
+        {
+            defaults = new Configuration(defaultFile);
+        }            
+    }
+
+    /**
+     * Private initializer method that sets up the generic
+     * resources.
+     *
+     * @exception IOException, if there was an I/O problem.
+     */
+    private void init( Configuration exp ) throws IOException
+    {
+        isInitialized = true;
+    }
+    
+    /**
+     * Indicate to client code whether property
+     * resources have been initialized or not.
+     */
+    public boolean isInitialized()
+    {
+        return isInitialized;
+    }        
+
+    /**
+     * Gets the property value for including other properties files.
+     * By default it is "include".
+     *
+     * @return A String.
+     */
+    public String getInclude()
+    {
+        return Configuration.include;
+    }
+
+    /**
+     * Sets the property value for including other properties files.
+     * By default it is "include".
+     *
+     * @param inc A String.
+     */
+    public void setInclude(String inc)
+    {
+		Configuration.include = inc;
+    }
+
+    /**
+     * Load the properties from the given input stream.
+     *
+     * @param input An InputStream.
+     * @exception IOException.
+     */
+    public synchronized void load(InputStream input)
+        throws IOException
+    {
+        PropertiesReader reader =
+            new PropertiesReader(new InputStreamReader(input));
+
+        try
+        {
+            while (true)
+            {
+                String line = reader.readProperty();
+                int equalSign = line.indexOf('=');
+
+                if (equalSign > 0)
+                {
+                    String key = line.substring(0, equalSign).trim();
+                    String value = line.substring(equalSign + 1).trim();
+
+                    /*
+                     * Configure produces lines like this ... just
+                     * ignore them.
+                     */
+                    if ("".equals(value))
+                        continue;
+
+                    if (getInclude() != null && 
+                        key.equalsIgnoreCase(getInclude()))
+                    {
+                        /*
+                         * Recursively load properties files.
+                         */
+                        File file = null;
+                        
+                        if (value.startsWith(fileSeparator))
+                        {
+                            /*
+                             * We have an absolute path so we'll
+                             * use this.
+                             */
+                            file = new File(value);
+                        }
+                        else
+                        {   
+                            /* 
+                             * We have a relative path, and we have
+                             * two possible forms here. If we have the
+                             * "./" form then just strip that off first
+                             * before continuing.
+                             */
+                            if (value.startsWith("." + fileSeparator))
+                            {
+                                value = value.substring(2);
+                            }
+                            
+                            file = new File(basePath + value);
+                        }
+                        
+                        if (file != null && file.exists() && file.canRead())
+                        {
+                            load ( new FileInputStream(file));
+                        }
+                    }
+                    else
+                    {
+                        addProperty(key,value);
+                        //setProperty(key,value);
+                    }                       
+                }
+            }
+        }
+        catch (NullPointerException e)
+        {
+            /*
+             * Should happen only when EOF is reached.
+             */
+            return;
+        }
+    }
+
+    /**
+     *  Gets a property from the configuration.
+     *
+     *  @param key property to retrieve
+     *  @return value as object. Will return user value if exists,
+     *          if not then default value if exists, otherwise null
+     */
+    public Object getProperty( String key)
+    {
+        /*
+         *  first, try to get from the 'user value' store
+         */
+        Object o = this.get(key);
+
+        if ( o == null)
+        {
+            /*
+             *  if there isn't a value there, get it from the
+             *  defaults if we have them
+             */
+            if (defaults != null)
+            {
+                o = defaults.get(key);
+            }
+        }
+
+        return o;
+    }
+    
+    /**
+     * 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 String key
+     * @param String value
+     */
+    //public void setProperty(String key, Object token)
+    public void addProperty(String key, Object token)
+    {
+
+        // $$$ GMJ : remove after 1.1 release
+        // for deprecation help
+        deprecationCrutch.addProperty( key, token );
+
+        Object o = this.get(key);
+
+        /*
+         *  $$$ GMJ
+         *  FIXME : post 1.0 release, we need to not assume
+         *  that a scalar is a String - it can be an Object
+         *  so we should make a little vector-like class
+         *  say, Foo that wraps (not extends Vector),
+         *  so we can do things like
+         *  if ( !( o instanceof Foo) )
+         *  so we know it's our 'vector' container
+         *
+         *  This applies throughout
+         */
+        
+        if (o instanceof String)
+        {
+            Vector v = new Vector(2);
+            v.addElement(o);
+            v.addElement(token);
+            put(key, v);
+        }
+        else if (o instanceof Vector)
+        {
+            ((Vector) o).addElement(token);
+        }
+        else
+        {
+            /*
+             * This is the first time that we have seen
+             * request to place an object in the 
+             * configuration with the key 'key'. So
+             * we just want to place it directly into
+             * the configuration ... but we are going to
+             * make a special exception for String objects
+             * that contain "," characters. We will take
+             * CSV lists and turn the list into a vector of
+             * Strings before placing it in the configuration.
+             * This is a concession for Properties and the
+             * like that cannot parse multiple same key
+             * values.
+             */
+            if (token instanceof String &&
+                ((String)token).indexOf(PropertiesTokenizer.DELIMITER) > 0)
+            {
+                PropertiesTokenizer tokenizer = 
+                    new PropertiesTokenizer((String)token);
+                    
+                while (tokenizer.hasMoreTokens())
+                {
+                    String value = tokenizer.nextToken();
+                    
+                    /*
+                     * we know this is a string, so make sure it
+                     * just goes in rather than risking vectorization
+                     * if it contains an escaped comma
+                     */
+                    addStringProperty(key,value);
+                }
+            }
+            else
+            {
+                /*
+                 * We want to keep track of the order the keys
+                 * are parsed, or dynamically entered into
+                 * the configuration. So when we see a key
+                 * for the first time we will place it in
+                 * an ArrayList so that if a client class needs
+                 * to perform operations with configuration
+                 * in a definite order it will be possible.
+                 */
+
+                /*
+                 * safety check
+                 */
+
+                if( !containsKey( key ) )
+                {
+                    keysAsListed.add(key);
+                }
+
+                /*
+                 * and the value
+                 */
+                put(key, token);
+            }                
+        }
+    }
+
+
+    /**
+     *  Sets a string property w/o checking for commas - used
+     *  internally when a property has been broken up into
+     *  strings that could contain escaped commas to prevent
+     *  the inadvertant vectorization.
+     *
+     *  Thanks to Leon Messerschmidt for this one.
+     *
+     */
+    private  void addStringProperty(String key, String token)
+    {
+        Object o = this.get(key);
+
+        /*
+         *  $$$ GMJ
+         *  FIXME : post 1.0 release, we need to not assume
+         *  that a scalar is a String - it can be an Object
+         *  so we should make a little vector-like class
+         *  say, Foo that wraps (not extends Vector),
+         *  so we can do things like
+         *  if ( !( o instanceof Foo) )
+         *  so we know it's our 'vector' container
+         *
+         *  This applies throughout
+         */
+
+        /*
+         *  do the usual thing - if we have a value and 
+         *  it's scalar, make a vector, otherwise add
+         *  to the vector
+         */
+ 
+        if (o instanceof String)
+        {
+            Vector v = new Vector(2);
+            v.addElement(o);
+            v.addElement(token);
+            put(key, v);
+        }
+        else if (o instanceof Vector)
+        {
+            ((Vector) o).addElement(token);
+        }
+        else
+        {
+            if( !containsKey( key ) )
+            {
+                keysAsListed.add(key);
+            }
+
+            put( key, token);
+        }
+    }
+
+    /**
+     * Set a property, this will replace any previously
+     * set values. Set values is implicitly a call
+     * to clearProperty(key), addProperty(key,value).
+     *
+     * @param String key
+     * @param String value
+     */
+    public void setProperty(String key, Object value)
+    {
+        clearProperty(key);
+        addProperty(key,value);
+    }
+    
+    /**
+     * Save the properties to the given outputstream.
+     *
+     * @param output An OutputStream.
+     * @param header A String.
+     * @exception IOException.
+     */
+    public synchronized void save(OutputStream output,
+                                  String Header)
+        throws IOException
+    {
+        if(output != null)
+        {
+            PrintWriter theWrtr = new PrintWriter(output);
+            if(Header != null)
+            {
+                theWrtr.println(Header);
+            }
+            Enumeration theKeys = keys();
+            while(theKeys.hasMoreElements())
+            {
+                String key = (String) theKeys.nextElement();
+                Object value = get((Object) key);
+                if(value != null)
+                {
+                    if(value instanceof String)
+                    {
+                        StringBuffer currentOutput = new StringBuffer();
+                        currentOutput.append(key);
+                        currentOutput.append("=");
+                        currentOutput.append((String) value);
+                        theWrtr.println(currentOutput.toString());
+                    }
+                    else if(value instanceof Vector)
+                    {
+                        Vector values = (Vector) value;
+                        Enumeration valuesEnum = values.elements();
+                        while(valuesEnum.hasMoreElements())
+                        {
+                            String currentElement = 
+                                   (String) valuesEnum.nextElement();
+                            StringBuffer currentOutput = new StringBuffer();
+                            currentOutput.append(key);
+                            currentOutput.append("=");
+                            currentOutput.append(currentElement);
+                            theWrtr.println(currentOutput.toString());
+                        }
+                    }
+                }    
+                theWrtr.println();
+                theWrtr.flush();
+            }    
+        }        
+    }
+
+    /**
+     * Combines an existing Hashtable with this Hashtable.
+     *
+     * Warning: It will overwrite previous entries without warning.
+     *
+     * @param Configuration
+     */
+    public void combine (Configuration c)
+    {
+        for (Iterator i = c.getKeys() ; i.hasNext() ;)
+        {
+            String key = (String) i.next();
+            //clearProperty(key);
+            setProperty( key, c.get(key) );
+        }
+    }
+    
+    /**
+     * Clear a property in the configuration.
+     *
+     * @param String key to remove along with corresponding value.
+     */
+    public void clearProperty(String key)
+    {
+        // $$$ GMJ : remove after 1.1 release
+        // for deprecation help
+        deprecationCrutch.clearProperty( key  );
+
+        if (containsKey(key))
+        {
+            /*
+             * we also need to rebuild the keysAsListed or else
+             * things get *very* confusing
+             */
+
+            for(int i = 0; i < keysAsListed.size(); i++)
+            {
+                if ( ( (String) keysAsListed.get(i)).equals( key ) )
+                {
+                    keysAsListed.remove(i);
+                    break;
+                }
+            }
+
+            remove(key);
+        }            
+    }
+
+    /**
+     * Get the list of the keys contained in the configuration
+     * repository.
+     *
+     * @return An Iterator.
+     */
+    public Iterator getKeys()
+    {
+        return keysAsListed.iterator();
+    }
+
+    /**
+     * Get the list of the keys contained in the configuration
+     * repository that match the specified prefix.
+     *
+     * @param prefix The prefix to test against.
+     * @return An Iterator of keys that match the prefix.
+     */
+    public Iterator getKeys(String prefix)
+    {
+        Iterator keys = getKeys();
+        ArrayList matchingKeys = new ArrayList();
+        
+        while( keys.hasNext() )
+        {
+            Object key = keys.next();
+            
+            if( key instanceof String && ((String) key).startsWith(prefix) )
+            {
+                matchingKeys.add(key);
+            }
+        }
+        return matchingKeys.iterator();
+    }
+
+    /**
+     * Create a Configurations object that is a subset
+     * of this one. Take into account duplicate keys
+     * by using the setProperty() in Configuration.
+     *
+     * @param String prefix
+     */
+    public Configuration subset(String prefix)
+    {
+        Configuration c = new Configuration();
+        Iterator keys = getKeys();
+        boolean validSubset = false;
+        
+        while( keys.hasNext() )
+        {
+            Object key = keys.next();
+            
+            if( key instanceof String && ((String) key).startsWith(prefix) )
+            {
+                if (!validSubset)
+                {
+                    validSubset = true;
+                }
+                
+                String newKey = null;
+                
+                /*
+                 * Check to make sure that c.subset(prefix) doesn't
+                 * blow up when there is only a single property
+                 * with the key prefix. This is not a useful
+                 * subset but it is a valid subset.
+                 */
+                if ( ((String)key).length() == prefix.length())
+                {
+                    newKey = prefix;
+                }
+                else
+                {
+                    newKey = ((String)key).substring(prefix.length() + 1);
+                }                    
+                
+                /*
+                 * Make sure to use the setProperty() method and not
+                 * just put(). setProperty() takes care of catching
+                 * all the keys in the order they appear in a
+                 * properties files or the order they are set
+                 * dynamically.
+                 */
+
+                c.setProperty(newKey, get(key));
+            }
+        }
+        
+        if (validSubset)
+        {
+            return c;
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+    /**
+     * Display the configuration for debugging
+     * purposes.
+     */
+    public void display()
+    {
+        Iterator i = getKeys();
+        
+        while (i.hasNext())
+        {
+            String key = (String) i.next();
+            Object value = get(key);
+            System.out.println(key + " => " + value);
+        }
+    }     
+
+    /**
+     * Get a string associated with the given configuration key.
+     *
+     * @param key The configuration key.
+     * @return The associated string.
+     * @exception ClassCastException is thrown if the key maps to an
+     * object that is not a String.
+     */
+    public String getString(String key)
+    {
+        return getString(key, null);
+    }
+
+    /**
+     * Get a string associated with the given configuration key.
+     *
+     * @param key The configuration key.
+     * @param defaultValue The default value.
+     * @return The associated string if key is found,
+     * default value otherwise.
+     * @exception ClassCastException is thrown if the key maps to an
+     * object that is not a String.
+     */
+    public String getString(String key,
+                            String defaultValue)
+    {
+        Object value = get(key);
+
+        if (value instanceof String)
+        {
+            return (String) value;
+        }
+        else if (value == null)
+        {
+            if (defaults != null)
+            {
+                return defaults.getString(key, defaultValue);
+            }
+            else
+            {
+                return defaultValue;
+            }
+        }
+        else if (value instanceof Vector)
+        {
+            return (String) ((Vector) value).get(0);
+        }
+        else
+        {
+            throw new ClassCastException(
+                '\'' + key + "' doesn't map to a String object");
+        }
+    }
+
+    /**
+     * Get a list of properties associated with the given
+     * configuration key.
+     *
+     * @param key The configuration key.
+     * @return The associated properties if key is found.
+     * @exception ClassCastException is thrown if the key maps to an
+     * object that is not a String/Vector.
+     * @exception IllegalArgumentException if one of the tokens is
+     * malformed (does not contain an equals sign).
+     */
+    public Properties getProperties(String key)
+    {
+        return getProperties(key, new Properties());
+    }
+
+    /**
+     * Get a list of properties associated with the given
+     * configuration key.
+     *
+     * @param key The configuration key.
+     * @return The associated properties if key is found.
+     * @exception ClassCastException is thrown if the key maps to an
+     * object that is not a String/Vector.
+     * @exception IllegalArgumentException if one of the tokens is
+     * malformed (does not contain an equals sign).
+     */
+    public Properties getProperties(String key,
+                                    Properties defaults)
+    {
+        /*
+         * Grab an array of the tokens for this key.
+         */
+        String[] tokens = getStringArray(key);
+
+        /* 
+         * Each token is of the form 'key=value'.
+         */
+        Properties props = new Properties(defaults);
+        for (int i = 0; i < tokens.length; i++)
+        {
+            String token = tokens[i];
+            int equalSign = token.indexOf('=');
+            if (equalSign > 0)
+            {
+                String pkey = token.substring(0, equalSign).trim();
+                String pvalue = token.substring(equalSign + 1).trim();
+                props.put(pkey, pvalue);
+            }
+            else
+            {
+                throw new IllegalArgumentException('\'' + token +
+                                                   "' does not contain " +
+                                                   "an equals sign");
+            }
+        }
+        return props;
+    }
+
+    /**
+     * Get an array of strings associated with the given configuration
+     * key.
+     *
+     * @param key The configuration key.
+     * @return The associated string array if key is found.
+     * @exception ClassCastException is thrown if the key maps to an
+     * object that is not a String/Vector.
+     */
+    public String[] getStringArray(String key)
+    {
+        Object value = get(key);
+
+        // What's your vector, Victor?
+        Vector vector;
+        if (value instanceof String)
+        {
+            vector = new Vector(1);
+            vector.addElement(value);
+        }
+        else if (value instanceof Vector)
+        {
+            vector = (Vector)value;
+        }
+        else if (value == null)
+        {
+            if (defaults != null)
+            {
+                return defaults.getStringArray(key);
+            }
+            else
+            {
+                return new String[0];
+            }
+        }
+        else
+        {
+            throw new ClassCastException(
+                '\'' + key + "' doesn't map to a String/Vector object");
+        }
+
+        String[] tokens = new String[vector.size()];
+        for (int i = 0; i < tokens.length; i++)
+        {
+            tokens[i] = (String)vector.elementAt(i);
+        }
+
+        return tokens;
+    }
+
+    /**
+     * Get a Vector of strings associated with the given configuration
+     * key.
+     *
+     * @param key The configuration key.
+     * @return The associated Vector.
+     * @exception ClassCastException is thrown if the key maps to an
+     * object that is not a Vector.
+     */
+    public Vector getVector(String key)
+    {
+        return getVector(key, null);
+    }
+
+    /**
+     * Get a Vector of strings associated with the given configuration
+     * key.
+     *
+     * @param key The configuration key.
+     * @param defaultValue The default value.
+     * @return The associated Vector.
+     * @exception ClassCastException is thrown if the key maps to an
+     * object that is not a Vector.
+     */
+    public Vector getVector(String key,
+                            Vector defaultValue)
+    {
+        Object value = get(key);
+
+        if (value instanceof Vector)
+        {
+            return (Vector) value;
+        }
+        else if (value instanceof String)
+        {
+            Vector v = new Vector(1);
+            v.addElement((String) value);
+            put(key, v);
+            return v;
+        }
+        else if (value == null)
+        {
+            if (defaults != null)
+            {
+                return defaults.getVector(key, defaultValue);
+            }
+            else
+            {
+                return ((defaultValue == null) ?
+                        new Vector() : defaultValue);
+            }
+        }
+        else
+        {
+            throw new ClassCastException(
+                '\'' + key + "' doesn't map to a Vector object");
+        }
+    }
+
+    /**
+     * Get a boolean associated with the given configuration key.
+     *
+     * @param key The configuration key.
+     * @return The associated boolean.
+     * @exception NoSuchElementException is thrown if the key doesn't
+     * map to an existing object.
+     * @exception ClassCastException is thrown if the key maps to an
+     * object that is not a Boolean.
+     */
+    public boolean getBoolean(String key)
+    {
+        Boolean b = getBoolean(key, (Boolean) null);
+        if (b != null)
+        {
+            return b.booleanValue();
+        }
+        else
+        {
+            throw new NoSuchElementException(
+                '\'' + key + "' doesn't map to an existing object");
+        }
+    }
+
+    /**
+     * Get a boolean associated with the given configuration key.
+     *
+     * @param key The configuration key.
+     * @param defaultValue The default value.
+     * @return The associated boolean.
+     * @exception ClassCastException is thrown if the key maps to an
+     * object that is not a Boolean.
+     */
+    public boolean getBoolean(String key, boolean defaultValue)
+    {
+        return getBoolean(key, new Boolean(defaultValue)).booleanValue();
+    }
+
+    /**
+     * Get a boolean associated with the given configuration key.
+     *
+     * @param key The configuration key.
+     * @param defaultValue The default value.
+     * @return The associated boolean if key is found and has valid
+     * format, default value otherwise.
+     * @exception ClassCastException is thrown if the key maps to an
+     * object that is not a Boolean.
+     */
+    public Boolean getBoolean(String key, Boolean defaultValue)
+    {
+    
+        Object value = get(key);
+
+        if (value instanceof Boolean)
+        {
+            return (Boolean) value;
+        }
+        else if (value instanceof String)
+        {
+            String s = testBoolean((String)value);
+            Boolean b = new Boolean(s);
+            put(key, b);
+            return b;
+        }
+        else if (value == null)
+        {
+            if (defaults != null)
+            {
+                return defaults.getBoolean(key, defaultValue);
+            }
+            else
+            {
+                return defaultValue;
+            }
+        }
+        else
+        {
+            throw new ClassCastException(
+                '\'' + key + "' doesn't map to a Boolean object");
+        }
+    }
+    
+    /**
+     * Test whether the string represent by value maps to a boolean
+     * value or not. We will allow <code>true</code>, <code>on</code>,
+     * and <code>yes</code> for a <code>true</code> boolean value, and
+     * <code>false</code>, <code>off</code>, and <code>no</code> for
+     * <code>false</code> boolean values.  Case of value to test for
+     * boolean status is ignored.
+     *
+     * @param String The value to test for boolean state.
+     * @return <code>true</code> or <code>false</code> if the supplied
+     * text maps to a boolean value, or <code>null</code> otherwise.
+     */
+    public String testBoolean(String value)
+    {
+        String s = ((String)value).toLowerCase();
+    
+        if (s.equals("true") || s.equals("on") || s.equals("yes"))
+        {
+            return "true";
+        }
+        else if (s.equals("false") || s.equals("off") || s.equals("no"))
+        {
+            return "false";
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+    /**
+     * Get a byte associated with the given configuration key.
+     *
+     * @param key The configuration key.
+     * @return The associated byte.
+     * @exception NoSuchElementException is thrown if the key doesn't
+     * map to an existing object.
+     * @exception ClassCastException is thrown if the key maps to an
+     * object that is not a Byte.
+     * @exception NumberFormatException is thrown if the value mapped
+     * by the key has not a valid number format.
+     */
+    public byte getByte(String key)
+    {
+        Byte b = getByte(key, null);
+        if (b != null)
+        {
+            return b.byteValue();
+        }
+        else
+        {
+            throw new NoSuchElementException(
+                '\'' + key + " doesn't map to an existing object");
+        }
+    }
+
+    /**
+     * Get a byte associated with the given configuration key.
+     *
+     * @param key The configuration key.
+     * @param defaultValue The default value.
+     * @return The associated byte.
+     * @exception ClassCastException is thrown if the key maps to an
+     * object that is not a Byte.
+     * @exception NumberFormatException is thrown if the value mapped
+     * by the key has not a valid number format.
+     */
+    public byte getByte(String key,
+                        byte defaultValue)
+    {
+        return getByte(key, new Byte(defaultValue)).byteValue();
+    }
+
+    /**
+     * Get a byte associated with the given configuration key.
+     *
+     * @param key The configuration key.
+     * @param defaultValue The default value.
+     * @return The associated byte if key is found and has valid
+     * format, default value otherwise.
+     * @exception ClassCastException is thrown if the key maps to an
+     * object that is not a Byte.
+     * @exception NumberFormatException is thrown if the value mapped
+     * by the key has not a valid number format.
+     */
+    public Byte getByte(String key,
+                        Byte defaultValue)
+    {
+        Object value = get(key);
+
+        if (value instanceof Byte)
+        {
+            return (Byte) value;
+        }
+        else if (value instanceof String)
+        {
+            Byte b = new Byte((String) value);
+            put(key, b);
+            return b;
+        }
+        else if (value == null)
+        {
+            if (defaults != null)
+            {
+                return defaults.getByte(key, defaultValue);
+            }
+            else
+            {
+                return defaultValue;
+            }
+        }
+        else
+        {
+            throw new ClassCastException(
+                '\'' + key + "' doesn't map to a Byte object");
+        }
+    }
+
+    /**
+     * Get a short associated with the given configuration key.
+     *
+     * @param key The configuration key.
+     * @return The associated short.
+     * @exception NoSuchElementException is thrown if the key doesn't
+     * map to an existing object.
+     * @exception ClassCastException is thrown if the key maps to an
+     * object that is not a Short.
+     * @exception NumberFormatException is thrown if the value mapped
+     * by the key has not a valid number format.
+     */
+    public short getShort(String key)
+    {
+        Short s = getShort(key, null);
+        if (s != null)
+        {
+            return s.shortValue();
+        }
+        else
+        {
+            throw new NoSuchElementException(
+                '\'' + key + "' doesn't map to an existing object");
+        }
+    }
+
+    /**
+     * Get a short associated with the given configuration key.
+     *
+     * @param key The configuration key.
+     * @param defaultValue The default value.
+     * @return The associated short.
+     * @exception ClassCastException is thrown if the key maps to an
+     * object that is not a Short.
+     * @exception NumberFormatException is thrown if the value mapped
+     * by the key has not a valid number format.
+     */
+    public short getShort(String key,
+                          short defaultValue)
+    {
+        return getShort(key, new Short(defaultValue)).shortValue();
+    }
+
+    /**
+     * Get a short associated with the given configuration key.
+     *
+     * @param key The configuration key.
+     * @param defaultValue The default value.
+     * @return The associated short if key is found and has valid
+     * format, default value otherwise.
+     * @exception ClassCastException is thrown if the key maps to an
+     * object that is not a Short.
+     * @exception NumberFormatException is thrown if the value mapped
+     * by the key has not a valid number format.
+     */
+    public Short getShort(String key,
+                          Short defaultValue)
+    {
+        Object value = get(key);
+
+        if (value instanceof Short)
+        {
+            return (Short) value;
+        }
+        else if (value instanceof String)
+        {
+            Short s = new Short((String) value);
+            put(key, s);
+            return s;
+        }
+        else if (value == null)
+        {
+            if (defaults != null)
+            {
+                return defaults.getShort(key, defaultValue);
+            }
+            else
+            {
+                return defaultValue;
+            }
+        }
+        else
+        {
+            throw new ClassCastException(
+                '\'' + key + "' doesn't map to a Short object");
+        }
+    }
+
+    /**
+     * The purpose of this method is to get the configuration resource
+     * with the given name as an integer.
+     *
+     * @param name The resource name.
+     * @return The value of the resource as an integer.
+     */
+    public int getInt(String name)
+    {
+        return getInteger(name);
+    }
+
+    /**
+     * The purpose of this method is to get the configuration resource
+     * with the given name as an integer, or a default value.
+     *
+     * @param name The resource name
+     * @param def The default value of the resource.
+     * @return The value of the resource as an integer.
+     */
+    public int getInt(String name,
+                      int def)
+    {
+        return getInteger(name, def);
+    }
+
+    /**
+     * Get a int associated with the given configuration key.
+     *
+     * @param key The configuration key.
+     * @return The associated int.
+     * @exception NoSuchElementException is thrown if the key doesn't
+     * map to an existing object.
+     * @exception ClassCastException is thrown if the key maps to an
+     * object that is not a Integer.
+     * @exception NumberFormatException is thrown if the value mapped
+     * by the key has not a valid number format.
+     */
+    public int getInteger(String key)
+    {
+        Integer i = getInteger(key, null);
+        if (i != null)
+        {
+            return i.intValue();
+        }
+        else
+        {
+            throw new NoSuchElementException(
+                '\'' + key + "' doesn't map to an existing object");
+        }
+    }
+
+    /**
+     * Get a int associated with the given configuration key.
+     *
+     * @param key The configuration key.
+     * @param defaultValue The default value.
+     * @return The associated int.
+     * @exception ClassCastException is thrown if the key maps to an
+     * object that is not a Integer.
+     * @exception NumberFormatException is thrown if the value mapped
+     * by the key has not a valid number format.
+     */
+    public int getInteger(String key,
+                          int defaultValue)
+    {    
+        Integer i = getInteger(key, null);
+        
+        if (i == null)
+        {
+            return defaultValue;
+        }
+        
+        return i.intValue();
+      }
+
+
+    /**
+     * Get a int associated with the given configuration key.
+     *
+     * @param key The configuration key.
+     * @param defaultValue The default value.
+     * @return The associated int if key is found and has valid
+     * format, default value otherwise.
+     * @exception ClassCastException is thrown if the key maps to an
+     * object that is not a Integer.
+     * @exception NumberFormatException is thrown if the value mapped
+     * by the key has not a valid number format.
+     */
+    public Integer getInteger(String key,
+                              Integer defaultValue)
+    {
+        Object value = get(key);
+
+        if (value instanceof Integer)
+        {
+            return (Integer) value;
+        }
+        else if (value instanceof String)
+        {
+            Integer i = new Integer((String) value);
+            put(key, i);
+            return i;
+        }
+        else if (value == null)
+        {
+            if (defaults != null)
+            {
+                return defaults.getInteger(key, defaultValue);
+            }
+            else
+            {
+                return defaultValue;
+            }
+        }
+        else
+        {
+            throw new ClassCastException(
+                '\'' + key + "' doesn't map to a Integer object");
+        }
+    }
+
+    /**
+     * Get a long associated with the given configuration key.
+     *
+     * @param key The configuration key.
+     * @return The associated long.
+     * @exception NoSuchElementException is thrown if the key doesn't
+     * map to an existing object.
+     * @exception ClassCastException is thrown if the key maps to an
+     * object that is not a Long.
+     * @exception NumberFormatException is thrown if the value mapped
+     * by the key has not a valid number format.
+     */
+    public long getLong(String key)
+    {
+        Long l = getLong(key, null);
+        if (l != null)
+        {
+            return l.longValue();
+        }
+        else
+        {
+            throw new NoSuchElementException(
+                '\'' + key + "' doesn't map to an existing object");
+        }
+    }
+
+    /**
+     * Get a long associated with the given configuration key.
+     *
+     * @param key The configuration key.
+     * @param defaultValue The default value.
+     * @return The associated long.
+     * @exception ClassCastException is thrown if the key maps to an
+     * object that is not a Long.
+     * @exception NumberFormatException is thrown if the value mapped
+     * by the key has not a valid number format.
+     */
+    public long getLong(String key,
+                        long defaultValue)
+    {
+        return getLong(key, new Long(defaultValue)).longValue();
+    }
+
+    /**
+     * Get a long associated with the given configuration key.
+     *
+     * @param key The configuration key.
+     * @param defaultValue The default value.
+     * @return The associated long if key is found and has valid
+     * format, default value otherwise.
+     * @exception ClassCastException is thrown if the key maps to an
+     * object that is not a Long.
+     * @exception NumberFormatException is thrown if the value mapped
+     * by the key has not a valid number format.
+     */
+    public Long getLong(String key,
+                        Long defaultValue)
+    {
+        Object value = get(key);
+
+        if (value instanceof Long)
+        {
+            return (Long) value;
+        }
+        else if (value instanceof String)
+        {
+            Long l = new Long((String) value);
+            put(key, l);
+            return l;
+        }
+        else if (value == null)
+        {
+            if (defaults != null)
+            {
+                return defaults.getLong(key, defaultValue);
+            }
+            else
+            {
+                return defaultValue;
+            }
+        }
+        else
+        {
+            throw new ClassCastException(
+                '\'' + key + "' doesn't map to a Long object");
+        }
+    }
+
+    /**
+     * Get a float associated with the given configuration key.
+     *
+     * @param key The configuration key.
+     * @return The associated float.
+     * @exception NoSuchElementException is thrown if the key doesn't
+     * map to an existing object.
+     * @exception ClassCastException is thrown if the key maps to an
+     * object that is not a Float.
+     * @exception NumberFormatException is thrown if the value mapped
+     * by the key has not a valid number format.
+     */
+    public float getFloat(String key)
+    {
+        Float f = getFloat(key, null);
+        if (f != null)
+        {
+            return f.floatValue();
+        }
+        else
+        {
+            throw new NoSuchElementException(
+                '\'' + key + "' doesn't map to an existing object");
+        }
+    }
+
+    /**
+     * Get a float associated with the given configuration key.
+     *
+     * @param key The configuration key.
+     * @param defaultValue The default value.
+     * @return The associated float.
+     * @exception ClassCastException is thrown if the key maps to an
+     * object that is not a Float.
+     * @exception NumberFormatException is thrown if the value mapped
+     * by the key has not a valid number format.
+     */
+    public float getFloat(String key,
+                          float defaultValue)
+    {
+        return getFloat(key, new Float(defaultValue)).floatValue();
+    }
+
+    /**
+     * Get a float associated with the given configuration key.
+     *
+     * @param key The configuration key.
+     * @param defaultValue The default value.
+     * @return The associated float if key is found and has valid
+     * format, default value otherwise.
+     * @exception ClassCastException is thrown if the key maps to an
+     * object that is not a Float.
+     * @exception NumberFormatException is thrown if the value mapped
+     * by the key has not a valid number format.
+     */
+    public Float getFloat(String key,
+                          Float defaultValue)
+    {
+        Object value = get(key);
+
+        if (value instanceof Float)
+        {
+            return (Float) value;
+        }
+        else if (value instanceof String)
+        {
+            Float f = new Float((String) value);
+            put(key, f);
+            return f;
+        }
+        else if (value == null)
+        {
+            if (defaults != null)
+            {
+                return defaults.getFloat(key, defaultValue);
+            }
+            else
+            {
+                return defaultValue;
+            }
+        }
+        else
+        {
+            throw new ClassCastException(
+                '\'' + key + "' doesn't map to a Float object");
+        }
+    }
+
+    /**
+     * Get a double associated with the given configuration key.
+     *
+     * @param key The configuration key.
+     * @return The associated double.
+     * @exception NoSuchElementException is thrown if the key doesn't
+     * map to an existing object.
+     * @exception ClassCastException is thrown if the key maps to an
+     * object that is not a Double.
+     * @exception NumberFormatException is thrown if the value mapped
+     * by the key has not a valid number format.
+     */
+    public double getDouble(String key)
+    {
+        Double d = getDouble(key, null);
+        if (d != null)
+        {
+            return d.doubleValue();
+        }
+        else
+        {
+            throw new NoSuchElementException(
+                '\'' + key + "' doesn't map to an existing object");
+        }
+    }
+
+    /**
+     * Get a double associated with the given configuration key.
+     *
+     * @param key The configuration key.
+     * @param defaultValue The default value.
+     * @return The associated double.
+     * @exception ClassCastException is thrown if the key maps to an
+     * object that is not a Double.
+     * @exception NumberFormatException is thrown if the value mapped
+     * by the key has not a valid number format.
+     */
+    public double getDouble(String key,
+                            double defaultValue)
+    {
+        return getDouble(key, new Double(defaultValue)).doubleValue();
+    }
+
+    /**
+     * Get a double associated with the given configuration key.
+     *
+     * @param key The configuration key.
+     * @param defaultValue The default value.
+     * @return The associated double if key is found and has valid
+     * format, default value otherwise.
+     * @exception ClassCastException is thrown if the key maps to an
+     * object that is not a Double.
+     * @exception NumberFormatException is thrown if the value mapped
+     * by the key has not a valid number format.
+     */
+    public Double getDouble(String key,
+                            Double defaultValue)
+    {
+        Object value = get(key);
+
+        if (value instanceof Double)
+        {
+            return (Double) value;
+        }
+        else if (value instanceof String)
+        {
+            Double d = new Double((String) value);
+            put(key, d);
+            return d;
+        }
+        else if (value == null)
+        {
+            if (defaults != null)
+            {
+                return defaults.getDouble(key, defaultValue);
+            }
+            else
+            {
+                return defaultValue;
+            }
+        }
+        else
+        {
+            throw new ClassCastException(
+                '\'' + key + "' doesn't map to a Double object");
+        }
+    }
+
+    /**
+     * Convert a standard properties class into a configuration
+     * class.
+     *
+     * @param Properties properties object to convert into
+     *                   a Configuration object.
+     *
+     * @return Configuration configuration created from the
+     *                      properties object.
+     */
+    public static Configuration convertProperties(Properties p)
+    {
+        Configuration c = new Configuration();
+    
+        for (Enumeration e = p.keys(); e.hasMoreElements() ; ) 
+        {
+            String s = (String) e.nextElement();
+            c.setProperty(s, p.getProperty(s));
+        }
+    
+        return c;
+    }
+
+    /**
+     *  <p>
+     *  Routine intended for deprecation period only
+     *  as we switch from using the Configuration
+     *  class in Velocity to the Jakarta Commons
+     *  ExtendedProperties
+     *  </p>
+     *  <p>
+     *  Do not use this for general use. It will disappear
+     * </p>
+     *  @return ExtendedProperties containing data of Configuration
+     *  
+     *  @deprecated Do not use.  For deprecation assistance only.
+     */
+    public ExtendedProperties getExtendedProperties() 
+    {
+        return deprecationCrutch; 
+    }
+
+
+}

Propchange: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/configuration/Configuration.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/defaults/directive.properties
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/defaults/directive.properties?rev=1343781&view=auto
==============================================================================
--- incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/defaults/directive.properties (added)
+++ incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/defaults/directive.properties Tue May 29 15:35:01 2012
@@ -0,0 +1,5 @@
+directive.1=org.apache.velocity.runtime.directive.Foreach
+directive.2=org.apache.velocity.runtime.directive.Include
+directive.3=org.apache.velocity.runtime.directive.Parse
+directive.4=org.apache.velocity.runtime.directive.Macro
+directive.5=org.apache.velocity.runtime.directive.Literal

Propchange: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/defaults/directive.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/defaults/velocity.properties
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/defaults/velocity.properties?rev=1343781&view=auto
==============================================================================
--- incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/defaults/velocity.properties (added)
+++ incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/defaults/velocity.properties Tue May 29 15:35:01 2012
@@ -0,0 +1,150 @@
+#----------------------------------------------------------------------------
+# These are the default properties for the
+# Velocity Runtime. These values are used when
+# Runtime.init() is called, and when Runtime.init(properties)
+# fails to find the specificed properties file.
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# R U N T I M E  L O G
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+#  default LogSystem to use: default: AvalonLogSystem
+#----------------------------------------------------------------------------
+
+runtime.log.logsystem.class = org.apache.velocity.runtime.log.AvalonLogSystem,org.apache.velocity.runtime.log.SimpleLog4JLogSystem
+
+#---------------------------------------------------------------------------
+# This is the location of the Velocity Runtime log.
+#----------------------------------------------------------------------------
+
+runtime.log = velocity.log
+
+#----------------------------------------------------------------------------
+# This controls if Runtime.error(), info() and warn() messages include the
+# whole stack trace. The last property controls whether invalid references
+# are logged.
+#----------------------------------------------------------------------------
+
+runtime.log.error.stacktrace = false
+runtime.log.warn.stacktrace = false
+runtime.log.info.stacktrace = false
+runtime.log.invalid.reference = true
+
+#----------------------------------------------------------------------------
+# Configuration for the Log4JLogSystem.
+# You must define the runtime.log.logsystem.class property to be:
+#   org.apache.velocity.runtime.log.Log4JLogSystem
+#
+# You must also include Log4J's .jar files into your classpath. They are
+# included with the Velocity distribution in the build/lib directory.
+#
+# There are several different options that you can configure.
+# Uncomment the ones that you want and also define their settings.
+#----------------------------------------------------------------------------
+#runtime.log.logsystem.log4j.pattern=%d - %m%n
+#runtime.log.logsystem.log4j.file.size=100000
+#runtime.log.logsystem.log4j.file.backups=1
+#runtime.log.logsystem.log4j.syslogd.host=my.syslog.server.com
+#runtime.log.logsystem.log4j.syslogd.facility=LOG_DAEMON
+#runtime.log.logsystem.log4j.remote.host=my.remote.server.com
+#runtime.log.logsystem.log4j.remote.port=1099
+#runtime.log.logsystem.log4j.email.server=localhost
+#runtime.log.logsystem.log4j.email.from=root@localhost
+#runtime.log.logsystem.log4j.email.to=root@localhost
+#runtime.log.logsystem.log4j.email.subject=Velocity Error Report
+#runtime.log.logsystem.log4j.email.buffer.size=512
+
+#----------------------------------------------------------------------------
+# T E M P L A T E  E N C O D I N G
+#----------------------------------------------------------------------------
+
+input.encoding=ISO-8859-1
+output.encoding=ISO-8859-1
+
+#----------------------------------------------------------------------------
+# F O R E A C H  P R O P E R T I E S
+#----------------------------------------------------------------------------
+# These properties control how the counter is accessed in the #foreach
+# directive. By default the reference $velocityCount will be available
+# in the body of the #foreach directive. The default starting value
+# for this reference is 1.
+#----------------------------------------------------------------------------
+
+directive.foreach.counter.name = velocityCount
+directive.foreach.counter.initial.value = 1
+
+#----------------------------------------------------------------------------
+# I N C L U D E  P R O P E R T I E S
+#----------------------------------------------------------------------------
+# These are the properties that governed the way #include'd content
+# is governed.
+#----------------------------------------------------------------------------
+
+directive.include.output.errormsg.start = <!-- include error :
+directive.include.output.errormsg.end   =  see error log -->
+
+#----------------------------------------------------------------------------
+# P A R S E  P R O P E R T I E S
+#----------------------------------------------------------------------------
+
+directive.parse.max.depth = 10
+
+#----------------------------------------------------------------------------
+# T E M P L A T E  L O A D E R S
+#----------------------------------------------------------------------------
+#
+#
+#----------------------------------------------------------------------------
+
+resource.loader = file
+
+file.resource.loader.description = Velocity File Resource Loader
+file.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader
+file.resource.loader.path = .
+file.resource.loader.cache = false
+file.resource.loader.modificationCheckInterval = 2
+
+#----------------------------------------------------------------------------
+# VELOCIMACRO PROPERTIES
+#----------------------------------------------------------------------------
+# global : name of default global library.  It is expected to be in the regular
+# template path.  You may remove it (either the file or this property) if
+# you wish with no harm.
+#----------------------------------------------------------------------------
+velocimacro.library = VM_global_library.vm
+
+velocimacro.permissions.allow.inline = true
+velocimacro.permissions.allow.inline.to.replace.global = false
+velocimacro.permissions.allow.inline.local.scope = false
+
+velocimacro.context.localscope = false
+
+#----------------------------------------------------------------------------
+# INTERPOLATION
+#----------------------------------------------------------------------------
+# turn off and on interpolation of references and directives in string
+# literals.  ON by default :)
+#----------------------------------------------------------------------------
+runtime.interpolate.string.literals = true
+
+
+#----------------------------------------------------------------------------
+# RESOURCE MANAGEMENT
+#----------------------------------------------------------------------------
+# Allows alternative ResourceManager and ResourceCache implementations
+# to be plugged in.
+#----------------------------------------------------------------------------
+resource.manager.class = org.apache.velocity.runtime.resource.ResourceManagerImpl
+resource.manager.cache.class = org.apache.velocity.runtime.resource.ResourceCacheImpl
+
+#----------------------------------------------------------------------------
+# PLUGGABLE INTROSPECTOR
+#----------------------------------------------------------------------------
+# Allows alternative introspection and all that can of worms brings
+#----------------------------------------------------------------------------
+
+runtime.introspector.uberspect = org.apache.velocity.util.introspection.UberspectImpl
+
+

Propchange: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/defaults/velocity.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/DirectiveConstants.java
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/DirectiveConstants.java?rev=1343781&view=auto
==============================================================================
--- incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/DirectiveConstants.java (added)
+++ incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/DirectiveConstants.java Tue May 29 15:35:01 2012
@@ -0,0 +1,32 @@
+package org.apache.velocity.runtime.directive;
+
+/*
+ * Copyright 2000-2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.
+ */
+
+/**
+ *  Base class for all directives used in Velocity.
+ *
+ *  @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
+ *  @version $Id: DirectiveConstants.java,v 1.4.14.1 2004/03/03 23:22:55 geirm Exp $ 
+ */
+public interface DirectiveConstants
+{
+    /** Block directive indicator */
+    public static final int BLOCK = 1;
+    
+    /** Line directive indicator */
+    public static final int LINE = 2;
+}        

Propchange: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/DirectiveConstants.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/InputBase.java
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/InputBase.java?rev=1343781&view=auto
==============================================================================
--- incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/InputBase.java (added)
+++ incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/InputBase.java Tue May 29 15:35:01 2012
@@ -0,0 +1,56 @@
+package org.apache.velocity.runtime.directive;
+
+/*
+ * Copyright 2000-2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.context.InternalContextAdapter;
+import org.apache.velocity.runtime.RuntimeConstants;
+import org.apache.velocity.runtime.resource.Resource;
+
+/**
+ * Base class for directives which do input operations
+ * (e.g. <code>#include()</code>, <code>#parse()</code>, etc.).
+ *
+ * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
+ * @since 1.4
+ */
+public abstract class InputBase extends Directive
+{
+    /**
+     * Decides the encoding used during input processing of this
+     * directive.
+     *
+     * Get the resource, and assume that we use the encoding of the
+     * current template the 'current resource' can be
+     * <code>null</code> if we are processing a stream....
+     *
+     * @param context The context to derive the default input encoding
+     * from.
+     * @return The encoding to use when processing this directive.     
+     */
+    protected String getInputEncoding(InternalContextAdapter context)
+    {
+        Resource current = context.getCurrentResource();
+        if (current != null)
+        {
+            return current.getEncoding();
+        }
+        else
+        {
+            return (String) rsvc.getProperty(RuntimeConstants.INPUT_ENCODING);
+        }
+    }
+}

Propchange: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/InputBase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/Literal.java
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/Literal.java?rev=1343781&view=auto
==============================================================================
--- incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/Literal.java (added)
+++ incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/Literal.java Tue May 29 15:35:01 2012
@@ -0,0 +1,79 @@
+package org.apache.velocity.runtime.directive;
+
+/*
+ * Copyright 2000-2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.*;
+
+import org.apache.velocity.context.InternalContextAdapter;
+import org.apache.velocity.runtime.parser.node.Node;
+
+import org.apache.velocity.runtime.RuntimeServices;
+
+/**
+ * A very simple directive that leverages the Node.literal()
+ * to grab the literal rendition of a node. We basically
+ * grab the literal value on init(), then repeatedly use
+ * that during render().
+ *
+ * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
+ * @version $Id: Literal.java,v 1.7.4.1 2004/03/03 23:22:56 geirm Exp $
+ */
+public class Literal extends Directive
+{
+    String literalText;
+    
+    /**
+     * Return name of this directive.
+     */
+    public String getName()
+    {
+        return "literal";
+    }        
+    
+    /**
+     * Return type of this directive.
+     */
+    public int getType()
+    {
+        return BLOCK;
+    }        
+
+    /**
+     * Store the literal rendition of a node using
+     * the Node.literal().
+     */
+    public void init(RuntimeServices rs, InternalContextAdapter context,
+                     Node node)
+        throws Exception
+    {
+        super.init( rs, context, node );
+
+        literalText = node.jjtGetChild(0).literal();
+    }    
+
+    /**
+     * Throw the literal rendition of the block between
+     * #literal()/#end into the writer.
+     */
+    public boolean render( InternalContextAdapter context, 
+                           Writer writer, Node node)
+        throws IOException
+    {
+        writer.write(literalText);
+        return true;
+    }
+}

Propchange: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/Literal.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/MacroParseException.java
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/MacroParseException.java?rev=1343781&view=auto
==============================================================================
--- incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/MacroParseException.java (added)
+++ incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/MacroParseException.java Tue May 29 15:35:01 2012
@@ -0,0 +1,35 @@
+package org.apache.velocity.runtime.directive;
+
+/*
+ * Copyright 2002,2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.runtime.parser.ParseException;
+
+/**
+ *  Exception to indicate problem happened while constructing #macro()
+ *
+ *  For internal use in parser - not to be passed to app level
+ *
+ * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
+ * @version $Id: MacroParseException.java,v 1.1.4.1 2004/03/03 23:22:56 geirm Exp $
+ */
+public class MacroParseException extends ParseException
+{
+    public MacroParseException(String msg)
+    {
+        super(msg);
+    }
+}

Propchange: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/MacroParseException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/Parse.java
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/Parse.java?rev=1343781&view=auto
==============================================================================
--- incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/Parse.java (added)
+++ incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/Parse.java Tue May 29 15:35:01 2012
@@ -0,0 +1,205 @@
+package org.apache.velocity.runtime.directive;
+
+/*
+ * Copyright 2000-2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.IOException;
+import java.io.Writer;
+
+import org.apache.velocity.context.InternalContextAdapter;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.runtime.RuntimeConstants;
+import org.apache.velocity.runtime.parser.node.Node;
+import org.apache.velocity.runtime.parser.node.SimpleNode;
+
+import org.apache.velocity.exception.MethodInvocationException;
+import org.apache.velocity.exception.ParseErrorException;
+import org.apache.velocity.exception.ResourceNotFoundException;
+
+/**
+ * Pluggable directive that handles the <code>#parse()</code>
+ * statement in VTL.
+ *
+ * <pre>
+ * Notes:
+ * -----
+ *  1) The parsed source material can only come from somewhere in 
+ *    the TemplateRoot tree for security reasons. There is no way 
+ *    around this.  If you want to include content from elsewhere on
+ *    your disk, use a link from somwhere under Template Root to that 
+ *    content.
+ *
+ *  2) There is a limited parse depth.  It is set as a property 
+ *    "parse_directive.maxdepth = 10"  for example.  There is a 20 iteration
+ *    safety in the event that the parameter isn't set.
+ * </pre>
+ *
+ * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
+ * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
+ * @author <a href="mailto:Christoph.Reck@dlr.de">Christoph Reck</a>
+ * @version $Id: Parse.java,v 1.27.4.1 2004/03/03 23:22:56 geirm Exp $
+ */
+public class Parse extends InputBase
+{
+    private boolean ready = false;
+
+    /**
+     * Return name of this directive.
+     */
+    public String getName()
+    {
+        return "parse";
+    }        
+    
+    /**
+     * Return type of this directive.
+     */
+    public int getType()
+    {
+        return LINE;
+    }        
+    
+    /**
+     *  iterates through the argument list and renders every
+     *  argument that is appropriate.  Any non appropriate
+     *  arguments are logged, but render() continues.
+     */
+    public boolean render( InternalContextAdapter context, 
+                           Writer writer, Node node)
+        throws IOException, ResourceNotFoundException, ParseErrorException,
+               MethodInvocationException
+    {
+        /*
+         *  did we get an argument?
+         */
+        if ( node.jjtGetChild(0) == null)
+        {
+            rsvc.error( "#parse() error :  null argument" );
+            return false;
+        }
+        
+        /*
+         *  does it have a value?  If you have a null reference, then no.
+         */
+        Object value =  node.jjtGetChild(0).value( context );
+
+        if ( value == null)
+        {
+            rsvc.error( "#parse() error :  null argument" );
+            return  false;
+        }
+
+        /*
+         *  get the path
+         */
+        String arg = value.toString();
+        
+        /*
+         *   see if we have exceeded the configured depth.
+         *   If it isn't configured, put a stop at 20 just in case.
+         */
+
+        Object[] templateStack = context.getTemplateNameStack();
+
+        if ( templateStack.length >= 
+                rsvc.getInt(RuntimeConstants.PARSE_DIRECTIVE_MAXDEPTH, 20) )
+        {
+            StringBuffer path = new StringBuffer();
+
+            for( int i = 0; i < templateStack.length; ++i)
+            {
+                path.append( " > " + templateStack[i] );
+            }
+
+            rsvc.error( "Max recursion depth reached (" + 
+                templateStack.length + ")"  + " File stack:" + path );
+            return false;
+        }
+
+        /*
+         *  now use the Runtime resource loader to get the template
+         */
+       
+        Template t = null;
+
+        try 
+        {
+            t = rsvc.getTemplate( arg, getInputEncoding(context) );
+        }
+        catch ( ResourceNotFoundException rnfe )
+        {
+       		/*
+       		 * the arg wasn't found.  Note it and throw
+       		 */
+       		 
+        	rsvc.error("#parse(): cannot find template '" + arg +
+                       "', called from template " +
+                       context.getCurrentTemplateName() + " at (" +
+                       getLine() + ", " + getColumn() + ")" );
+        	throw rnfe;
+        }
+        catch ( ParseErrorException pee )
+        {
+        	/*
+        	 * the arg was found, but didn't parse - syntax error
+        	 *  note it and throw
+        	 */
+
+        	rsvc.error("#parse(): syntax error in #parse()-ed template '" +
+                       arg + "', called from template " +
+                       context.getCurrentTemplateName() + " at (" +
+                       getLine() + ", " + getColumn() + ")" );
+        		
+        	throw pee;
+        } 
+        catch ( Exception e)
+        {	
+        	rsvc.error("#parse() : arg = " + arg + ".  Exception : " + e);
+            return false;
+        }
+    
+        /*
+         *  and render it
+         */
+        try
+        {
+            context.pushCurrentTemplateName(arg);
+            ((SimpleNode) t.getData()).render( context, writer );
+        }
+        catch ( Exception e )
+        {        
+            /*
+             *  if it's a MIE, it came from the render.... throw it...
+             */
+
+            if ( e instanceof MethodInvocationException)
+            {
+                throw (MethodInvocationException) e;
+            }
+
+            rsvc.error( "Exception rendering #parse( " + arg + " )  : " + e );
+            return false;
+        }
+        finally
+        {
+            context.popCurrentTemplateName();
+        }
+
+        return true;
+    }
+}
+

Propchange: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/Parse.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/ParseDirectiveException.java
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/ParseDirectiveException.java?rev=1343781&view=auto
==============================================================================
--- incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/ParseDirectiveException.java (added)
+++ incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/ParseDirectiveException.java Tue May 29 15:35:01 2012
@@ -0,0 +1,75 @@
+package org.apache.velocity.runtime.directive;
+
+/*
+ * Copyright 2000-2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.util.Stack;
+
+/**
+ * Exception for #parse() problems
+ *
+ * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
+ * @version $Id: ParseDirectiveException.java,v 1.4.14.1 2004/03/03 23:22:56 geirm Exp $
+ */
+public class ParseDirectiveException extends Exception
+{
+    private Stack filenameStack = new Stack();
+    private String msg = "";
+    private int depthCount = 0;
+
+    /**
+     * Constructor
+     */
+    ParseDirectiveException( String m, int i )
+    {
+        msg = m;
+        depthCount = i;
+    }
+
+    /**
+     * Get a message.
+     */
+    public String getMessage()
+    {
+        String returnStr  =  "#parse() exception : depth = " + 
+            depthCount + " -> " + msg;
+
+        returnStr += " File stack : ";
+
+        try
+        {
+            while( !filenameStack.empty())
+            {
+                returnStr += (String) filenameStack.pop();
+                returnStr += " -> ";
+            }
+        }
+        catch( Exception e)
+        {
+        }
+
+        return returnStr;
+    }
+
+    /**
+     * Add a file to the filename stack
+     */
+    public void addFile( String s )
+    {
+        filenameStack.push( s );
+    }
+
+}

Propchange: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/runtime/directive/ParseDirectiveException.java
------------------------------------------------------------------------------
    svn:eol-style = native