You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@velocity.apache.org by ap...@apache.org on 2010/12/01 13:15:41 UTC

svn commit: r1040976 [2/2] - in /velocity/engine/trunk/velocity-engine-core: ./ src/main/java/org/apache/velocity/app/event/implement/ src/main/java/org/apache/velocity/runtime/ src/main/java/org/apache/velocity/runtime/directive/ src/main/java/org/apa...

Added: velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/thirdparty/commons/lang/Entities.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/thirdparty/commons/lang/Entities.java?rev=1040976&view=auto
==============================================================================
--- velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/thirdparty/commons/lang/Entities.java (added)
+++ velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/thirdparty/commons/lang/Entities.java Wed Dec  1 12:15:39 2010
@@ -0,0 +1,992 @@
+/*
+ * 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.
+ */
+
+package org.apache.velocity.thirdparty.commons.lang;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * Copied and edited from Apache Commons Lang 2.4.
+ *
+ * <p>
+ * Provides HTML and XML entity utilities.
+ * </p>
+ *
+ * @see <a href="http://hotwired.lycos.com/webmonkey/reference/special_characters/">ISO Entities</a>
+ * @see <a href="http://www.w3.org/TR/REC-html32#latin1">HTML 3.2 Character Entities for ISO Latin-1</a>
+ * @see <a href="http://www.w3.org/TR/REC-html40/sgml/entities.html">HTML 4.0 Character entity references</a>
+ * @see <a href="http://www.w3.org/TR/html401/charset.html#h-5.3">HTML 4.01 Character References</a>
+ * @see <a href="http://www.w3.org/TR/html401/charset.html#code-position">HTML 4.01 Code positions</a>
+ *
+ * @author <a href="mailto:alex@purpletech.com">Alexander Day Chaffee</a>
+ * @author <a href="mailto:ggregory@seagullsw.com">Gary Gregory</a>
+ * @since 2.0
+ * @version $Id: Entities.java 636641 2008-03-13 06:11:30Z bayard $
+ */
+class Entities {
+
+    private static final String[][] BASIC_ARRAY = {{"quot", "34"}, // " - double-quote
+        {"amp", "38"}, // & - ampersand
+        {"lt", "60"}, // < - less-than
+        {"gt", "62"}, // > - greater-than
+    };
+
+    private static final String[][] APOS_ARRAY = {{"apos", "39"}, // XML apostrophe
+    };
+
+    // package scoped for testing
+    static final String[][] ISO8859_1_ARRAY = {{"nbsp", "160"}, // non-breaking space
+        {"iexcl", "161"}, // inverted exclamation mark
+        {"cent", "162"}, // cent sign
+        {"pound", "163"}, // pound sign
+        {"curren", "164"}, // currency sign
+        {"yen", "165"}, // yen sign = yuan sign
+        {"brvbar", "166"}, // broken bar = broken vertical bar
+        {"sect", "167"}, // section sign
+        {"uml", "168"}, // diaeresis = spacing diaeresis
+        {"copy", "169"}, // � - copyright sign
+        {"ordf", "170"}, // feminine ordinal indicator
+        {"laquo", "171"}, // left-pointing double angle quotation mark = left pointing guillemet
+        {"not", "172"}, // not sign
+        {"shy", "173"}, // soft hyphen = discretionary hyphen
+        {"reg", "174"}, // � - registered trademark sign
+        {"macr", "175"}, // macron = spacing macron = overline = APL overbar
+        {"deg", "176"}, // degree sign
+        {"plusmn", "177"}, // plus-minus sign = plus-or-minus sign
+        {"sup2", "178"}, // superscript two = superscript digit two = squared
+        {"sup3", "179"}, // superscript three = superscript digit three = cubed
+        {"acute", "180"}, // acute accent = spacing acute
+        {"micro", "181"}, // micro sign
+        {"para", "182"}, // pilcrow sign = paragraph sign
+        {"middot", "183"}, // middle dot = Georgian comma = Greek middle dot
+        {"cedil", "184"}, // cedilla = spacing cedilla
+        {"sup1", "185"}, // superscript one = superscript digit one
+        {"ordm", "186"}, // masculine ordinal indicator
+        {"raquo", "187"}, // right-pointing double angle quotation mark = right pointing guillemet
+        {"frac14", "188"}, // vulgar fraction one quarter = fraction one quarter
+        {"frac12", "189"}, // vulgar fraction one half = fraction one half
+        {"frac34", "190"}, // vulgar fraction three quarters = fraction three quarters
+        {"iquest", "191"}, // inverted question mark = turned question mark
+        {"Agrave", "192"}, // � - uppercase A, grave accent
+        {"Aacute", "193"}, // � - uppercase A, acute accent
+        {"Acirc", "194"}, // � - uppercase A, circumflex accent
+        {"Atilde", "195"}, // � - uppercase A, tilde
+        {"Auml", "196"}, // � - uppercase A, umlaut
+        {"Aring", "197"}, // � - uppercase A, ring
+        {"AElig", "198"}, // � - uppercase AE
+        {"Ccedil", "199"}, // � - uppercase C, cedilla
+        {"Egrave", "200"}, // � - uppercase E, grave accent
+        {"Eacute", "201"}, // � - uppercase E, acute accent
+        {"Ecirc", "202"}, // � - uppercase E, circumflex accent
+        {"Euml", "203"}, // � - uppercase E, umlaut
+        {"Igrave", "204"}, // � - uppercase I, grave accent
+        {"Iacute", "205"}, // � - uppercase I, acute accent
+        {"Icirc", "206"}, // � - uppercase I, circumflex accent
+        {"Iuml", "207"}, // � - uppercase I, umlaut
+        {"ETH", "208"}, // � - uppercase Eth, Icelandic
+        {"Ntilde", "209"}, // � - uppercase N, tilde
+        {"Ograve", "210"}, // � - uppercase O, grave accent
+        {"Oacute", "211"}, // � - uppercase O, acute accent
+        {"Ocirc", "212"}, // � - uppercase O, circumflex accent
+        {"Otilde", "213"}, // � - uppercase O, tilde
+        {"Ouml", "214"}, // � - uppercase O, umlaut
+        {"times", "215"}, // multiplication sign
+        {"Oslash", "216"}, // � - uppercase O, slash
+        {"Ugrave", "217"}, // � - uppercase U, grave accent
+        {"Uacute", "218"}, // � - uppercase U, acute accent
+        {"Ucirc", "219"}, // � - uppercase U, circumflex accent
+        {"Uuml", "220"}, // � - uppercase U, umlaut
+        {"Yacute", "221"}, // � - uppercase Y, acute accent
+        {"THORN", "222"}, // � - uppercase THORN, Icelandic
+        {"szlig", "223"}, // � - lowercase sharps, German
+        {"agrave", "224"}, // � - lowercase a, grave accent
+        {"aacute", "225"}, // � - lowercase a, acute accent
+        {"acirc", "226"}, // � - lowercase a, circumflex accent
+        {"atilde", "227"}, // � - lowercase a, tilde
+        {"auml", "228"}, // � - lowercase a, umlaut
+        {"aring", "229"}, // � - lowercase a, ring
+        {"aelig", "230"}, // � - lowercase ae
+        {"ccedil", "231"}, // � - lowercase c, cedilla
+        {"egrave", "232"}, // � - lowercase e, grave accent
+        {"eacute", "233"}, // � - lowercase e, acute accent
+        {"ecirc", "234"}, // � - lowercase e, circumflex accent
+        {"euml", "235"}, // � - lowercase e, umlaut
+        {"igrave", "236"}, // � - lowercase i, grave accent
+        {"iacute", "237"}, // � - lowercase i, acute accent
+        {"icirc", "238"}, // � - lowercase i, circumflex accent
+        {"iuml", "239"}, // � - lowercase i, umlaut
+        {"eth", "240"}, // � - lowercase eth, Icelandic
+        {"ntilde", "241"}, // � - lowercase n, tilde
+        {"ograve", "242"}, // � - lowercase o, grave accent
+        {"oacute", "243"}, // � - lowercase o, acute accent
+        {"ocirc", "244"}, // � - lowercase o, circumflex accent
+        {"otilde", "245"}, // � - lowercase o, tilde
+        {"ouml", "246"}, // � - lowercase o, umlaut
+        {"divide", "247"}, // division sign
+        {"oslash", "248"}, // � - lowercase o, slash
+        {"ugrave", "249"}, // � - lowercase u, grave accent
+        {"uacute", "250"}, // � - lowercase u, acute accent
+        {"ucirc", "251"}, // � - lowercase u, circumflex accent
+        {"uuml", "252"}, // � - lowercase u, umlaut
+        {"yacute", "253"}, // � - lowercase y, acute accent
+        {"thorn", "254"}, // � - lowercase thorn, Icelandic
+        {"yuml", "255"}, // � - lowercase y, umlaut
+    };
+
+    // http://www.w3.org/TR/REC-html40/sgml/entities.html
+    // package scoped for testing
+    static final String[][] HTML40_ARRAY = {
+    // <!-- Latin Extended-B -->
+        {"fnof", "402"}, // latin small f with hook = function= florin, U+0192 ISOtech -->
+        // <!-- Greek -->
+        {"Alpha", "913"}, // greek capital letter alpha, U+0391 -->
+        {"Beta", "914"}, // greek capital letter beta, U+0392 -->
+        {"Gamma", "915"}, // greek capital letter gamma,U+0393 ISOgrk3 -->
+        {"Delta", "916"}, // greek capital letter delta,U+0394 ISOgrk3 -->
+        {"Epsilon", "917"}, // greek capital letter epsilon, U+0395 -->
+        {"Zeta", "918"}, // greek capital letter zeta, U+0396 -->
+        {"Eta", "919"}, // greek capital letter eta, U+0397 -->
+        {"Theta", "920"}, // greek capital letter theta,U+0398 ISOgrk3 -->
+        {"Iota", "921"}, // greek capital letter iota, U+0399 -->
+        {"Kappa", "922"}, // greek capital letter kappa, U+039A -->
+        {"Lambda", "923"}, // greek capital letter lambda,U+039B ISOgrk3 -->
+        {"Mu", "924"}, // greek capital letter mu, U+039C -->
+        {"Nu", "925"}, // greek capital letter nu, U+039D -->
+        {"Xi", "926"}, // greek capital letter xi, U+039E ISOgrk3 -->
+        {"Omicron", "927"}, // greek capital letter omicron, U+039F -->
+        {"Pi", "928"}, // greek capital letter pi, U+03A0 ISOgrk3 -->
+        {"Rho", "929"}, // greek capital letter rho, U+03A1 -->
+        // <!-- there is no Sigmaf, and no U+03A2 character either -->
+        {"Sigma", "931"}, // greek capital letter sigma,U+03A3 ISOgrk3 -->
+        {"Tau", "932"}, // greek capital letter tau, U+03A4 -->
+        {"Upsilon", "933"}, // greek capital letter upsilon,U+03A5 ISOgrk3 -->
+        {"Phi", "934"}, // greek capital letter phi,U+03A6 ISOgrk3 -->
+        {"Chi", "935"}, // greek capital letter chi, U+03A7 -->
+        {"Psi", "936"}, // greek capital letter psi,U+03A8 ISOgrk3 -->
+        {"Omega", "937"}, // greek capital letter omega,U+03A9 ISOgrk3 -->
+        {"alpha", "945"}, // greek small letter alpha,U+03B1 ISOgrk3 -->
+        {"beta", "946"}, // greek small letter beta, U+03B2 ISOgrk3 -->
+        {"gamma", "947"}, // greek small letter gamma,U+03B3 ISOgrk3 -->
+        {"delta", "948"}, // greek small letter delta,U+03B4 ISOgrk3 -->
+        {"epsilon", "949"}, // greek small letter epsilon,U+03B5 ISOgrk3 -->
+        {"zeta", "950"}, // greek small letter zeta, U+03B6 ISOgrk3 -->
+        {"eta", "951"}, // greek small letter eta, U+03B7 ISOgrk3 -->
+        {"theta", "952"}, // greek small letter theta,U+03B8 ISOgrk3 -->
+        {"iota", "953"}, // greek small letter iota, U+03B9 ISOgrk3 -->
+        {"kappa", "954"}, // greek small letter kappa,U+03BA ISOgrk3 -->
+        {"lambda", "955"}, // greek small letter lambda,U+03BB ISOgrk3 -->
+        {"mu", "956"}, // greek small letter mu, U+03BC ISOgrk3 -->
+        {"nu", "957"}, // greek small letter nu, U+03BD ISOgrk3 -->
+        {"xi", "958"}, // greek small letter xi, U+03BE ISOgrk3 -->
+        {"omicron", "959"}, // greek small letter omicron, U+03BF NEW -->
+        {"pi", "960"}, // greek small letter pi, U+03C0 ISOgrk3 -->
+        {"rho", "961"}, // greek small letter rho, U+03C1 ISOgrk3 -->
+        {"sigmaf", "962"}, // greek small letter final sigma,U+03C2 ISOgrk3 -->
+        {"sigma", "963"}, // greek small letter sigma,U+03C3 ISOgrk3 -->
+        {"tau", "964"}, // greek small letter tau, U+03C4 ISOgrk3 -->
+        {"upsilon", "965"}, // greek small letter upsilon,U+03C5 ISOgrk3 -->
+        {"phi", "966"}, // greek small letter phi, U+03C6 ISOgrk3 -->
+        {"chi", "967"}, // greek small letter chi, U+03C7 ISOgrk3 -->
+        {"psi", "968"}, // greek small letter psi, U+03C8 ISOgrk3 -->
+        {"omega", "969"}, // greek small letter omega,U+03C9 ISOgrk3 -->
+        {"thetasym", "977"}, // greek small letter theta symbol,U+03D1 NEW -->
+        {"upsih", "978"}, // greek upsilon with hook symbol,U+03D2 NEW -->
+        {"piv", "982"}, // greek pi symbol, U+03D6 ISOgrk3 -->
+        // <!-- General Punctuation -->
+        {"bull", "8226"}, // bullet = black small circle,U+2022 ISOpub -->
+        // <!-- bullet is NOT the same as bullet operator, U+2219 -->
+        {"hellip", "8230"}, // horizontal ellipsis = three dot leader,U+2026 ISOpub -->
+        {"prime", "8242"}, // prime = minutes = feet, U+2032 ISOtech -->
+        {"Prime", "8243"}, // double prime = seconds = inches,U+2033 ISOtech -->
+        {"oline", "8254"}, // overline = spacing overscore,U+203E NEW -->
+        {"frasl", "8260"}, // fraction slash, U+2044 NEW -->
+        // <!-- Letterlike Symbols -->
+        {"weierp", "8472"}, // script capital P = power set= Weierstrass p, U+2118 ISOamso -->
+        {"image", "8465"}, // blackletter capital I = imaginary part,U+2111 ISOamso -->
+        {"real", "8476"}, // blackletter capital R = real part symbol,U+211C ISOamso -->
+        {"trade", "8482"}, // trade mark sign, U+2122 ISOnum -->
+        {"alefsym", "8501"}, // alef symbol = first transfinite cardinal,U+2135 NEW -->
+        // <!-- alef symbol is NOT the same as hebrew letter alef,U+05D0 although the
+        // same glyph could be used to depict both characters -->
+        // <!-- Arrows -->
+        {"larr", "8592"}, // leftwards arrow, U+2190 ISOnum -->
+        {"uarr", "8593"}, // upwards arrow, U+2191 ISOnum-->
+        {"rarr", "8594"}, // rightwards arrow, U+2192 ISOnum -->
+        {"darr", "8595"}, // downwards arrow, U+2193 ISOnum -->
+        {"harr", "8596"}, // left right arrow, U+2194 ISOamsa -->
+        {"crarr", "8629"}, // downwards arrow with corner leftwards= carriage return, U+21B5 NEW -->
+        {"lArr", "8656"}, // leftwards double arrow, U+21D0 ISOtech -->
+        // <!-- ISO 10646 does not say that lArr is the same as the 'is implied by'
+        // arrow but also does not have any other character for that function.
+        // So ? lArr canbe used for 'is implied by' as ISOtech suggests -->
+        {"uArr", "8657"}, // upwards double arrow, U+21D1 ISOamsa -->
+        {"rArr", "8658"}, // rightwards double arrow,U+21D2 ISOtech -->
+        // <!-- ISO 10646 does not say this is the 'implies' character but does not
+        // have another character with this function so ?rArr can be used for
+        // 'implies' as ISOtech suggests -->
+        {"dArr", "8659"}, // downwards double arrow, U+21D3 ISOamsa -->
+        {"hArr", "8660"}, // left right double arrow,U+21D4 ISOamsa -->
+        // <!-- Mathematical Operators -->
+        {"forall", "8704"}, // for all, U+2200 ISOtech -->
+        {"part", "8706"}, // partial differential, U+2202 ISOtech -->
+        {"exist", "8707"}, // there exists, U+2203 ISOtech -->
+        {"empty", "8709"}, // empty set = null set = diameter,U+2205 ISOamso -->
+        {"nabla", "8711"}, // nabla = backward difference,U+2207 ISOtech -->
+        {"isin", "8712"}, // element of, U+2208 ISOtech -->
+        {"notin", "8713"}, // not an element of, U+2209 ISOtech -->
+        {"ni", "8715"}, // contains as member, U+220B ISOtech -->
+        // <!-- should there be a more memorable name than 'ni'? -->
+        {"prod", "8719"}, // n-ary product = product sign,U+220F ISOamsb -->
+        // <!-- prod is NOT the same character as U+03A0 'greek capital letter pi'
+        // though the same glyph might be used for both -->
+        {"sum", "8721"}, // n-ary summation, U+2211 ISOamsb -->
+        // <!-- sum is NOT the same character as U+03A3 'greek capital letter sigma'
+        // though the same glyph might be used for both -->
+        {"minus", "8722"}, // minus sign, U+2212 ISOtech -->
+        {"lowast", "8727"}, // asterisk operator, U+2217 ISOtech -->
+        {"radic", "8730"}, // square root = radical sign,U+221A ISOtech -->
+        {"prop", "8733"}, // proportional to, U+221D ISOtech -->
+        {"infin", "8734"}, // infinity, U+221E ISOtech -->
+        {"ang", "8736"}, // angle, U+2220 ISOamso -->
+        {"and", "8743"}, // logical and = wedge, U+2227 ISOtech -->
+        {"or", "8744"}, // logical or = vee, U+2228 ISOtech -->
+        {"cap", "8745"}, // intersection = cap, U+2229 ISOtech -->
+        {"cup", "8746"}, // union = cup, U+222A ISOtech -->
+        {"int", "8747"}, // integral, U+222B ISOtech -->
+        {"there4", "8756"}, // therefore, U+2234 ISOtech -->
+        {"sim", "8764"}, // tilde operator = varies with = similar to,U+223C ISOtech -->
+        // <!-- tilde operator is NOT the same character as the tilde, U+007E,although
+        // the same glyph might be used to represent both -->
+        {"cong", "8773"}, // approximately equal to, U+2245 ISOtech -->
+        {"asymp", "8776"}, // almost equal to = asymptotic to,U+2248 ISOamsr -->
+        {"ne", "8800"}, // not equal to, U+2260 ISOtech -->
+        {"equiv", "8801"}, // identical to, U+2261 ISOtech -->
+        {"le", "8804"}, // less-than or equal to, U+2264 ISOtech -->
+        {"ge", "8805"}, // greater-than or equal to,U+2265 ISOtech -->
+        {"sub", "8834"}, // subset of, U+2282 ISOtech -->
+        {"sup", "8835"}, // superset of, U+2283 ISOtech -->
+        // <!-- note that nsup, 'not a superset of, U+2283' is not covered by the
+        // Symbol font encoding and is not included. Should it be, for symmetry?
+        // It is in ISOamsn --> <!ENTITY nsub", "8836"},
+        // not a subset of, U+2284 ISOamsn -->
+        {"sube", "8838"}, // subset of or equal to, U+2286 ISOtech -->
+        {"supe", "8839"}, // superset of or equal to,U+2287 ISOtech -->
+        {"oplus", "8853"}, // circled plus = direct sum,U+2295 ISOamsb -->
+        {"otimes", "8855"}, // circled times = vector product,U+2297 ISOamsb -->
+        {"perp", "8869"}, // up tack = orthogonal to = perpendicular,U+22A5 ISOtech -->
+        {"sdot", "8901"}, // dot operator, U+22C5 ISOamsb -->
+        // <!-- dot operator is NOT the same character as U+00B7 middle dot -->
+        // <!-- Miscellaneous Technical -->
+        {"lceil", "8968"}, // left ceiling = apl upstile,U+2308 ISOamsc -->
+        {"rceil", "8969"}, // right ceiling, U+2309 ISOamsc -->
+        {"lfloor", "8970"}, // left floor = apl downstile,U+230A ISOamsc -->
+        {"rfloor", "8971"}, // right floor, U+230B ISOamsc -->
+        {"lang", "9001"}, // left-pointing angle bracket = bra,U+2329 ISOtech -->
+        // <!-- lang is NOT the same character as U+003C 'less than' or U+2039 'single left-pointing angle quotation
+        // mark' -->
+        {"rang", "9002"}, // right-pointing angle bracket = ket,U+232A ISOtech -->
+        // <!-- rang is NOT the same character as U+003E 'greater than' or U+203A
+        // 'single right-pointing angle quotation mark' -->
+        // <!-- Geometric Shapes -->
+        {"loz", "9674"}, // lozenge, U+25CA ISOpub -->
+        // <!-- Miscellaneous Symbols -->
+        {"spades", "9824"}, // black spade suit, U+2660 ISOpub -->
+        // <!-- black here seems to mean filled as opposed to hollow -->
+        {"clubs", "9827"}, // black club suit = shamrock,U+2663 ISOpub -->
+        {"hearts", "9829"}, // black heart suit = valentine,U+2665 ISOpub -->
+        {"diams", "9830"}, // black diamond suit, U+2666 ISOpub -->
+
+        // <!-- Latin Extended-A -->
+        {"OElig", "338"}, // -- latin capital ligature OE,U+0152 ISOlat2 -->
+        {"oelig", "339"}, // -- latin small ligature oe, U+0153 ISOlat2 -->
+        // <!-- ligature is a misnomer, this is a separate character in some languages -->
+        {"Scaron", "352"}, // -- latin capital letter S with caron,U+0160 ISOlat2 -->
+        {"scaron", "353"}, // -- latin small letter s with caron,U+0161 ISOlat2 -->
+        {"Yuml", "376"}, // -- latin capital letter Y with diaeresis,U+0178 ISOlat2 -->
+        // <!-- Spacing Modifier Letters -->
+        {"circ", "710"}, // -- modifier letter circumflex accent,U+02C6 ISOpub -->
+        {"tilde", "732"}, // small tilde, U+02DC ISOdia -->
+        // <!-- General Punctuation -->
+        {"ensp", "8194"}, // en space, U+2002 ISOpub -->
+        {"emsp", "8195"}, // em space, U+2003 ISOpub -->
+        {"thinsp", "8201"}, // thin space, U+2009 ISOpub -->
+        {"zwnj", "8204"}, // zero width non-joiner,U+200C NEW RFC 2070 -->
+        {"zwj", "8205"}, // zero width joiner, U+200D NEW RFC 2070 -->
+        {"lrm", "8206"}, // left-to-right mark, U+200E NEW RFC 2070 -->
+        {"rlm", "8207"}, // right-to-left mark, U+200F NEW RFC 2070 -->
+        {"ndash", "8211"}, // en dash, U+2013 ISOpub -->
+        {"mdash", "8212"}, // em dash, U+2014 ISOpub -->
+        {"lsquo", "8216"}, // left single quotation mark,U+2018 ISOnum -->
+        {"rsquo", "8217"}, // right single quotation mark,U+2019 ISOnum -->
+        {"sbquo", "8218"}, // single low-9 quotation mark, U+201A NEW -->
+        {"ldquo", "8220"}, // left double quotation mark,U+201C ISOnum -->
+        {"rdquo", "8221"}, // right double quotation mark,U+201D ISOnum -->
+        {"bdquo", "8222"}, // double low-9 quotation mark, U+201E NEW -->
+        {"dagger", "8224"}, // dagger, U+2020 ISOpub -->
+        {"Dagger", "8225"}, // double dagger, U+2021 ISOpub -->
+        {"permil", "8240"}, // per mille sign, U+2030 ISOtech -->
+        {"lsaquo", "8249"}, // single left-pointing angle quotation mark,U+2039 ISO proposed -->
+        // <!-- lsaquo is proposed but not yet ISO standardized -->
+        {"rsaquo", "8250"}, // single right-pointing angle quotation mark,U+203A ISO proposed -->
+        // <!-- rsaquo is proposed but not yet ISO standardized -->
+        {"euro", "8364"}, // -- euro sign, U+20AC NEW -->
+    };
+
+    /**
+     * <p>
+     * The set of entities supported by standard XML.
+     * </p>
+     */
+    public static final Entities XML;
+
+    /**
+     * <p>
+     * The set of entities supported by HTML 3.2.
+     * </p>
+     */
+    public static final Entities HTML32;
+
+    /**
+     * <p>
+     * The set of entities supported by HTML 4.0.
+     * </p>
+     */
+    public static final Entities HTML40;
+
+    static {
+        XML = new Entities();
+        XML.addEntities(BASIC_ARRAY);
+        XML.addEntities(APOS_ARRAY);
+    }
+
+    static {
+        HTML32 = new Entities();
+        HTML32.addEntities(BASIC_ARRAY);
+        HTML32.addEntities(ISO8859_1_ARRAY);
+    }
+
+    static {
+        HTML40 = new Entities();
+        fillWithHtml40Entities(HTML40);
+    }
+
+    /**
+     * <p>
+     * Fills the specified entities instance with HTML 40 entities.
+     * </p>
+     *
+     * @param entities
+     *            the instance to be filled.
+     */
+    static void fillWithHtml40Entities(Entities entities) {
+        entities.addEntities(BASIC_ARRAY);
+        entities.addEntities(ISO8859_1_ARRAY);
+        entities.addEntities(HTML40_ARRAY);
+    }
+
+    static interface EntityMap {
+        /**
+         * <p>
+         * Add an entry to this entity map.
+         * </p>
+         *
+         * @param name
+         *            the entity name
+         * @param value
+         *            the entity value
+         */
+        void add(String name, int value);
+
+        /**
+         * <p>
+         * Returns the name of the entity identified by the specified value.
+         * </p>
+         *
+         * @param value
+         *            the value to locate
+         * @return entity name associated with the specified value
+         */
+        String name(int value);
+
+        /**
+         * <p>
+         * Returns the value of the entity identified by the specified name.
+         * </p>
+         *
+         * @param name
+         *            the name to locate
+         * @return entity value associated with the specified name
+         */
+        int value(String name);
+    }
+
+    static class PrimitiveEntityMap implements EntityMap {
+        private Map<String, Integer> mapNameToValue = new HashMap<String, Integer>();
+
+        private Map<Integer, String> mapValueToName = new HashMap<Integer, String>();
+
+        /**
+         * {@inheritDoc}
+         */
+        public void add(String name, int value) {
+            mapNameToValue.put(name, new Integer(value));
+            mapValueToName.put(value, name);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String name(int value) {
+            return (String) mapValueToName.get(value);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public int value(String name) {
+            Object value = mapNameToValue.get(name);
+            if (value == null) {
+                return -1;
+            }
+            return ((Integer) value).intValue();
+        }
+    }
+
+    static abstract class MapIntMap implements Entities.EntityMap {
+        protected Map<String, Integer> mapNameToValue;
+
+        protected Map<Integer, String> mapValueToName;
+
+        /**
+         * {@inheritDoc}
+         */
+        public void add(String name, int value) {
+            mapNameToValue.put(name, new Integer(value));
+            mapValueToName.put(new Integer(value), name);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String name(int value) {
+            return (String) mapValueToName.get(new Integer(value));
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public int value(String name) {
+            Object value = mapNameToValue.get(name);
+            if (value == null) {
+                return -1;
+            }
+            return ((Integer) value).intValue();
+        }
+    }
+
+    static class HashEntityMap extends MapIntMap {
+        /**
+         * Constructs a new instance of <code>HashEntityMap</code>.
+         */
+        public HashEntityMap() {
+            mapNameToValue = new HashMap<String, Integer>();
+            mapValueToName = new HashMap<Integer, String>();
+        }
+    }
+
+    static class TreeEntityMap extends MapIntMap {
+        /**
+         * Constructs a new instance of <code>TreeEntityMap</code>.
+         */
+        public TreeEntityMap() {
+            mapNameToValue = new TreeMap<String, Integer>();
+            mapValueToName = new TreeMap<Integer, String>();
+        }
+    }
+
+    static class LookupEntityMap extends PrimitiveEntityMap {
+        private String[] lookupTable;
+
+        private int LOOKUP_TABLE_SIZE = 256;
+
+        /**
+         * {@inheritDoc}
+         */
+        public String name(int value) {
+            if (value < LOOKUP_TABLE_SIZE) {
+                return lookupTable()[value];
+            }
+            return super.name(value);
+        }
+
+        /**
+         * <p>
+         * Returns the lookup table for this entity map. The lookup table is created if it has not been previously.
+         * </p>
+         *
+         * @return the lookup table
+         */
+        private String[] lookupTable() {
+            if (lookupTable == null) {
+                createLookupTable();
+            }
+            return lookupTable;
+        }
+
+        /**
+         * <p>
+         * Creates an entity lookup table of LOOKUP_TABLE_SIZE elements, initialized with entity names.
+         * </p>
+         */
+        private void createLookupTable() {
+            lookupTable = new String[LOOKUP_TABLE_SIZE];
+            for (int i = 0; i < LOOKUP_TABLE_SIZE; ++i) {
+                lookupTable[i] = super.name(i);
+            }
+        }
+    }
+
+    static class ArrayEntityMap implements EntityMap {
+        protected int growBy = 100;
+
+        protected int size = 0;
+
+        protected String[] names;
+
+        protected int[] values;
+
+        /**
+         * Constructs a new instance of <code>ArrayEntityMap</code>.
+         */
+        public ArrayEntityMap() {
+            names = new String[growBy];
+            values = new int[growBy];
+        }
+
+        /**
+         * Constructs a new instance of <code>ArrayEntityMap</code> specifying the size by which the array should
+         * grow.
+         *
+         * @param growBy
+         *            array will be initialized to and will grow by this amount
+         */
+        public ArrayEntityMap(int growBy) {
+            this.growBy = growBy;
+            names = new String[growBy];
+            values = new int[growBy];
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public void add(String name, int value) {
+            ensureCapacity(size + 1);
+            names[size] = name;
+            values[size] = value;
+            size++;
+        }
+
+        /**
+         * Verifies the capacity of the entity array, adjusting the size if necessary.
+         *
+         * @param capacity
+         *            size the array should be
+         */
+        protected void ensureCapacity(int capacity) {
+            if (capacity > names.length) {
+                int newSize = Math.max(capacity, size + growBy);
+                String[] newNames = new String[newSize];
+                System.arraycopy(names, 0, newNames, 0, size);
+                names = newNames;
+                int[] newValues = new int[newSize];
+                System.arraycopy(values, 0, newValues, 0, size);
+                values = newValues;
+            }
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String name(int value) {
+            for (int i = 0; i < size; ++i) {
+                if (values[i] == value) {
+                    return names[i];
+                }
+            }
+            return null;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public int value(String name) {
+            for (int i = 0; i < size; ++i) {
+                if (names[i].equals(name)) {
+                    return values[i];
+                }
+            }
+            return -1;
+        }
+    }
+
+    static class BinaryEntityMap extends ArrayEntityMap {
+
+        /**
+         * Constructs a new instance of <code>BinaryEntityMap</code>.
+         */
+        public BinaryEntityMap() {
+            super();
+        }
+
+        /**
+         * Constructs a new instance of <code>ArrayEntityMap</code> specifying the size by which the underlying array
+         * should grow.
+         *
+         * @param growBy
+         *            array will be initialized to and will grow by this amount
+         */
+        public BinaryEntityMap(int growBy) {
+            super(growBy);
+        }
+
+        /**
+         * Performs a binary search of the entity array for the specified key. This method is based on code in
+         * {@link java.util.Arrays}.
+         *
+         * @param key
+         *            the key to be found
+         * @return the index of the entity array matching the specified key
+         */
+        private int binarySearch(int key) {
+            int low = 0;
+            int high = size - 1;
+
+            while (low <= high) {
+                int mid = (low + high) >>> 1;
+                int midVal = values[mid];
+
+                if (midVal < key) {
+                    low = mid + 1;
+                } else if (midVal > key) {
+                    high = mid - 1;
+                } else {
+                    return mid; // key found
+                }
+            }
+            return -(low + 1); // key not found.
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public void add(String name, int value) {
+            ensureCapacity(size + 1);
+            int insertAt = binarySearch(value);
+            if (insertAt > 0) {
+                return; // note: this means you can't insert the same value twice
+            }
+            insertAt = -(insertAt + 1); // binarySearch returns it negative and off-by-one
+            System.arraycopy(values, insertAt, values, insertAt + 1, size - insertAt);
+            values[insertAt] = value;
+            System.arraycopy(names, insertAt, names, insertAt + 1, size - insertAt);
+            names[insertAt] = name;
+            size++;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String name(int value) {
+            int index = binarySearch(value);
+            if (index < 0) {
+                return null;
+            }
+            return names[index];
+        }
+    }
+
+    // package scoped for testing
+    EntityMap map = new Entities.LookupEntityMap();
+
+    /**
+     * <p>
+     * Adds entities to this entity.
+     * </p>
+     *
+     * @param entityArray
+     *            array of entities to be added
+     */
+    public void addEntities(String[][] entityArray) {
+        for (int i = 0; i < entityArray.length; ++i) {
+            addEntity(entityArray[i][0], Integer.parseInt(entityArray[i][1]));
+        }
+    }
+
+    /**
+     * <p>
+     * Add an entity to this entity.
+     * </p>
+     *
+     * @param name
+     *            name of the entity
+     * @param value
+     *            vale of the entity
+     */
+    public void addEntity(String name, int value) {
+        map.add(name, value);
+    }
+
+    /**
+     * <p>
+     * Returns the name of the entity identified by the specified value.
+     * </p>
+     *
+     * @param value
+     *            the value to locate
+     * @return entity name associated with the specified value
+     */
+    public String entityName(int value) {
+        return map.name(value);
+    }
+
+    /**
+     * <p>
+     * Returns the value of the entity identified by the specified name.
+     * </p>
+     *
+     * @param name
+     *            the name to locate
+     * @return entity value associated with the specified name
+     */
+    public int entityValue(String name) {
+        return map.value(name);
+    }
+
+    /**
+     * <p>
+     * Escapes the characters in a <code>String</code>.
+     * </p>
+     *
+     * <p>
+     * For example, if you have called addEntity(&quot;foo&quot;, 0xA1), escape(&quot;\u00A1&quot;) will return
+     * &quot;&amp;foo;&quot;
+     * </p>
+     *
+     * @param str
+     *            The <code>String</code> to escape.
+     * @return A new escaped <code>String</code>.
+     */
+    public String escape(String str) {
+        StringWriter stringWriter = createStringWriter(str);
+        try {
+            this.escape(stringWriter, str);
+        } catch (IOException e) {
+            // This should never happen because ALL the StringWriter methods called by #escape(Writer, String) do not
+            // throw IOExceptions.
+            throw new UnhandledException(e);
+        }
+        return stringWriter.toString();
+    }
+
+    /**
+     * <p>
+     * Escapes the characters in the <code>String</code> passed and writes the result to the <code>Writer</code>
+     * passed.
+     * </p>
+     *
+     * @param writer
+     *            The <code>Writer</code> to write the results of the escaping to. Assumed to be a non-null value.
+     * @param str
+     *            The <code>String</code> to escape. Assumed to be a non-null value.
+     * @throws IOException
+     *             when <code>Writer</code> passed throws the exception from calls to the {@link Writer#write(int)}
+     *             methods.
+     *
+     * @see #escape(String)
+     * @see Writer
+     */
+    public void escape(Writer writer, String str) throws IOException {
+        int len = str.length();
+        for (int i = 0; i < len; i++) {
+            char c = str.charAt(i);
+            String entityName = this.entityName(c);
+            if (entityName == null) {
+                if (c > 0x7F) {
+                    writer.write("&#");
+                    writer.write(Integer.toString(c, 10));
+                    writer.write(';');
+                } else {
+                    writer.write(c);
+                }
+            } else {
+                writer.write('&');
+                writer.write(entityName);
+                writer.write(';');
+            }
+        }
+    }
+
+    /**
+     * <p>
+     * Unescapes the entities in a <code>String</code>.
+     * </p>
+     *
+     * <p>
+     * For example, if you have called addEntity(&quot;foo&quot;, 0xA1), unescape(&quot;&amp;foo;&quot;) will return
+     * &quot;\u00A1&quot;
+     * </p>
+     *
+     * @param str
+     *            The <code>String</code> to escape.
+     * @return A new escaped <code>String</code>.
+     */
+    public String unescape(String str) {
+        int firstAmp = str.indexOf('&');
+        if (firstAmp < 0) {
+            return str;
+        } else {
+            StringWriter stringWriter = createStringWriter(str);
+            try {
+                this.doUnescape(stringWriter, str, firstAmp);
+            } catch (IOException e) {
+                // This should never happen because ALL the StringWriter methods called by #escape(Writer, String)
+                // do not throw IOExceptions.
+                throw new UnhandledException(e);
+            }
+            return stringWriter.toString();
+        }
+    }
+
+    /**
+     * Make the StringWriter 10% larger than the source String to avoid growing the writer
+     *
+     * @param str The source string
+     * @return A newly created StringWriter
+     */
+    private StringWriter createStringWriter(String str) {
+        return new StringWriter((int) (str.length() + (str.length() * 0.1)));
+    }
+
+    /**
+     * <p>
+     * Unescapes the escaped entities in the <code>String</code> passed and writes the result to the
+     * <code>Writer</code> passed.
+     * </p>
+     *
+     * @param writer
+     *            The <code>Writer</code> to write the results to; assumed to be non-null.
+     * @param str
+     *            The source <code>String</code> to unescape; assumed to be non-null.
+     * @throws IOException
+     *             when <code>Writer</code> passed throws the exception from calls to the {@link Writer#write(int)}
+     *             methods.
+     *
+     * @see #escape(String)
+     * @see Writer
+     */
+    public void unescape(Writer writer, String str) throws IOException {
+        int firstAmp = str.indexOf('&');
+        if (firstAmp < 0) {
+            writer.write(str);
+            return;
+        } else {
+            doUnescape(writer, str, firstAmp);
+        }
+    }
+
+    /**
+     * Underlying unescape method that allows the optimisation of not starting from the 0 index again.
+     *
+     * @param writer
+     *            The <code>Writer</code> to write the results to; assumed to be non-null.
+     * @param str
+     *            The source <code>String</code> to unescape; assumed to be non-null.
+     * @param firstAmp
+     *            The <code>int</code> index of the first ampersand in the source String.
+     * @throws IOException
+     *             when <code>Writer</code> passed throws the exception from calls to the {@link Writer#write(int)}
+     *             methods.
+     */
+    private void doUnescape(Writer writer, String str, int firstAmp) throws IOException {
+        writer.write(str, 0, firstAmp);
+        int len = str.length();
+        for (int i = firstAmp; i < len; i++) {
+            char c = str.charAt(i);
+            if (c == '&') {
+                int nextIdx = i + 1;
+                int semiColonIdx = str.indexOf(';', nextIdx);
+                if (semiColonIdx == -1) {
+                    writer.write(c);
+                    continue;
+                }
+                int amphersandIdx = str.indexOf('&', i + 1);
+                if (amphersandIdx != -1 && amphersandIdx < semiColonIdx) {
+                    // Then the text looks like &...&...;
+                    writer.write(c);
+                    continue;
+                }
+                String entityContent = str.substring(nextIdx, semiColonIdx);
+                int entityValue = -1;
+                int entityContentLen = entityContent.length();
+                if (entityContentLen > 0) {
+                    if (entityContent.charAt(0) == '#') { // escaped value content is an integer (decimal or
+                        // hexidecimal)
+                        if (entityContentLen > 1) {
+                            char isHexChar = entityContent.charAt(1);
+                            try {
+                                switch (isHexChar) {
+                                    case 'X' :
+                                    case 'x' : {
+                                        entityValue = Integer.parseInt(entityContent.substring(2), 16);
+                                        break;
+                                    }
+                                    default : {
+                                        entityValue = Integer.parseInt(entityContent.substring(1), 10);
+                                    }
+                                }
+                                if (entityValue > 0xFFFF) {
+                                    entityValue = -1;
+                                }
+                            } catch (NumberFormatException e) {
+                                entityValue = -1;
+                            }
+                        }
+                    } else { // escaped value content is an entity name
+                        entityValue = this.entityValue(entityContent);
+                    }
+                }
+
+                if (entityValue == -1) {
+                    writer.write('&');
+                    writer.write(entityContent);
+                    writer.write(';');
+                } else {
+                    writer.write(entityValue);
+                }
+                i = semiColonIdx; // move index up to the semi-colon
+            } else {
+                writer.write(c);
+            }
+        }
+    }
+
+}

Added: velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/thirdparty/commons/lang/StringEscapeUtils.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/thirdparty/commons/lang/StringEscapeUtils.java?rev=1040976&view=auto
==============================================================================
--- velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/thirdparty/commons/lang/StringEscapeUtils.java (added)
+++ velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/thirdparty/commons/lang/StringEscapeUtils.java Wed Dec  1 12:15:39 2010
@@ -0,0 +1,364 @@
+/*
+ * 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.
+ */
+package org.apache.velocity.thirdparty.commons.lang;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+
+/**
+ * Copied and stripped from Apache Commons Lang 2.4.
+ *
+ * <p>Escapes and unescapes <code>String</code>s for
+ * Java, Java Script, HTML, XML, and SQL.</p>
+ *
+ * @author Apache Jakarta Turbine
+ * @author Purple Technology
+ * @author <a href="mailto:alex@purpletech.com">Alexander Day Chaffee</a>
+ * @author Antony Riley
+ * @author Helge Tesgaard
+ * @author <a href="sean@boohai.com">Sean Brown</a>
+ * @author <a href="mailto:ggregory@seagullsw.com">Gary Gregory</a>
+ * @author Phil Steitz
+ * @author Pete Gieser
+ * @since 2.0
+ * @version $Id: StringEscapeUtils.java 612880 2008-01-17 17:34:43Z ggregory $
+ */
+public class StringEscapeUtils {
+
+    // HTML and XML
+    //--------------------------------------------------------------------------
+    /**
+     * <p>Escapes the characters in a <code>String</code> using HTML entities.</p>
+     *
+     * <p>
+     * For example:
+     * </p>
+     * <p><code>"bread" & "butter"</code></p>
+     * becomes:
+     * <p>
+     * <code>&amp;quot;bread&amp;quot; &amp;amp; &amp;quot;butter&amp;quot;</code>.
+     * </p>
+     *
+     * <p>Supports all known HTML 4.0 entities, including funky accents.
+     * Note that the commonly used apostrophe escape character (&amp;apos;)
+     * is not a legal entity and so is not supported). </p>
+     *
+     * @param str  the <code>String</code> to escape, may be null
+     * @return a new escaped <code>String</code>, <code>null</code> if null string input
+     *
+     * @see #unescapeHtml(String)
+     * @see <a href="http://hotwired.lycos.com/webmonkey/reference/special_characters/">ISO Entities</a>
+     * @see <a href="http://www.w3.org/TR/REC-html32#latin1">HTML 3.2 Character Entities for ISO Latin-1</a>
+     * @see <a href="http://www.w3.org/TR/REC-html40/sgml/entities.html">HTML 4.0 Character entity references</a>
+     * @see <a href="http://www.w3.org/TR/html401/charset.html#h-5.3">HTML 4.01 Character References</a>
+     * @see <a href="http://www.w3.org/TR/html401/charset.html#code-position">HTML 4.01 Code positions</a>
+     */
+    public static String escapeHtml(String str) {
+        if (str == null) {
+            return null;
+        }
+        try {
+            StringWriter writer = new StringWriter ((int)(str.length() * 1.5));
+            escapeHtml(writer, str);
+            return writer.toString();
+        } catch (IOException e) {
+            //assert false;
+            //should be impossible
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * <p>Escapes the characters in a <code>String</code> using HTML entities and writes
+     * them to a <code>Writer</code>.</p>
+     *
+     * <p>
+     * For example:
+     * </p>
+     * <code>"bread" & "butter"</code>
+     * <p>becomes:</p>
+     * <code>&amp;quot;bread&amp;quot; &amp;amp; &amp;quot;butter&amp;quot;</code>.
+     *
+     * <p>Supports all known HTML 4.0 entities, including funky accents.
+     * Note that the commonly used apostrophe escape character (&amp;apos;)
+     * is not a legal entity and so is not supported). </p>
+     *
+     * @param writer  the writer receiving the escaped string, not null
+     * @param string  the <code>String</code> to escape, may be null
+     * @throws IllegalArgumentException if the writer is null
+     * @throws IOException when <code>Writer</code> passed throws the exception from
+     *                                       calls to the {@link Writer#write(int)} methods.
+     *
+     * @see #escapeHtml(String)
+     * @see #unescapeHtml(String)
+     * @see <a href="http://hotwired.lycos.com/webmonkey/reference/special_characters/">ISO Entities</a>
+     * @see <a href="http://www.w3.org/TR/REC-html32#latin1">HTML 3.2 Character Entities for ISO Latin-1</a>
+     * @see <a href="http://www.w3.org/TR/REC-html40/sgml/entities.html">HTML 4.0 Character entity references</a>
+     * @see <a href="http://www.w3.org/TR/html401/charset.html#h-5.3">HTML 4.01 Character References</a>
+     * @see <a href="http://www.w3.org/TR/html401/charset.html#code-position">HTML 4.01 Code positions</a>
+     */
+    public static void escapeHtml(Writer writer, String string) throws IOException {
+        if (writer == null ) {
+            throw new IllegalArgumentException ("The Writer must not be null.");
+        }
+        if (string == null) {
+            return;
+        }
+        Entities.HTML40.escape(writer, string);
+    }
+
+    /**
+     * <p>Escapes the characters in a <code>String</code> using JavaScript String rules.</p>
+     * <p>Escapes any values it finds into their JavaScript String form.
+     * Deals correctly with quotes and control-chars (tab, backslash, cr, ff, etc.) </p>
+     *
+     * <p>So a tab becomes the characters <code>'\\'</code> and
+     * <code>'t'</code>.</p>
+     *
+     * <p>The only difference between Java strings and JavaScript strings
+     * is that in JavaScript, a single quote must be escaped.</p>
+     *
+     * <p>Example:
+     * <pre>
+     * input string: He didn't say, "Stop!"
+     * output string: He didn\'t say, \"Stop!\"
+     * </pre>
+     * </p>
+     *
+     * @param str  String to escape values in, may be null
+     * @return String with escaped values, <code>null</code> if null string input
+     */
+    public static String escapeJavaScript(String str) {
+        return escapeJavaStyleString(str, true);
+    }
+
+    /**
+     * <p>Escapes the characters in a <code>String</code> using JavaScript String rules
+     * to a <code>Writer</code>.</p>
+     *
+     * <p>A <code>null</code> string input has no effect.</p>
+     *
+     * @see #escapeJavaScript(java.lang.String)
+     * @param out  Writer to write escaped string into
+     * @param str  String to escape values in, may be null
+     * @throws IllegalArgumentException if the Writer is <code>null</code>
+     * @throws IOException if error occurs on underlying Writer
+     **/
+    public static void escapeJavaScript(Writer out, String str) throws IOException {
+        escapeJavaStyleString(out, str, true);
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Escapes the characters in a <code>String</code> to be suitable to pass to
+     * an SQL query.</p>
+     *
+     * <p>For example,
+     * <pre>statement.executeQuery("SELECT * FROM MOVIES WHERE TITLE='" +
+     *   StringEscapeUtils.escapeSql("McHale's Navy") +
+     *   "'");</pre>
+     * </p>
+     *
+     * <p>At present, this method only turns single-quotes into doubled single-quotes
+     * (<code>"McHale's Navy"</code> => <code>"McHale''s Navy"</code>). It does not
+     * handle the cases of percent (%) or underscore (_) for use in LIKE clauses.</p>
+     *
+     * see http://www.jguru.com/faq/view.jsp?EID=8881
+     * @param str  the string to escape, may be null
+     * @return a new String, escaped for SQL, <code>null</code> if null string input
+     */
+    public static String escapeSql(String str) {
+        if (str == null) {
+            return null;
+        }
+        return StringUtils.replace(str, "'", "''");
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Escapes the characters in a <code>String</code> using XML entities.</p>
+     *
+     * <p>For example: <tt>"bread" & "butter"</tt> =>
+     * <tt>&amp;quot;bread&amp;quot; &amp;amp; &amp;quot;butter&amp;quot;</tt>.
+     * </p>
+     *
+     * <p>Supports only the five basic XML entities (gt, lt, quot, amp, apos).
+     * Does not support DTDs or external entities.</p>
+     *
+     * <p>Note that unicode characters greater than 0x7f are currently escaped to
+     *    their numerical \\u equivalent. This may change in future releases. </p>
+     *
+     * @param writer  the writer receiving the unescaped string, not null
+     * @param str  the <code>String</code> to escape, may be null
+     * @throws IllegalArgumentException if the writer is null
+     * @throws IOException if there is a problem writing
+     * @see #unescapeXml(java.lang.String)
+     */
+    public static void escapeXml(Writer writer, String str) throws IOException {
+        if (writer == null ) {
+            throw new IllegalArgumentException ("The Writer must not be null.");
+        }
+        if (str == null) {
+            return;
+        }
+        Entities.XML.escape(writer, str);
+    }
+
+    /**
+     * <p>Escapes the characters in a <code>String</code> using XML entities.</p>
+     *
+     * <p>For example: <tt>"bread" & "butter"</tt> =>
+     * <tt>&amp;quot;bread&amp;quot; &amp;amp; &amp;quot;butter&amp;quot;</tt>.
+     * </p>
+     *
+     * <p>Supports only the five basic XML entities (gt, lt, quot, amp, apos).
+     * Does not support DTDs or external entities.</p>
+     *
+     * <p>Note that unicode characters greater than 0x7f are currently escaped to
+     *    their numerical \\u equivalent. This may change in future releases. </p>
+     *
+     * @param str  the <code>String</code> to escape, may be null
+     * @return a new escaped <code>String</code>, <code>null</code> if null string input
+     * @see #unescapeXml(java.lang.String)
+     */
+    public static String escapeXml(String str) {
+        if (str == null) {
+            return null;
+        }
+        return Entities.XML.escape(str);
+    }
+
+    /**
+     * <p>Worker method for the {@link #escapeJavaScript(String)} method.</p>
+     *
+     * @param str String to escape values in, may be null
+     * @param escapeSingleQuotes escapes single quotes if <code>true</code>
+     * @return the escaped string
+     */
+    private static String escapeJavaStyleString(String str, boolean escapeSingleQuotes) {
+        if (str == null) {
+            return null;
+        }
+        try {
+            StringWriter writer = new StringWriter(str.length() * 2);
+            escapeJavaStyleString(writer, str, escapeSingleQuotes);
+            return writer.toString();
+        } catch (IOException ioe) {
+            // this should never ever happen while writing to a StringWriter
+            ioe.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * <p>Worker method for the {@link #escapeJavaScript(String)} method.</p>
+     *
+     * @param out write to receieve the escaped string
+     * @param str String to escape values in, may be null
+     * @param escapeSingleQuote escapes single quotes if <code>true</code>
+     * @throws IOException if an IOException occurs
+     */
+    private static void escapeJavaStyleString(Writer out, String str, boolean escapeSingleQuote) throws IOException {
+        if (out == null) {
+            throw new IllegalArgumentException("The Writer must not be null");
+        }
+        if (str == null) {
+            return;
+        }
+        int sz;
+        sz = str.length();
+        for (int i = 0; i < sz; i++) {
+            char ch = str.charAt(i);
+
+            // handle unicode
+            if (ch > 0xfff) {
+                out.write("\\u" + hex(ch));
+            } else if (ch > 0xff) {
+                out.write("\\u0" + hex(ch));
+            } else if (ch > 0x7f) {
+                out.write("\\u00" + hex(ch));
+            } else if (ch < 32) {
+                switch (ch) {
+                    case '\b':
+                        out.write('\\');
+                        out.write('b');
+                        break;
+                    case '\n':
+                        out.write('\\');
+                        out.write('n');
+                        break;
+                    case '\t':
+                        out.write('\\');
+                        out.write('t');
+                        break;
+                    case '\f':
+                        out.write('\\');
+                        out.write('f');
+                        break;
+                    case '\r':
+                        out.write('\\');
+                        out.write('r');
+                        break;
+                    default :
+                        if (ch > 0xf) {
+                            out.write("\\u00" + hex(ch));
+                        } else {
+                            out.write("\\u000" + hex(ch));
+                        }
+                        break;
+                }
+            } else {
+                switch (ch) {
+                    case '\'':
+                        if (escapeSingleQuote) {
+                          out.write('\\');
+                        }
+                        out.write('\'');
+                        break;
+                    case '"':
+                        out.write('\\');
+                        out.write('"');
+                        break;
+                    case '\\':
+                        out.write('\\');
+                        out.write('\\');
+                        break;
+                    case '/':
+                        out.write('\\');
+                        out.write('/');
+                        break;
+                    default :
+                        out.write(ch);
+                        break;
+                }
+            }
+        }
+    }
+
+    /**
+     * <p>Returns an upper case hexadecimal <code>String</code> for the given
+     * character.</p>
+     *
+     * @param ch The character to convert.
+     * @return An upper case hexadecimal <code>String</code>
+     */
+    private static String hex(char ch) {
+        return Integer.toHexString(ch).toUpperCase();
+    }
+}

Added: velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/thirdparty/commons/lang/StringUtils.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/thirdparty/commons/lang/StringUtils.java?rev=1040976&view=auto
==============================================================================
--- velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/thirdparty/commons/lang/StringUtils.java (added)
+++ velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/thirdparty/commons/lang/StringUtils.java Wed Dec  1 12:15:39 2010
@@ -0,0 +1,190 @@
+/*
+ * 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.
+ */
+package org.apache.velocity.thirdparty.commons.lang;
+
+/**
+ * Copied and stripped from Apache Commons Lang 2.4.
+ *
+ * @version $Id: StringUtils.java 635447 2008-03-10 06:27:09Z bayard $
+ */
+public class StringUtils {
+
+    /**
+     * <p><code>StringUtils</code> instances should NOT be constructed in
+     * standard programming. Instead, the class should be used as
+     * <code>StringUtils.trim(" foo ");</code>.</p>
+     *
+     * <p>This constructor is private to avoid instantiation.</p>
+     */
+    private StringUtils() {
+    }
+
+    /**
+     * The empty String <code>""</code>.
+     * @since 2.0
+     */
+    public static final String EMPTY = "";
+
+    // Empty checks
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Checks if a String is empty ("") or null.</p>
+     *
+     * <pre>
+     * StringUtils.isEmpty(null)      = true
+     * StringUtils.isEmpty("")        = true
+     * StringUtils.isEmpty(" ")       = false
+     * StringUtils.isEmpty("bob")     = false
+     * StringUtils.isEmpty("  bob  ") = false
+     * </pre>
+     *
+     * <p>NOTE: This method changed in Lang version 2.0.
+     * It no longer trims the String.
+     * That functionality is available in isBlank().</p>
+     *
+     * @param str  the String to check, may be null
+     * @return <code>true</code> if the String is empty or null
+     */
+    public static boolean isEmpty(String str) {
+        return str == null || str.length() == 0;
+    }
+
+    /**
+     * <p>Checks if a String is not empty ("") and not null.</p>
+     *
+     * <pre>
+     * StringUtils.isNotEmpty(null)      = false
+     * StringUtils.isNotEmpty("")        = false
+     * StringUtils.isNotEmpty(" ")       = true
+     * StringUtils.isNotEmpty("bob")     = true
+     * StringUtils.isNotEmpty("  bob  ") = true
+     * </pre>
+     *
+     * @param str  the String to check, may be null
+     * @return <code>true</code> if the String is not empty and not null
+     */
+    public static boolean isNotEmpty(String str) {
+        return !StringUtils.isEmpty(str);
+    }
+
+    // Equals
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Compares two Strings, returning <code>true</code> if they are equal.</p>
+     *
+     * <p><code>null</code>s are handled without exceptions. Two <code>null</code>
+     * references are considered to be equal. The comparison is case sensitive.</p>
+     *
+     * <pre>
+     * StringUtils.equals(null, null)   = true
+     * StringUtils.equals(null, "abc")  = false
+     * StringUtils.equals("abc", null)  = false
+     * StringUtils.equals("abc", "abc") = true
+     * StringUtils.equals("abc", "ABC") = false
+     * </pre>
+     *
+     * @see java.lang.String#equals(Object)
+     * @param str1  the first String, may be null
+     * @param str2  the second String, may be null
+     * @return <code>true</code> if the Strings are equal, case sensitive, or
+     *  both <code>null</code>
+     */
+    public static boolean equals(String str1, String str2) {
+        return str1 == null ? str2 == null : str1.equals(str2);
+    }
+
+    /**
+     * <p>Replaces all occurrences of a String within another String.</p>
+     *
+     * <p>A <code>null</code> reference passed to this method is a no-op.</p>
+     *
+     * <pre>
+     * StringUtils.replace(null, *, *)        = null
+     * StringUtils.replace("", *, *)          = ""
+     * StringUtils.replace("any", null, *)    = "any"
+     * StringUtils.replace("any", *, null)    = "any"
+     * StringUtils.replace("any", "", *)      = "any"
+     * StringUtils.replace("aba", "a", null)  = "aba"
+     * StringUtils.replace("aba", "a", "")    = "b"
+     * StringUtils.replace("aba", "a", "z")   = "zbz"
+     * </pre>
+     *
+     * @see #replace(String text, String searchString, String replacement, int max)
+     * @param text  text to search and replace in, may be null
+     * @param searchString  the String to search for, may be null
+     * @param replacement  the String to replace it with, may be null
+     * @return the text with any replacements processed,
+     *  <code>null</code> if null String input
+     */
+    public static String replace(String text, String searchString, String replacement) {
+        return replace(text, searchString, replacement, -1);
+    }
+
+    /**
+     * <p>Replaces a String with another String inside a larger String,
+     * for the first <code>max</code> values of the search String.</p>
+     *
+     * <p>A <code>null</code> reference passed to this method is a no-op.</p>
+     *
+     * <pre>
+     * StringUtils.replace(null, *, *, *)         = null
+     * StringUtils.replace("", *, *, *)           = ""
+     * StringUtils.replace("any", null, *, *)     = "any"
+     * StringUtils.replace("any", *, null, *)     = "any"
+     * StringUtils.replace("any", "", *, *)       = "any"
+     * StringUtils.replace("any", *, *, 0)        = "any"
+     * StringUtils.replace("abaa", "a", null, -1) = "abaa"
+     * StringUtils.replace("abaa", "a", "", -1)   = "b"
+     * StringUtils.replace("abaa", "a", "z", 0)   = "abaa"
+     * StringUtils.replace("abaa", "a", "z", 1)   = "zbaa"
+     * StringUtils.replace("abaa", "a", "z", 2)   = "zbza"
+     * StringUtils.replace("abaa", "a", "z", -1)  = "zbzz"
+     * </pre>
+     *
+     * @param text  text to search and replace in, may be null
+     * @param searchString  the String to search for, may be null
+     * @param replacement  the String to replace it with, may be null
+     * @param max  maximum number of values to replace, or <code>-1</code> if no maximum
+     * @return the text with any replacements processed,
+     *  <code>null</code> if null String input
+     */
+    public static String replace(String text, String searchString, String replacement, int max) {
+        if (isEmpty(text) || isEmpty(searchString) || replacement == null || max == 0) {
+            return text;
+        }
+        int start = 0;
+        int end = text.indexOf(searchString, start);
+        if (end == -1) {
+            return text;
+        }
+        int replLength = searchString.length();
+        int increase = replacement.length() - replLength;
+        increase = (increase < 0 ? 0 : increase);
+        increase *= (max < 0 ? 16 : (max > 64 ? 64 : max));
+        StringBuffer buf = new StringBuffer(text.length() + increase);
+        while (end != -1) {
+            buf.append(text.substring(start, end)).append(replacement);
+            start = end + replLength;
+            if (--max == 0) {
+                break;
+            }
+            end = text.indexOf(searchString, start);
+        }
+        buf.append(text.substring(start));
+        return buf.toString();
+    }
+}

Added: velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/thirdparty/commons/lang/UnhandledException.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/thirdparty/commons/lang/UnhandledException.java?rev=1040976&view=auto
==============================================================================
--- velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/thirdparty/commons/lang/UnhandledException.java (added)
+++ velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/thirdparty/commons/lang/UnhandledException.java Wed Dec  1 12:15:39 2010
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+package org.apache.velocity.thirdparty.commons.lang;
+
+/**
+ * Copied and edited from Apache Commons Lang 2.4.
+ *
+ * <p>Thrown when it is impossible or undesirable to consume or throw a checked exception.</p>
+ * This exception supplements the standard exception classes by providing a more
+ * semantically rich description of the problem.</p>
+ *
+ * <p><code>UnhandledException</code> represents the case where a method has to deal
+ * with a checked exception but does not wish to.
+ * Instead, the checked exception is rethrown in this unchecked wrapper.</p>
+ *
+ * <pre>
+ * public void foo() {
+ *   try {
+ *     // do something that throws IOException
+ *   } catch (IOException ex) {
+ *     // don't want to or can't throw IOException from foo()
+ *     throw new UnhandledException(ex);
+ *   }
+ * }
+ * </pre>
+ *
+ * @author Matthew Hawthorne
+ * @since 2.0
+ * @version $Id: UnhandledException.java 437554 2006-08-28 06:21:41Z bayard $
+ */
+public class UnhandledException extends RuntimeException {
+
+    /**
+     * Required for serialization support.
+     *
+     * @see java.io.Serializable
+     */
+    private static final long serialVersionUID = 1393325091074936794L;
+
+	/**
+     * Constructs the exception using a cause.
+     *
+     * @param cause  the underlying cause
+     */
+    public UnhandledException(Throwable cause) {
+        super(cause);
+    }
+
+    /**
+     * Constructs the exception using a message and cause.
+     *
+     * @param message  the message to use
+     * @param cause  the underlying cause
+     */
+    public UnhandledException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}

Modified: velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/util/introspection/ClassMap.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/util/introspection/ClassMap.java?rev=1040976&r1=1040975&r2=1040976&view=diff
==============================================================================
--- velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/util/introspection/ClassMap.java (original)
+++ velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/util/introspection/ClassMap.java Wed Dec  1 12:15:39 2010
@@ -16,7 +16,7 @@ package org.apache.velocity.util.introsp
  * "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.    
+ * under the License.
  */
 
 import java.lang.reflect.Method;
@@ -24,7 +24,6 @@ import java.lang.reflect.Modifier;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
-import org.apache.commons.lang.text.StrBuilder;
 import org.apache.velocity.runtime.log.Log;
 
 /**
@@ -47,7 +46,7 @@ public class ClassMap
 
     /** Class logger */
     private final Log log;
-    
+
     /**
      * Class passed into the constructor used to as
      * the basis for the Method map.
@@ -64,13 +63,13 @@ public class ClassMap
     {
         this.clazz = clazz;
         this.log = log;
-        
+
         if (debugReflection && log.isDebugEnabled())
         {
             log.debug("=================================================================");
             log.debug("== Class: " + clazz);
         }
-        
+
         methodCache = createMethodCache();
 
         if (debugReflection && log.isDebugEnabled())
@@ -117,14 +116,14 @@ public class ClassMap
 	// hit java.lang.Object. That is important because it will give us the methods of the declaring class
 	// which might in turn be abstract further up the tree.
 	//
-	// We also ignore all SecurityExceptions that might happen due to SecurityManager restrictions (prominently 
+	// We also ignore all SecurityExceptions that might happen due to SecurityManager restrictions (prominently
 	// hit with Tomcat 5.5).
 	//
 	// We can also omit all that complicated getPublic, getAccessible and upcast logic that the class map had up
 	// until Velocity 1.4. As we always reflect all elements of the tree (that's what we have a cache for), we will
 	// hit the public elements sooner or later because we reflect all the public elements anyway.
 	//
-        // Ah, the miracles of Java for(;;) ... 
+        // Ah, the miracles of Java for(;;) ...
         for (Class classToReflect = getCachedClass(); classToReflect != null ; classToReflect = classToReflect.getSuperclass())
         {
             if (Modifier.isPublic(classToReflect.getModifiers()))
@@ -184,8 +183,8 @@ public class ClassMap
     }
 
     /**
-     * This is the cache to store and look up the method information. 
-     * 
+     * This is the cache to store and look up the method information.
+     *
      * @author <a href="mailto:henning@apache.org">Henning P. Schmiedehausen</a>
      * @version $Id$
      */
@@ -250,7 +249,7 @@ public class ClassMap
             Object cacheEntry = cache.get(methodKey);
             if (cacheEntry == CACHE_MISS)
             {
-                // We looked this up before and failed. 
+                // We looked this up before and failed.
                 return null;
             }
 
@@ -270,7 +269,7 @@ public class ClassMap
                     throw ae;
                 }
 
-                cache.put(methodKey, 
+                cache.put(methodKey,
                         (cacheEntry != null) ? cacheEntry : CACHE_MISS);
             }
 
@@ -301,7 +300,7 @@ public class ClassMap
          * Make a methodKey for the given method using
          * the concatenation of the name and the
          * types of the method parameters.
-         * 
+         *
          * @param method to be stored as key
          * @return key for ClassMap
          */
@@ -314,7 +313,7 @@ public class ClassMap
                 return method.getName();
             }
 
-            StrBuilder methodKey = new StrBuilder((args+1)*16).append(method.getName());
+            StringBuilder methodKey = new StringBuilder((args+1)*16).append(method.getName());
 
             for (int j = 0; j < args; j++)
             {
@@ -349,7 +348,7 @@ public class ClassMap
                 return method;
             }
 
-            StrBuilder methodKey = new StrBuilder((args+1)*16).append(method);
+            StringBuilder methodKey = new StringBuilder((args+1)*16).append(method);
 
             for (int j = 0; j < args; j++)
             {

Modified: velocity/engine/trunk/velocity-engine-core/src/main/parser/Parser.jjt
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/parser/Parser.jjt?rev=1040976&r1=1040975&r2=1040976&view=diff
==============================================================================
--- velocity/engine/trunk/velocity-engine-core/src/main/parser/Parser.jjt (original)
+++ velocity/engine/trunk/velocity-engine-core/src/main/parser/Parser.jjt Wed Dec  1 12:15:39 2010
@@ -14,7 +14,7 @@
  * "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.    
+ * under the License.
  */
 
 /*
@@ -83,10 +83,7 @@ import org.apache.velocity.exception.Vel
 import org.apache.velocity.runtime.RuntimeServices;
 import org.apache.velocity.runtime.parser.node.*;
 import org.apache.velocity.runtime.directive.Directive;
-import org.apache.velocity.runtime.directive.Macro;
 import org.apache.velocity.runtime.directive.MacroParseException;
-import org.apache.velocity.util.StringUtils;
-import org.apache.commons.lang.text.StrBuilder;
 import org.apache.velocity.runtime.RuntimeConstants;
 
 /**
@@ -114,13 +111,13 @@ public class Parser
      * Name of current template we are parsing.  Passed to us in parse()
      */
     public String currentTemplateName = "";
-    
+
     /**
-     * Set to true if the property 
+     * Set to true if the property
      * RuntimeConstants.RUNTIME_REFERENCES_STRICT_ESCAPE is set to true
      */
-    public boolean strictEscape = false; 
-     
+    public boolean strictEscape = false;
+
     VelocityCharStream velcharstream = null;
 
     private RuntimeServices rsvc = null;
@@ -146,10 +143,10 @@ public class Parser
          */
         velcharstream = new VelocityCharStream(
                 new ByteArrayInputStream("\n".getBytes()), 1, 1 );
-                
-                
-        strictEscape = 
-            rs.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT_ESCAPE, false);                
+
+
+        strictEscape =
+            rs.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT_ESCAPE, false);
 
         /*
          *  and save the RuntimeServices
@@ -252,7 +249,7 @@ public class Parser
         String strDirective = strImage.substring(iLast + 1);
 
         boolean bRecognizedDirective = false;
-        
+
         // we don't have to call substring method all the time in this method
         String dirTag = strDirective.substring(1);
         if (dirTag.charAt(0) == '{')
@@ -268,9 +265,9 @@ public class Parser
          *  if the derective is defined or not.
          */
 
-        if (strictEscape 
-             || isDirective(dirTag) 
-             || macroNames.containsKey(dirTag) 
+        if (strictEscape
+             || isDirective(dirTag)
+             || macroNames.containsKey(dirTag)
              || rsvc.isVelocimacro(dirTag, currentTemplateName))
         {
             bRecognizedDirective = true;
@@ -344,7 +341,7 @@ public class Parser
         }
         return false;
     }
-    
+
     /**
      * We use this method in a lookahead to determine if we are in a macro
      * default value assignment.  The standard lookahead is not smart enough.
@@ -354,7 +351,7 @@ public class Parser
     {
        // Basically if the last character read was not '$' then false
        if (token_source.curLexState != REFERENCE) return false;
-       
+
        char c = ' ';
        int backup = 0;
        try
@@ -365,7 +362,7 @@ public class Parser
                 c = velcharstream.readChar();
                 backup++;
            }
-           
+
            // This is what we are ultimately looking for
            if (c != '=') return false;
        }
@@ -376,9 +373,9 @@ public class Parser
        {
            velcharstream.backup(backup);
        }
-              
+
        return true;
-    }    
+    }
 }
 
 PARSER_END(Parser)
@@ -391,7 +388,7 @@ TOKEN_MGR_DECLS:
     private int rparen = 0;
 
     List stateStack = new ArrayList(50);
-    
+
     public boolean debugPrint = false;
 
     private boolean inReference;
@@ -446,7 +443,7 @@ TOKEN_MGR_DECLS:
         if( debugPrint )
             System.out.println(" (" + stateStack.size() + ") pushing cur state : " +
                 curLexState );
-        
+
         ParserState s = new ParserState();
         s.lparen = lparen;
         s.rparen = rparen;
@@ -486,7 +483,7 @@ TOKEN_MGR_DECLS:
         int rparen;
         int lexstate;
     }
-    
+
     /**
      *  handles the dropdown logic when encountering a RPAREN
      */
@@ -560,7 +557,7 @@ TOKEN:
      stateStackPush();
      SwitchTo(REFINDEX);
    }
-  
+
 }
 
 <REFINDEX>
@@ -569,7 +566,7 @@ TOKEN:
    <INDEX_RBRACKET: "]">
    {
      stateStackPop();
-   }  
+   }
 }
 
 
@@ -796,7 +793,7 @@ MORE :
            SwitchTo( IN_TEXTBLOCK );
        }
     }
-    
+
 |   <"#**" ~["#"]>
     {
     	if (!inComment)
@@ -817,7 +814,7 @@ MORE :
 	        SwitchTo( IN_MULTI_LINE_COMMENT );
     	}
     }
-    
+
 |   <HASH : "#" >
     {
         if (! inComment)
@@ -1125,7 +1122,7 @@ TOKEN:
  *  TODO, the "@" symbol for block macros to be correct really should prefix WORD
  *  and BRACKETED_WORD, e.g., <WORD ["@"] ( <LETTER... etc...
  *  However, having the conditional character at the beginning screws up
- *  Macro parse.  As it is now you can have #@1234 defined as a macro 
+ *  Macro parse.  As it is now you can have #@1234 defined as a macro
  *  Which is not correct.
  */
 
@@ -1156,7 +1153,7 @@ TOKEN:
  *          |       re stateStack.
  *          |-- >  REFMOD2 : state switch to when the LPAREN is encountered.
  *                  again, this is a switch, not a push.
- * 
+ *
  *  During the REFERENCE or REFMODIFIER lex states we will switch to
  *  REFINDEX if a bracket is encountered '['.  for example:  $foo[1]
  *  or $foo.bar[1], $foo.bar( "arg" )[1]
@@ -1501,7 +1498,7 @@ SimpleNode Directive() :
          */
 
         jjtThis.setDirectiveName(directiveName);
-        
+
         if ( d == null)
         {
             if( directiveName.startsWith("@") )
@@ -1542,14 +1539,14 @@ SimpleNode Directive() :
      *  if this is indeed a token, match the #foo ( arg ) pattern
      */
     ([<WHITESPACE>] <LPAREN> ( LOOKAHEAD(2) [<WHITESPACE>] [<COMMA> [<WHITESPACE>]]
-       (              
-           [LOOKAHEAD( { isMacro && isAssignment() }) 
+       (
+           [LOOKAHEAD( { isMacro && isAssignment() })
               DirectiveAssign() [<WHITESPACE>] <EQUALS> [<WHITESPACE>]
            {
                argtypes.add(ParserTreeConstants.JJTDIRECTIVEASSIGN);
            }
            ]
-            argType = DirectiveArg() 
+            argType = DirectiveArg()
             {
                 argtypes.add(argType);
                 if (d == null && argType == ParserTreeConstants.JJTWORD)
@@ -1572,8 +1569,8 @@ SimpleNode Directive() :
               + " arguments", currentTemplateName, t);
           }
         }
-        
-         <SINGLE_LINE_COMMENT_START> [<SINGLE_LINE_COMMENT>] 
+
+         <SINGLE_LINE_COMMENT_START> [<SINGLE_LINE_COMMENT>]
       )
     )* [<WHITESPACE>] <RPAREN>)
     |
@@ -1587,7 +1584,7 @@ SimpleNode Directive() :
         {
             d.checkArgs(argtypes, t, currentTemplateName);
         }
-        
+
         if (directiveType  == Directive.LINE)
         {
             return jjtThis;
@@ -1642,7 +1639,7 @@ void Map() : {}
       |
       [ <WHITESPACE> ]
      )
-     
+
      /** note: need both tokens as they are generated in different states **/
      ( <RIGHT_CURLEY> | <RCURLY> )
 }
@@ -1784,7 +1781,7 @@ void Text() : {}
 |   <ESCAPE>
 |   <LCURLY>
 |   <RCURLY>
-|   <EMPTY_INDEX>    
+|   <EMPTY_INDEX>
 }
 
 /* -----------------------------------------------------------------------

Modified: velocity/engine/trunk/velocity-engine-core/src/main/resources/org/apache/velocity/runtime/defaults/velocity.properties
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/resources/org/apache/velocity/runtime/defaults/velocity.properties?rev=1040976&r1=1040975&r2=1040976&view=diff
==============================================================================
--- velocity/engine/trunk/velocity-engine-core/src/main/resources/org/apache/velocity/runtime/defaults/velocity.properties (original)
+++ velocity/engine/trunk/velocity-engine-core/src/main/resources/org/apache/velocity/runtime/defaults/velocity.properties Wed Dec  1 12:15:39 2010
@@ -13,17 +13,17 @@
 # "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.    
+# under the License.
 
 # ----------------------------------------------------------------------------
 # R U N T I M E  L O G
 # ----------------------------------------------------------------------------
 
 # ----------------------------------------------------------------------------
-#  default LogChute to use: default: AvalonLogChute, Log4JLogChute, CommonsLogLogChute, ServletLogChute, JdkLogChute
+#  default LogChute to use: default: Log4JLogChute, CommonsLogLogChute, ServletLogChute, JdkLogChute
 # ----------------------------------------------------------------------------
 
-runtime.log.logsystem.class = org.apache.velocity.runtime.log.AvalonLogChute,org.apache.velocity.runtime.log.Log4JLogChute,org.apache.velocity.runtime.log.CommonsLogLogChute,org.apache.velocity.runtime.log.ServletLogChute,org.apache.velocity.runtime.log.JdkLogChute
+runtime.log.logsystem.class = org.apache.velocity.runtime.log.Log4JLogChute,org.apache.velocity.runtime.log.CommonsLogLogChute,org.apache.velocity.runtime.log.ServletLogChute,org.apache.velocity.runtime.log.JdkLogChute
 
 # ---------------------------------------------------------------------------
 # This is the location of the Velocity Runtime log.
@@ -117,7 +117,7 @@ velocimacro.max.depth = 20
 # ----------------------------------------------------------------------------
 # VELOCIMACRO STRICT MODE
 # ----------------------------------------------------------------------------
-# if true, will throw an exception for incorrect number 
+# if true, will throw an exception for incorrect number
 # of arguments.  false by default (for backwards compatibility)
 # but this option will eventually be removed and will always
 # act as if true
@@ -125,7 +125,7 @@ velocimacro.max.depth = 20
 velocimacro.arguments.strict = false
 
 # ----------------------------------------------------------------------------
-# VELOCIMACRO BODY REFERENCE 
+# VELOCIMACRO BODY REFERENCE
 # ----------------------------------------------------------------------------
 # Defines name of the reference that can be used to render the AST block passed to
 # block macro call as an argument inside a macro.
@@ -199,7 +199,7 @@ runtime.introspector.uberspect = org.apa
 # ----------------------------------------------------------------------------
 # SECURE INTROSPECTOR
 # ----------------------------------------------------------------------------
-# If selected, prohibits methods in certain classes and packages from being 
+# If selected, prohibits methods in certain classes and packages from being
 # accessed.
 # ----------------------------------------------------------------------------
 
@@ -209,7 +209,7 @@ introspector.restrict.packages = java.la
 
 introspector.restrict.classes = java.lang.Class
 introspector.restrict.classes = java.lang.ClassLoader
-                
+
 # Restrict these for extra safety
 
 introspector.restrict.classes = java.lang.Compiler

Modified: velocity/engine/trunk/velocity-engine-core/src/test/java/org/apache/velocity/test/BaseTestCase.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/test/java/org/apache/velocity/test/BaseTestCase.java?rev=1040976&r1=1040975&r2=1040976&view=diff
==============================================================================
--- velocity/engine/trunk/velocity-engine-core/src/test/java/org/apache/velocity/test/BaseTestCase.java (original)
+++ velocity/engine/trunk/velocity-engine-core/src/test/java/org/apache/velocity/test/BaseTestCase.java Wed Dec  1 12:15:39 2010
@@ -16,7 +16,7 @@ package org.apache.velocity.test;
  * "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.    
+ * under the License.
  */
 
 import java.io.File;
@@ -167,12 +167,12 @@ public abstract class BaseTestCase exten
      * Compare an expected string with the given loaded template
      */
     protected void assertTmplEquals(String expected, String template)
-    {        
+    {
         info("Expected:  " + expected + " from '" + template + "'");
 
         StringWriter writer = new StringWriter();
         try
-        {          
+        {
             engine.mergeTemplate(template, "utf-8", context, writer);
         }
         catch (RuntimeException re)
@@ -184,12 +184,12 @@ public abstract class BaseTestCase exten
         {
             info("Exception!", e);
             throw new RuntimeException(e);
-        }        
+        }
 
         info("Result:  " + writer.toString());
-        assertEquals(expected, writer.toString());  
+        assertEquals(expected, writer.toString());
     }
-    
+
     /**
      * Ensure that a context value is as expected.
      */
@@ -358,7 +358,7 @@ public abstract class BaseTestCase exten
                 buf.append(baseFile.getPath());
             }
 
-            if (org.apache.commons.lang.StringUtils.isNotEmpty(ext))
+            if (org.apache.velocity.thirdparty.commons.lang.StringUtils.isNotEmpty(ext))
             {
                 buf.append('.').append(ext);
             }

Modified: velocity/engine/trunk/velocity-engine-core/src/test/java/org/apache/velocity/test/sql/HsqlDB.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/test/java/org/apache/velocity/test/sql/HsqlDB.java?rev=1040976&r1=1040975&r2=1040976&view=diff
==============================================================================
--- velocity/engine/trunk/velocity-engine-core/src/test/java/org/apache/velocity/test/sql/HsqlDB.java (original)
+++ velocity/engine/trunk/velocity-engine-core/src/test/java/org/apache/velocity/test/sql/HsqlDB.java Wed Dec  1 12:15:39 2010
@@ -16,11 +16,10 @@ package org.apache.velocity.test.sql;
  * "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.    
+ * under the License.
  */
 
-import org.apache.commons.lang.StringUtils;
-
+import org.apache.velocity.thirdparty.commons.lang.StringUtils;
 import org.hsqldb.jdbcDriver;
 
 import java.io.FileReader;