Fix bug #1385272: Parsing of short open tags not fully compatible to PHP parse
authoraxelcl <axelcl>
Mon, 19 Dec 2005 20:18:04 +0000 (20:18 +0000)
committeraxelcl <axelcl>
Mon, 19 Dec 2005 20:18:04 +0000 (20:18 +0000)
net.sourceforge.phpeclipse.tests/src/net/sourceforge/phpeclipse/tests/parser/OverlibTestCase.java
net.sourceforge.phpeclipse.tests/src/net/sourceforge/phpeclipse/tests/parser/PHPParserTestCase.java
net.sourceforge.phpeclipse.tests/src/net/sourceforge/phpeclipse/tests/parser/PHPParserTestSuite.java [new file with mode: 0644]
net.sourceforge.phpeclipse.tests/src/net/sourceforge/phpeclipse/tests/parser/ShortTagTestCase.java [new file with mode: 0644]
net.sourceforge.phpeclipse.tests/src/net/sourceforge/phpeclipse/tests/parser/SmartyCompilerTestCase.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Scanner.java

index b119ff8..db9099e 100644 (file)
@@ -487,27 +487,14 @@ public class OverlibTestCase extends AbstractCompilerTest {
                "");
 //    parser.phpParserTester(strEval, 1);
   }
-  private void checkHTML(String strEval) {
-    if (Scanner.DEBUG) {
-      System.out.println("\n------------------------------------");
-      System.out.println(strEval);
-    }
-    checkParseHTML(
-        strEval.toCharArray(),
-               "");
-//    parser.phpParserTester(strEval, 1);
-  }
 //  private void checkHTML(String strEval) {
 //    if (Scanner.DEBUG) {
 //      System.out.println("\n------------------------------------");
 //      System.out.println(strEval);
 //    }
-//    parser.parse(strEval);
-//  }
-//  /**
-//   * The JUnit setup method
-//   */
-//  protected void setUp() {
-//    parser = new Parser(null);
+//    checkParseHTML(
+//        strEval.toCharArray(),
+//             "");
+////    parser.phpParserTester(strEval, 1);
 //  }
 }
index db68ad3..ff9c420 100644 (file)
@@ -223,25 +223,13 @@ public class PHPParserTestCase extends AbstractCompilerTest {
                // parser.phpParserTester(strEval, 1);
        }
 
-       private void checkHTML(String strEval) {
-               if (Scanner.DEBUG) {
-                       System.out.println("\n------------------------------------");
-                       System.out.println(strEval);
-               }
-               checkParseHTML(strEval.toCharArray(), "");
-               // parser.phpParserTester(strEval, 1);
-       }
-       // private void checkHTML(String strEval) {
-       // if (Scanner.DEBUG) {
-       // System.out.println("\n------------------------------------");
-       // System.out.println(strEval);
-       // }
-       // parser.parse(strEval);
-       // }
-       // /**
-       // * The JUnit setup method
-       // */
-       // protected void setUp() {
-       // parser = new Parser(null);
-       // }
+//     private void checkHTML(String strEval) {
+//             if (Scanner.DEBUG) {
+//                     System.out.println("\n------------------------------------");
+//                     System.out.println(strEval);
+//             }
+//             checkParseHTML(strEval.toCharArray(), "");
+//             // parser.phpParserTester(strEval, 1);
+//     }
+
 }
diff --git a/net.sourceforge.phpeclipse.tests/src/net/sourceforge/phpeclipse/tests/parser/PHPParserTestSuite.java b/net.sourceforge.phpeclipse.tests/src/net/sourceforge/phpeclipse/tests/parser/PHPParserTestSuite.java
new file mode 100644 (file)
index 0000000..8320b5b
--- /dev/null
@@ -0,0 +1,36 @@
+package net.sourceforge.phpeclipse.tests.parser;
+
+/*******************************************************************************
+ * Copyright (c) 2002 www.phpeclipse.de All rights
+ * reserved. This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0 which accompanies this
+ * distribution, and is available at http://www.eclipse.org/legal/cpl-v10.html
+ ******************************************************************************/
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * PHPeclipse Parser Test Suite
+ * Runs all PHP parser test cases
+ *
+ */
+public class PHPParserTestSuite extends TestCase {
+
+       public PHPParserTestSuite(String name) {
+               super(name);
+       }
+
+       public static Test suite() {
+               TestSuite suite = new TestSuite("PHPeclipse Parser Test Suite");
+               suite.addTest(new TestSuite(PHPParserTestCase.class));
+               suite.addTest(new TestSuite(ShortTagTestCase.class));
+               suite.addTest(new TestSuite(PHPManualTestCase.class));
+               suite.addTest(new TestSuite(OverlibTestCase.class));
+               suite.addTest(new TestSuite(SmartyCompilerTestCase.class));
+               return suite;
+
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse.tests/src/net/sourceforge/phpeclipse/tests/parser/ShortTagTestCase.java b/net.sourceforge.phpeclipse.tests/src/net/sourceforge/phpeclipse/tests/parser/ShortTagTestCase.java
new file mode 100644 (file)
index 0000000..6924876
--- /dev/null
@@ -0,0 +1,28 @@
+package net.sourceforge.phpeclipse.tests.parser;
+
+/*******************************************************************************
+ * Copyright (c) 2002 www.phpeclipse.de All rights
+ * reserved. This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0 which accompanies this
+ * distribution, and is available at http://www.eclipse.org/legal/cpl-v10.html
+ ******************************************************************************/
+import net.sourceforge.phpdt.core.tests.util.AbstractCompilerTest;
+
+/**
+ * Tests the php parser
+ */
+public class ShortTagTestCase extends AbstractCompilerTest {
+       public ShortTagTestCase(String name) {
+               super(name);
+       }
+
+       /**
+        * Test the PHP Parser with different PHP short tag snippets
+        */
+       public void testPHPParser() {
+               checkHTML("<?=$var?>");
+               checkHTML("<?=\"a\"; someOtherPHPCode(); ?>");
+               checkHTML("<?= \"a\", \"b\" ?> text <?= \"a\", \"b\" ?>");
+       }
+
+}
index 88c39dd..6b1abb5 100644 (file)
@@ -19,1888 +19,1888 @@ public class SmartyCompilerTestCase extends AbstractCompilerTest {
    * Test the PHP Parser with different PHP snippets
    */
   public void testPHPParser() {
-    checkHTML("<?php\n" + 
-               "\n" + 
-               "/**\n" + 
-               " * Project:     Smarty: the PHP compiling template engine\n" + 
-               " * File:        Smarty_Compiler.class.php\n" + 
-               " * Author:      Monte Ohrt <monte@ispi.net>\n" + 
-               " *              Andrei Zmievski <andrei@php.net>\n" + 
-               " *\n" + 
-               " * Version:     2.4.2\n" + 
-               " * Copyright:   2001,2002 ispi of Lincoln, Inc.\n" + 
-               " *\n" + 
-               " * This library is free software; you can redistribute it and/or\n" + 
-               " * modify it under the terms of the GNU Lesser General Public\n" + 
-               " * License as published by the Free Software Foundation; either\n" + 
-               " * version 2.1 of the License, or (at your option) any later version.\n" + 
-               " *\n" + 
-               " * This library is distributed in the hope that it will be useful,\n" + 
-               " * but WITHOUT ANY WARRANTY; without even the implied warranty of\n" + 
-               " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n" + 
-               " * Lesser General Public License for more details.\n" + 
-               " *\n" + 
-               " * You should have received a copy of the GNU Lesser General Public\n" + 
-               " * License along with this library; if not, write to the Free Software\n" + 
-               " * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n" + 
-               " *\n" + 
-               " * You may contact the authors of Smarty by e-mail at:\n" + 
-               " * monte@ispi.net\n" + 
-               " * andrei@php.net\n" + 
-               " *\n" + 
-               " * Or, write to:\n" + 
-               " * Monte Ohrt\n" + 
-               " * Director of Technology, ispi\n" + 
-               " * 237 S. 70th suite 220\n" + 
-               " * Lincoln, NE 68510\n" + 
-               " *\n" + 
-               " * The latest version of Smarty can be obtained from:\n" + 
-               " * http://www.phpinsider.com/\n" + 
-               " *\n" + 
-               " */\n" + 
-               "\n" + 
-               "class Smarty_Compiler extends Smarty {\n" + 
-               "       \n" + 
-               "    // internal vars\n" + 
-               "    public $_sectionelse_stack     =   array();    // keeps track of whether section had \'else\' part\n" + 
-               "    public $_foreachelse_stack     =   array();    // keeps track of whether foreach had \'else\' part\n" + 
-               "    public $_literal_blocks        =   array();    // keeps literal template blocks\n" + 
-               "    public $_php_blocks            =   array();    // keeps php code blocks\n" + 
-               "    public $_current_file          =   null;       // the current template being compiled\n" + 
-               "    public $_current_line_no       =   1;          // line number for error messages\n" + 
-               "    public $_capture_stack         =   array();    // keeps track of nested capture buffers\n" + 
-               "    public $_plugin_info           =   array();    // keeps track of plugins to load\n" + 
-               "    public $_init_smarty_vars      =   false;\n" + 
-               "       public $_permitted_tokens               =       array(\'true\',\'false\',\'yes\',\'no\',\'on\',\'off\');\n" + 
-               "    public $_db_qstr_regexp            =       null;           // regexps are setup in the constructor\n" + 
-               "    public $_si_qstr_regexp            =       null;\n" + 
-               "    public $_qstr_regexp                       =       null;\n" + 
-               "    public $_func_regexp                       =       null;\n" + 
-               "    public $_var_bracket_regexp        =       null;\n" + 
-               "    public $_dvar_guts_regexp          =       null;\n" + 
-               "    public $_dvar_regexp                       =       null;\n" + 
-               "    public $_cvar_regexp                       =       null;\n" + 
-               "    public $_svar_regexp                       =       null;\n" + 
-               "    public $_avar_regexp                       =       null;\n" + 
-               "    public $_mod_regexp                        =       null;\n" + 
-               "    public $_var_regexp                    =   null;\n" + 
-               "    public $_parenth_param_regexp      =       null;\n" + 
-               "       public $_func_call_regexp               =       null;\n" + 
-               "       public $_obj_ext_regexp         =       null;\n" + 
-               "       public $_obj_start_regexp               =       null;\n" + 
-               "       public $_obj_params_regexp              =       null;\n" + 
-               "       public $_obj_call_regexp                =       null;\n" + 
-               "\n" + 
-               "       /**\n" + 
-               "        * The class constructor.\n" + 
-               "        *\n" + 
-               "        * @access public\n" + 
-               "        */\n" + 
-               "    function Smarty_Compiler()\n" + 
-               "    {\n" + 
-               "               // matches double quoted strings:\n" + 
-               "               // \"foobar\"\n" + 
-               "               // \"foo\\\"bar\"\n" + 
-               "       $this->_db_qstr_regexp = \'\"[^\"\\\\\\\\]*(?:\\\\\\\\.[^\"\\\\\\\\]*)*\"\';\n" + 
-               "\n" + 
-               "               // matches single quoted strings:\n" + 
-               "               // \'foobar\'\n" + 
-               "               // \'foo\\\'bar\'\n" + 
-               "       $this->_si_qstr_regexp = \'\\\'[^\\\'\\\\\\\\]*(?:\\\\\\\\.[^\\\'\\\\\\\\]*)*\\\'\';\n" + 
-               "\n" + 
-               "               // matches single or double quoted strings\n" + 
-               "       $this->_qstr_regexp = \'(?:\' . $this->_db_qstr_regexp . \'|\' . $this->_si_qstr_regexp . \')\';\n" + 
-               "\n" + 
-               "               // matches bracket portion of vars\n" + 
-               "               // [0]\n" + 
-               "               // [foo]\n" + 
-               "               // [$bar]\n" + 
-               "               $this->_var_bracket_regexp = \'\\[\\$?[\\w\\.]+\\]\';\n" + 
-               "                               \n" + 
-               "               // matches $ vars (not objects):\n" + 
-               "               // $foo\n" + 
-               "               // $foo.bar\n" + 
-               "               // $foo.bar.foobar\n" + 
-               "               // $foo[0]\n" + 
-               "               // $foo[$bar]\n" + 
-               "               // $foo[5][blah]\n" + 
-               "               // $foo[5].bar[$foobar][4]\n" + 
-               "               $this->_dvar_guts_regexp = \'\\w+(?:\' . $this->_var_bracket_regexp\n" + 
-               "                               . \')*(?:\\.\\$?\\w+(?:\' . $this->_var_bracket_regexp . \')*)*\';\n" + 
-               "               $this->_dvar_regexp = \'\\$\' . $this->_dvar_guts_regexp;\n" + 
-               "\n" + 
-               "               // matches config vars:\n" + 
-               "               // #foo#\n" + 
-               "               // #foobar123_foo#\n" + 
-               "               $this->_cvar_regexp = \'\\#\\w+\\#\';\n" + 
-               "\n" + 
-               "               // matches section vars:\n" + 
-               "               // %foo.bar%\n" + 
-               "               $this->_svar_regexp = \'\\%\\w+\\.\\w+\\%\';\n" + 
-               "\n" + 
-               "               // matches all valid variables (no quotes, no modifiers)\n" + 
-               "               $this->_avar_regexp = \'(?:\' . $this->_dvar_regexp . \'|\'\n" + 
-               "                  . $this->_cvar_regexp . \'|\' . $this->_svar_regexp . \')\';\n" + 
-               "\n" + 
-               "               // matches valid modifier syntax:\n" + 
-               "               // |foo\n" + 
-               "               // |@foo\n" + 
-               "               // |foo:\"bar\"\n" + 
-               "               // |foo:$bar\n" + 
-               "               // |foo:\"bar\":$foobar\n" + 
-               "               // |foo|bar\n" + 
-               "               // |foo\n" + 
-               "               $this->_mod_regexp = \'(?:\\|@?\\w+(?::(?>\\w+|\'\n" + 
-               "                  . $this->_avar_regexp . \'|\' . $this->_qstr_regexp .\'))*)\';\n" + 
-               "\n" + 
-               "               // matches valid variable syntax:\n" + 
-               "               // $foo\n" + 
-               "               // $foo\n" + 
-               "               // #foo#\n" + 
-               "               // #foo#\n" + 
-               "               // \"text\"\n" + 
-               "               // \"text\"\n" + 
-               "               $this->_var_regexp = \'(?:\' . $this->_avar_regexp . \'|\' . $this->_qstr_regexp . \')\';\n" + 
-               "                               \n" + 
-               "               // matches valid object call (no objects allowed in parameters):\n" + 
-               "               // $foo->bar\n" + 
-               "               // $foo->bar()\n" + 
-               "               // $foo->bar(\"text\")\n" + 
-               "               // $foo->bar($foo, $bar, \"text\")\n" + 
-               "               // $foo->bar($foo|bar, \"foo\"|bar)\n" + 
-               "               // $foo->bar->foo()\n" + 
-               "               // $foo->bar->foo->bar()\n" + 
-               "               $this->_obj_ext_regexp = \'\\->(?:\\w+|\' . $this->_dvar_regexp . \')\';\n" + 
-               "       $this->_obj_params_regexp = \'\\((?:\\w+|\'\n" + 
-               "                               . $this->_var_regexp . \'(?>\' . $this->_mod_regexp . \'*)(?:\\s*,\\s*(?:(?:\\w+|\'\n" + 
-               "                               . $this->_var_regexp . \'(?>\' . $this->_mod_regexp . \'*))))*)?\\)\';          \n" + 
-               "       $this->_obj_start_regexp = \'(?:\' . $this->_dvar_regexp . \'(?:\' . $this->_obj_ext_regexp . \')+)\';\n" + 
-               "               $this->_obj_call_regexp = \'(?:\' . $this->_obj_start_regexp . \'(?:\' . $this->_obj_params_regexp . \')?)\';\n" + 
-               "               \n" + 
-               "               // matches valid function name:\n" + 
-               "               // foo123\n" + 
-               "               // _foo_bar\n" + 
-               "               $this->_func_regexp = \'[a-zA-Z_]\\w*\';\n" + 
-               "\n" + 
-               "               // matches valid registered object:\n" + 
-               "               // foo.bar\n" + 
-               "               $this->_reg_obj_regexp = \'[a-zA-Z_]\\w*->[a-zA-Z_]\\w*\';\n" + 
-               "                               \n" + 
-               "               // matches valid parameter values:\n" + 
-               "               // true\n" + 
-               "               // $foo\n" + 
-               "               // $foo|bar\n" + 
-               "               // #foo#\n" + 
-               "               // #foo#|bar\n" + 
-               "               // \"text\"\n" + 
-               "               // \"text\"|bar\n" + 
-               "               // $foo->bar\n" + 
-               "               $this->_param_regexp = \'(?:\\s*(?:\' . $this->_obj_call_regexp . \'|\'\n" + 
-               "                  . $this->_var_regexp  . \'|\\w+)(?>\' . $this->_mod_regexp . \'*)\\s*)\';            \n" + 
-               "               \n" + 
-               "               // matches valid parenthesised function parameters:\n" + 
-               "               // \n" + 
-               "               // \"text\"\n" + 
-               "               //      $foo, $bar, \"text\"\n" + 
-               "               // $foo|bar, \"foo\"|bar, $foo->bar($foo)|bar\n" + 
-               "       $this->_parenth_param_regexp = \'(?:\\((?:\\w+|\'\n" + 
-               "                               . $this->_param_regexp . \'(?:\\s*,\\s*(?:(?:\\w+|\'\n" + 
-               "                               . $this->_param_regexp . \')))*)?\\))\';\n" + 
-               "       \n" + 
-               "               // matches valid function call:\n" + 
-               "               // foo()\n" + 
-               "               // foo_bar($foo)\n" + 
-               "               // _foo_bar($foo,\"bar\")\n" + 
-               "               // foo123($foo,$foo->bar(),\"foo\")\n" + 
-               "       $this->_func_call_regexp = \'(?:\' . $this->_func_regexp . \'\\s*(?:\'\n" + 
-               "                  . $this->_parenth_param_regexp . \'))\';             \n" + 
-               "\n" + 
-               "       }                       \n" + 
-               "                       \n" + 
-               "       /**\n" + 
-               "        * compile a template file\n" + 
-               "        *\n" + 
-               "        * @access public\n" + 
-               "        * @param  $tpl_file\n" + 
-               "        * @param  $template_source\n" + 
-               "        * @param  $template_compiled\n" + 
-               "        */\n" + 
-               "    function _compile_file($tpl_file, $template_source, &$template_compiled)\n" + 
-               "    {\n" + 
-               "        if ($this->security) {\n" + 
-               "            // do not allow php syntax to be executed unless specified\n" + 
-               "            if ($this->php_handling == SMARTY_PHP_ALLOW &&\n" + 
-               "                !$this->security_settings[\'PHP_HANDLING\']) {\n" + 
-               "                $this->php_handling = SMARTY_PHP_PASSTHRU;\n" + 
-               "            }\n" + 
-               "        }\n" + 
-               "\n" + 
-               "        $this->_load_filters();\n" + 
-               "\n" + 
-               "        $this->_current_file = $tpl_file;\n" + 
-               "        $this->_current_line_no = 1;\n" + 
-               "        $ldq = preg_quote($this->left_delimiter, \'!\');\n" + 
-               "        $rdq = preg_quote($this->right_delimiter, \'!\');\n" + 
-               "\n" + 
-               "        // run template source through prefilter functions\n" + 
-               "        if (count($this->_plugins[\'prefilter\']) > 0) {\n" + 
-               "            foreach ($this->_plugins[\'prefilter\'] as $filter_name => $prefilter) {\n" + 
-               "                if ($prefilter === false) continue; \n" + 
-               "                if ($prefilter[3] || function_exists($prefilter[0])) {\n" + 
-               "                    $template_source = $prefilter[0]($template_source, $this);\n" + 
-               "                    $this->_plugins[\'prefilter\'][$filter_name][3] = true;\n" + 
-               "                } else {\n" + 
-               "                    $this->_trigger_fatal_error(\"[plugin] prefilter \'$filter_name\' is not implemented\");\n" + 
-               "                }\n" + 
-               "            }\n" + 
-               "        }\n" + 
-               "\n" + 
-               "        /* Annihilate the comments. */\n" + 
-               "        $template_source = preg_replace(\"!({$ldq})\\*(.*?)\\*({$rdq})!se\",\n" + 
-               "                                        \"\'\\\\1*\'.str_repeat(\\\"\\n\\\", substr_count(\'\\\\2\', \\\"\\n\\\")) .\'*\\\\3\'\",\n" + 
-               "                                        $template_source);\n" + 
-               "\n" + 
-               "        /* Pull out the literal blocks. */\n" + 
-               "        preg_match_all(\"!{$ldq}literal{$rdq}(.*?){$ldq}/literal{$rdq}!s\", $template_source, $match);\n" + 
-               "        $this->_literal_blocks = $match[1];\n" + 
-               "        $template_source = preg_replace(\"!{$ldq}literal{$rdq}(.*?){$ldq}/literal{$rdq}!s\",\n" + 
-               "                                        $this->quote_replace($this->left_delimiter.\'literal\'.$this->right_delimiter), $template_source);\n" + 
-               "\n" + 
-               "        /* Pull out the php code blocks. */\n" + 
-               "        preg_match_all(\"!{$ldq}php{$rdq}(.*?){$ldq}/php{$rdq}!s\", $template_source, $match);\n" + 
-               "        $this->_php_blocks = $match[1];\n" + 
-               "        $template_source = preg_replace(\"!{$ldq}php{$rdq}(.*?){$ldq}/php{$rdq}!s\",\n" + 
-               "                                        $this->quote_replace($this->left_delimiter.\'php\'.$this->right_delimiter), $template_source);\n" + 
-               "\n" + 
-               "        /* Gather all template tags. */\n" + 
-               "        preg_match_all(\"!{$ldq}\\s*(.*?)\\s*{$rdq}!s\", $template_source, $match);\n" + 
-               "        $template_tags = $match[1];\n" + 
-               "        /* Split content by template tags to obtain non-template content. */\n" + 
-               "        $text_blocks = preg_split(\"!{$ldq}.*?{$rdq}!s\", $template_source);\n" + 
-               "               \n" + 
-               "        /* loop through text blocks */\n" + 
-               "        for ($curr_tb = 0, $for_max = count($text_blocks); $curr_tb < $for_max; $curr_tb++) {\n" + 
-               "            /* match anything resembling php tags */\n" + 
-               "            if (preg_match_all(\'!(<\\?(?:\\w+|=)?|\\?>|language\\s*=\\s*[\\\"\\\']?php[\\\"\\\']?)!is\', $text_blocks[$curr_tb], $sp_match)) {\n" + 
-               "                               /* replace tags with placeholders to prevent recursive replacements */\n" + 
-               "                               $sp_match[1] = array_unique($sp_match[1]);\n" + 
-               "                               usort($sp_match[1], \'_smarty_sort_length\');\n" + 
-               "                for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) {\n" + 
-               "                                       $text_blocks[$curr_tb] = str_replace($sp_match[1][$curr_sp],\'%%%SMARTYSP\'.$curr_sp.\'%%%\',$text_blocks[$curr_tb]);\n" + 
-               "                               }\n" + 
-               "                /* process each one */\n" + 
-               "                for ($curr_sp = 0, $for_max2 = count($sp_match[0]); $curr_sp < $for_max2; $curr_sp++) {\n" + 
-               "                    if ($this->php_handling == SMARTY_PHP_PASSTHRU) {\n" + 
-               "                        /* echo php contents */\n" + 
-               "                        $text_blocks[$curr_tb] = str_replace(\'%%%SMARTYSP\'.$curr_sp.\'%%%\', \'<?php echo \\\'\'.str_replace(\"\'\", \"\\\'\", $sp_match[1][$curr_sp]).\'\\\'; ?>\'.\"\\n\", $text_blocks[$curr_tb]);\n" + 
-               "                    } else if ($this->php_handling == SMARTY_PHP_QUOTE) {\n" + 
-               "                        /* quote php tags */\n" + 
-               "                        $text_blocks[$curr_tb] = str_replace(\'%%%SMARTYSP\'.$curr_sp.\'%%%\', htmlspecialchars($sp_match[1][$curr_sp]), $text_blocks[$curr_tb]);\n" + 
-               "                    } else if ($this->php_handling == SMARTY_PHP_REMOVE) {\n" + 
-               "                        /* remove php tags */\n" + 
-               "                        $text_blocks[$curr_tb] = str_replace(\'%%%SMARTYSP\'.$curr_sp.\'%%%\', \'\', $text_blocks[$curr_tb]);\n" + 
-               "                    } else {\n" + 
-               "                                               /* SMARTY_PHP_ALLOW, but echo non php starting tags */\n" + 
-               "                                               $sp_match[1][$curr_sp] = preg_replace(\'%(<\\?(?!php|=|$))%i\', \'<?php echo \\\'\\\\1\\\'?>\'.\"\\n\", $sp_match[1][$curr_sp]);\n" + 
-               "                                               $text_blocks[$curr_tb] = str_replace(\'%%%SMARTYSP\'.$curr_sp.\'%%%\', $sp_match[1][$curr_sp], $text_blocks[$curr_tb]);\n" + 
-               "                                       }\n" + 
-               "                }\n" + 
-               "            }\n" + 
-               "        }\n" + 
-               "\n" + 
-               "        /* Compile the template tags into PHP code. */\n" + 
-               "        $compiled_tags = array();\n" + 
-               "        for ($i = 0, $for_max = count($template_tags); $i < $for_max; $i++) {\n" + 
-               "            $this->_current_line_no += substr_count($text_blocks[$i], \"\\n\");\n" + 
-               "            $compiled_tags[] = $this->_compile_tag($template_tags[$i]);\n" + 
-               "            $this->_current_line_no += substr_count($template_tags[$i], \"\\n\");\n" + 
-               "        }\n" + 
-               "\n" + 
-               "        $template_compiled = \'\';\n" + 
-               "\n" + 
-               "        /* Interleave the compiled contents and text blocks to get the final result. */\n" + 
-               "        for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) {\n" + 
-               "            $template_compiled .= $text_blocks[$i].$compiled_tags[$i];\n" + 
-               "        }\n" + 
-               "        $template_compiled .= $text_blocks[$i];\n" + 
-               "\n" + 
-               "        /* Reformat data between \'strip\' and \'/strip\' tags, removing spaces, tabs and newlines. */\n" + 
-               "        if (preg_match_all(\"!{$ldq}strip{$rdq}.*?{$ldq}/strip{$rdq}!s\", $template_compiled, $match)) {\n" + 
-               "            $strip_tags = $match[0];\n" + 
-               "            $strip_tags_modified = preg_replace(\"!{$ldq}/?strip{$rdq}|[\\t ]+$|^[\\t ]+!m\", \'\', $strip_tags);\n" + 
-               "            $strip_tags_modified = preg_replace(\'![\\r\\n]+!m\', \'\', $strip_tags_modified);\n" + 
-               "            for ($i = 0, $for_max = count($strip_tags); $i < $for_max; $i++)\n" + 
-               "                $template_compiled = preg_replace(\"!{$ldq}strip{$rdq}.*?{$ldq}/strip{$rdq}!s\",\n" + 
-               "                                                  $this->quote_replace($strip_tags_modified[$i]),\n" + 
-               "                                                  $template_compiled, 1);\n" + 
-               "        }\n" + 
-               "\n" + 
-               "        // remove \\n from the end of the file, if any\n" + 
-               "        if ($template_compiled{strlen($template_compiled) - 1} == \"\\n\" ) {\n" + 
-               "            $template_compiled = substr($template_compiled, 0, -1);\n" + 
-               "        }\n" + 
-               "\n" + 
-               "        // run compiled template through postfilter functions\n" + 
-               "        if (count($this->_plugins[\'postfilter\']) > 0) {\n" + 
-               "            foreach ($this->_plugins[\'postfilter\'] as $filter_name => $postfilter) {\n" + 
-               "                if ($postfilter === false) continue;\n" + 
-               "                if ($postfilter[3] || function_exists($postfilter[0])) {\n" + 
-               "                    $template_compiled = $postfilter[0]($template_compiled, $this);\n" + 
-               "                    $this->_plugins[\'postfilter\'][$filter_name][3] = true;\n" + 
-               "                } else {\n" + 
-               "                    $this->_trigger_plugin_error(\"Smarty plugin error: postfilter \'$filter_name\' is not implemented\");\n" + 
-               "                }\n" + 
-               "            }\n" + 
-               "        }\n" + 
-               "\n" + 
-               "        // put header at the top of the compiled template\n" + 
-               "        $template_header = \"<?php /* Smarty version \".$this->_version.\", created on \".strftime(\"%Y-%m-%d %H:%M:%S\").\"\\n\";\n" + 
-               "        $template_header .= \"         compiled from \".$tpl_file.\" */ ?>\\n\";\n" + 
-               "\n" + 
-               "        /* Emit code to load needed plugins. */\n" + 
-               "        if (count($this->_plugin_info)) {\n" + 
-               "            $plugins_code = \'<?php $this->_load_plugins(array(\';\n" + 
-               "            foreach ($this->_plugin_info as $plugin_type => $plugins) {\n" + 
-               "                foreach ($plugins as $plugin_name => $plugin_info) {\n" + 
-               "                    $plugins_code .= \"\\narray(\'$plugin_type\', \'$plugin_name\', \'$plugin_info[0]\', $plugin_info[1], \";\n" + 
-               "                    $plugins_code .= $plugin_info[2] ? \'true),\' : \'false),\';\n" + 
-               "                }\n" + 
-               "            }\n" + 
-               "            $plugins_code .= \")); ?>\";\n" + 
-               "            $template_header .= $plugins_code;\n" + 
-               "            $this->_plugin_info = array();\n" + 
-               "        }\n" + 
-               "\n" + 
-               "        if ($this->_init_smarty_vars) {\n" + 
-               "            $template_header .= \"<?php \\$this->_assign_smarty_interface(); ?>\\n\";\n" + 
-               "            $this->_init_smarty_vars = false;\n" + 
-               "        }\n" + 
-               "\n" + 
-               "        $template_compiled = $template_header . $template_compiled;\n" + 
-               "\n" + 
-               "        return true;\n" + 
-               "    }\n" + 
-               "\n" + 
-               "       /**\n" + 
-               "        * Compile a template tag\n" + 
-               "        *\n" + 
-               "        * @access public\n" + 
-               "        * @param  $template_tag\n" + 
-               "        */\n" + 
-               "    function _compile_tag($template_tag)\n" + 
-               "    {          \n" + 
-               "                               \n" + 
-               "        /* Matched comment. */\n" + 
-               "        if ($template_tag{0} == \'*\' && $template_tag{strlen($template_tag) - 1} == \'*\')\n" + 
-               "            return \'\';\n" + 
-               "               \n" + 
-               "        /* Split tag into two three parts: command, command modifiers and the arguments. */\n" + 
-               "        if(! preg_match(\'/^(?:(\' . $this->_obj_call_regexp . \'|\' . $this->_var_regexp\n" + 
-               "                               . \'|\' . $this->_reg_obj_regexp . \'|\\/?\' . $this->_func_regexp . \')(\' . $this->_mod_regexp . \'*))\n" + 
-               "                      (?:\\s+(.*))?$\n" + 
-               "                    /xs\', $template_tag, $match)) {\n" + 
-               "                       $this->_syntax_error(\"unrecognized tag: $template_tag\", E_USER_ERROR, __FILE__, __LINE__);\n" + 
-               "               }\n" + 
-               "\n" + 
-               "        $tag_command = $match[1];\n" + 
-               "        $tag_modifier = isset($match[2]) ? $match[2] : null;\n" + 
-               "        $tag_args = isset($match[3]) ? $match[3] : null;\n" + 
-               "               \n" + 
-               "               \n" + 
-               "        /* If the tag name is a variable or object, we process it. */\n" + 
-               "        if (preg_match(\'!^\' . $this->_obj_call_regexp . \'|\' . $this->_var_regexp . \'$!\', $tag_command)) {\n" + 
-               "            $return = $this->_parse_var_props($tag_command . $tag_modifier, $this->_parse_attrs($tag_args));\n" + 
-               "                       if(isset($_tag_attrs[\'assign\'])) {\n" + 
-               "                               return \"<?php \\$this->assign(\'\" . $this->_dequote($_tag_attrs[\'assign\']) . \"\', $return ); ?>\\n\";  \n" + 
-               "                       } else {\n" + 
-               "               return \"<?php echo $return; ?>\\n\";\n" + 
-               "                       }\n" + 
-               "               }\n" + 
-               "               \n" + 
-               "           /* If the tag name is a registered object, we process it. */\n" + 
-               "        if (preg_match(\'!^\' . $this->_reg_obj_regexp . \'$!\', $tag_command)) {\n" + 
-               "                       return $this->_compile_registered_object_tag($tag_command, $this->_parse_attrs($tag_args), $tag_modifier);\n" + 
-               "               }\n" + 
-               "\n" + 
-               "        switch ($tag_command) {\n" + 
-               "            case \'include\':\n" + 
-               "                return $this->_compile_include_tag($tag_args);\n" + 
-               "\n" + 
-               "            case \'include_php\':\n" + 
-               "                return $this->_compile_include_php_tag($tag_args);\n" + 
-               "\n" + 
-               "            case \'if\':\n" + 
-               "                return $this->_compile_if_tag($tag_args);\n" + 
-               "\n" + 
-               "            case \'else\':\n" + 
-               "                return \'<?php else: ?>\';\n" + 
-               "\n" + 
-               "            case \'elseif\':\n" + 
-               "                return $this->_compile_if_tag($tag_args, true);\n" + 
-               "\n" + 
-               "            case \'/if\':\n" + 
-               "                return \'<?php endif; ?>\';\n" + 
-               "\n" + 
-               "            case \'capture\':\n" + 
-               "                return $this->_compile_capture_tag(true, $tag_args);\n" + 
-               "\n" + 
-               "            case \'/capture\':\n" + 
-               "                return $this->_compile_capture_tag(false);\n" + 
-               "\n" + 
-               "            case \'ldelim\':\n" + 
-               "                return $this->left_delimiter;\n" + 
-               "\n" + 
-               "            case \'rdelim\':\n" + 
-               "                return $this->right_delimiter;\n" + 
-               "\n" + 
-               "            case \'section\':\n" + 
-               "                array_push($this->_sectionelse_stack, false);\n" + 
-               "                return $this->_compile_section_start($tag_args);\n" + 
-               "\n" + 
-               "            case \'sectionelse\':\n" + 
-               "                $this->_sectionelse_stack[count($this->_sectionelse_stack)-1] = true;\n" + 
-               "                return \"<?php endfor; else: ?>\";\n" + 
-               "\n" + 
-               "            case \'/section\':\n" + 
-               "                if (array_pop($this->_sectionelse_stack))\n" + 
-               "                    return \"<?php endif; ?>\";\n" + 
-               "                else\n" + 
-               "                    return \"<?php endfor; endif; ?>\";\n" + 
-               "\n" + 
-               "            case \'foreach\':\n" + 
-               "                array_push($this->_foreachelse_stack, false);\n" + 
-               "                return $this->_compile_foreach_start($tag_args);\n" + 
-               "                break;\n" + 
-               "\n" + 
-               "            case \'foreachelse\':\n" + 
-               "                $this->_foreachelse_stack[count($this->_foreachelse_stack)-1] = true;\n" + 
-               "                return \"<?php endforeach; else: ?>\";\n" + 
-               "\n" + 
-               "            case \'/foreach\':\n" + 
-               "                if (array_pop($this->_foreachelse_stack))\n" + 
-               "                    return \"<?php endif; ?>\";\n" + 
-               "                else\n" + 
-               "                    return \"<?php endforeach; endif; ?>\";\n" + 
-               "\n" + 
-               "            case \'config_load\':\n" + 
-               "                return $this->_compile_config_load_tag($tag_args);\n" + 
-               "\n" + 
-               "            case \'strip\':\n" + 
-               "            case \'/strip\':\n" + 
-               "                return $this->left_delimiter.$tag_command.$this->right_delimiter;\n" + 
-               "\n" + 
-               "            case \'literal\':\n" + 
-               "                list (,$literal_block) = each($this->_literal_blocks);\n" + 
-               "                $this->_current_line_no += substr_count($literal_block, \"\\n\");\n" + 
-               "                return \"<?php echo \'\".str_replace(\"\'\", \"\\\'\", str_replace(\"\\\\\", \"\\\\\\\\\", $literal_block)).\"\'; ?>\\n\";\n" + 
-               "\n" + 
-               "            case \'php\':\n" + 
-               "                if ($this->security && !$this->security_settings[\'PHP_TAGS\']) {\n" + 
-               "                    $this->_syntax_error(\"(secure mode) php tags not permitted\", E_USER_WARNING, __FILE__, __LINE__);\n" + 
-               "                    return;\n" + 
-               "                }\n" + 
-               "                list (,$php_block) = each($this->_php_blocks);\n" + 
-               "                $this->_current_line_no += substr_count($php_block, \"\\n\");\n" + 
-               "                return \'<?php \'.$php_block.\' ?>\';\n" + 
-               "\n" + 
-               "            case \'insert\':\n" + 
-               "                return $this->_compile_insert_tag($tag_args);\n" + 
-               "\n" + 
-               "            default:\n" + 
-               "                if ($this->_compile_compiler_tag($tag_command, $tag_args, $output)) {\n" + 
-               "                    return $output;\n" + 
-               "                } else if ($this->_compile_block_tag($tag_command, $tag_args, $tag_modifier, $output)) {\n" + 
-               "                    return $output;\n" + 
-               "                } else {\n" + 
-               "                    return $this->_compile_custom_tag($tag_command, $tag_args, $tag_modifier);\n" + 
-               "                }\n" + 
-               "        }\n" + 
-               "    }\n" + 
-               "\n" + 
-               "\n" + 
-               "       /**\n" + 
-               "        * compile the custom compiler tag\n" + 
-               "        *\n" + 
-               "        * @access public\n" + 
-               "        * @param  $tag_command\n" + 
-               "        * @param  $tag_args\n" + 
-               "        * @param  $output\n" + 
-               "        */\n" + 
-               "    function _compile_compiler_tag($tag_command, $tag_args, &$output)\n" + 
-               "    {\n" + 
-               "        $found = false;\n" + 
-               "        $have_function = true;\n" + 
-               "\n" + 
-               "        /*\n" + 
-               "         * First we check if the compiler function has already been registered\n" + 
-               "         * or loaded from a plugin file.\n" + 
-               "         */\n" + 
-               "        if (isset($this->_plugins[\'compiler\'][$tag_command])) {\n" + 
-               "            $found = true;\n" + 
-               "            $plugin_func = $this->_plugins[\'compiler\'][$tag_command][0];\n" + 
-               "            if (!function_exists($plugin_func)) {\n" + 
-               "                $message = \"compiler function \'$tag_command\' is not implemented\";\n" + 
-               "                $have_function = false;\n" + 
-               "            }\n" + 
-               "        }\n" + 
-               "        /*\n" + 
-               "         * Otherwise we need to load plugin file and look for the function\n" + 
-               "         * inside it.\n" + 
-               "         */\n" + 
-               "        else if ($plugin_file = $this->_get_plugin_filepath(\'compiler\', $tag_command)) {\n" + 
-               "            $found = true;\n" + 
-               "\n" + 
-               "            include_once $plugin_file;\n" + 
-               "\n" + 
-               "            $plugin_func = \'smarty_compiler_\' . $tag_command;\n" + 
-               "            if (!function_exists($plugin_func)) {\n" + 
-               "                $message = \"plugin function $plugin_func() not found in $plugin_file\\n\";\n" + 
-               "                $have_function = false;\n" + 
-               "            } else {\n" + 
-               "                $this->_plugins[\'compiler\'][$tag_command] = array($plugin_func, null, null);\n" + 
-               "            }\n" + 
-               "        }\n" + 
-               "\n" + 
-               "        /*\n" + 
-               "         * True return value means that we either found a plugin or a\n" + 
-               "         * dynamically registered function. False means that we didn\'t and the\n" + 
-               "         * compiler should now emit code to load custom function plugin for this\n" + 
-               "         * tag.\n" + 
-               "         */\n" + 
-               "        if ($found) {\n" + 
-               "            if ($have_function) {\n" + 
-               "                $output = \'<?php \' . $plugin_func($tag_args, $this) . \' ?>\';\n" + 
-               "            } else {\n" + 
-               "                $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);\n" + 
-               "            }\n" + 
-               "            return true;\n" + 
-               "        } else {\n" + 
-               "            return false;\n" + 
-               "        }\n" + 
-               "    }\n" + 
-               "\n" + 
-               "\n" + 
-               "       /**\n" + 
-               "        * compile block function tag\n" + 
-               "        *\n" + 
-               "        * @access public\n" + 
-               "        * @param  $tag_command\n" + 
-               "        * @param  $tag_args\n" + 
-               "        * @param  $tag_modifier\n" + 
-               "        * @param  $output\n" + 
-               "        */\n" + 
-               "    function _compile_block_tag($tag_command, $tag_args, $tag_modifier, &$output)\n" + 
-               "    {\n" + 
-               "        if ($tag_command{0} == \'/\') {\n" + 
-               "            $start_tag = false;\n" + 
-               "            $tag_command = substr($tag_command, 1);\n" + 
-               "        } else\n" + 
-               "            $start_tag = true;\n" + 
-               "\n" + 
-               "        $found = false;\n" + 
-               "        $have_function = true;\n" + 
-               "\n" + 
-               "        /*\n" + 
-               "         * First we check if the block function has already been registered\n" + 
-               "         * or loaded from a plugin file.\n" + 
-               "         */\n" + 
-               "        if (isset($this->_plugins[\'block\'][$tag_command])) {\n" + 
-               "            $found = true;\n" + 
-               "            $plugin_func = $this->_plugins[\'block\'][$tag_command][0];\n" + 
-               "            if (!function_exists($plugin_func)) {\n" + 
-               "                $message = \"block function \'$tag_command\' is not implemented\";\n" + 
-               "                $have_function = false;\n" + 
-               "            }\n" + 
-               "        }\n" + 
-               "        /*\n" + 
-               "         * Otherwise we need to load plugin file and look for the function\n" + 
-               "         * inside it.\n" + 
-               "         */\n" + 
-               "        else if ($plugin_file = $this->_get_plugin_filepath(\'block\', $tag_command)) {\n" + 
-               "            $found = true;\n" + 
-               "\n" + 
-               "            include_once $plugin_file;\n" + 
-               "\n" + 
-               "            $plugin_func = \'smarty_block_\' . $tag_command;\n" + 
-               "            if (!function_exists($plugin_func)) {\n" + 
-               "                $message = \"plugin function $plugin_func() not found in $plugin_file\\n\";\n" + 
-               "                $have_function = false;\n" + 
-               "            } else {\n" + 
-               "                $this->_plugins[\'block\'][$tag_command] = array($plugin_func, null, null);\n" + 
-               "            }\n" + 
-               "        }\n" + 
-               "\n" + 
-               "        if (!$found) {\n" + 
-               "            return false;\n" + 
-               "        } else if (!$have_function) {\n" + 
-               "            $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);\n" + 
-               "            return true;\n" + 
-               "        }\n" + 
-               "\n" + 
-               "        /*\n" + 
-               "         * Even though we\'ve located the plugin function, compilation\n" + 
-               "         * happens only once, so the plugin will still need to be loaded\n" + 
-               "         * at runtime for future requests.\n" + 
-               "         */\n" + 
-               "        $this->_add_plugin(\'block\', $tag_command);\n" + 
-               "\n" + 
-               "        if ($start_tag) {\n" + 
-               "            $arg_list = array();\n" + 
-               "            $attrs = $this->_parse_attrs($tag_args);\n" + 
-               "            foreach ($attrs as $arg_name => $arg_value) {\n" + 
-               "                if (is_bool($arg_value))\n" + 
-               "                    $arg_value = $arg_value ? \'true\' : \'false\';\n" + 
-               "                $arg_list[] = \"\'$arg_name\' => $arg_value\";\n" + 
-               "            }\n" + 
-               "\n" + 
-               "            $output = \"<?php \\$this->_tag_stack[] = array(\'$tag_command\', array(\".implode(\',\', (array)$arg_list).\")); \\$this->_plugins[\'block\'][\'$tag_command\'][0](array(\".implode(\',\', (array)$arg_list).\"), null, \\$this); ob_start(); ?>\";\n" + 
-               "        } else {\n" + 
-               "            $output = \"<?php \\$this->_block_content = ob_get_contents(); ob_end_clean(); \";\n" + 
-               "                       $out_tag_text = \"\\$this->_plugins[\'block\'][\'$tag_command\'][0](\\$this->_tag_stack[count(\\$this->_tag_stack)-1][1], \\$this->_block_content, \\$this)\";\n" + 
-               "                       if($tag_modifier != \'\') {\n" + 
-               "                               $this->_parse_modifiers($out_tag_text, $tag_modifier);\n" + 
-               "                       }\n" + 
-               "                       $output .= \'echo \' . $out_tag_text . \';\';\n" + 
-               "                       $output .= \" array_pop(\\$this->_tag_stack); ?>\";\n" + 
-               "        }\n" + 
-               "\n" + 
-               "        return true;\n" + 
-               "    }\n" + 
-               "\n" + 
-               "\n" + 
-               "       /**\n" + 
-               "        * compile custom function tag\n" + 
-               "        *\n" + 
-               "        * @access public\n" + 
-               "        * @param  $tag_command\n" + 
-               "        * @param  $tag_args\n" + 
-               "        * @param  $tag_modifier\n" + 
-               "        */\n" + 
-               "    function _compile_custom_tag($tag_command, $tag_args, $tag_modifier)\n" + 
-               "    {\n" + 
-               "        $this->_add_plugin(\'function\', $tag_command);\n" + 
-               "\n" + 
-               "        $arg_list = array();\n" + 
-               "        $attrs = $this->_parse_attrs($tag_args);\n" + 
-               "        foreach ($attrs as $arg_name => $arg_value) {\n" + 
-               "            if (is_bool($arg_value))\n" + 
-               "                $arg_value = $arg_value ? \'true\' : \'false\';\n" + 
-               "            $arg_list[] = \"\'$arg_name\' => $arg_value\";\n" + 
-               "        }\n" + 
-               "               \n" + 
-               "               $return = \"\\$this->_plugins[\'function\'][\'$tag_command\'][0](array(\".implode(\',\', (array)$arg_list).\"), \\$this)\";\n" + 
-               "               \n" + 
-               "               if($tag_modifier != \'\') {\n" + 
-               "                       $this->_parse_modifiers($return, $tag_modifier);\n" + 
-               "               }\n" + 
-               "               \n" + 
-               "        return \'<?php echo \' . $return . \" ; ?>\\n\";\n" + 
-               "    }\n" + 
-               "\n" + 
-               "       /**\n" + 
-               "        * compile a registered object tag\n" + 
-               "        *\n" + 
-               "        * @access public\n" + 
-               "        * @param  $tag_command\n" + 
-               "        * @param  $attrs\n" + 
-               "        * @param  $tag_modifier\n" + 
-               "        */\n" + 
-               "    function _compile_registered_object_tag($tag_command, $attrs, $tag_modifier)\n" + 
-               "    {\n" + 
-               "               list($object, $obj_comp) = explode(\'->\', $tag_command);\n" + 
-               "\n" + 
-               "        $arg_list = array();\n" + 
-               "               if(count($attrs)) {\n" + 
-               "                       $_assign_var = false;\n" + 
-               "               foreach ($attrs as $arg_name => $arg_value) {\n" + 
-               "                               if($arg_name == \'assign\') {\n" + 
-               "                                       $_assign_var = $arg_value;\n" + 
-               "                                       unset($attrs[\'assign\']);\n" + 
-               "                                       continue;\n" + 
-               "                               }\n" + 
-               "               if (is_bool($arg_value))\n" + 
-               "                       $arg_value = $arg_value ? \'true\' : \'false\';\n" + 
-               "               $arg_list[] = \"\'$arg_name\' => $arg_value\";\n" + 
-               "               }\n" + 
-               "               }\n" + 
-               "                               \n" + 
-               "               if(!is_object($this->_reg_objects[$object][0])) {\n" + 
-               "                       $this->_trigger_fatal_error(\"registered \'$object\' is not an object\");\n" + 
-               "               } elseif(!empty($this->_reg_objects[$object][1]) && !in_array($obj_comp, $this->_reg_objects[$object][1])) {\n" + 
-               "                       $this->_trigger_fatal_error(\"\'$obj_comp\' is not a registered component of object \'$object\'\");\n" + 
-               "               } elseif(method_exists($this->_reg_objects[$object][0], $obj_comp)) {\n" + 
-               "                       // method\n" + 
-               "                       if($this->_reg_objects[$object][2]) {\n" + 
-               "                               // smarty object argument format\n" + 
-               "                               $return = \"\\$this->_reg_objects[\'$object\'][0]->$obj_comp(array(\".implode(\',\', (array)$arg_list).\"), \\$this)\";\n" + 
-               "                       } else {\n" + 
-               "                               // traditional argument format\n" + 
-               "                               $return = \"\\$this->_reg_objects[\'$object\'][0]->$obj_comp(\".implode(\',\', array_values($attrs)).\")\";\n" + 
-               "                       }\n" + 
-               "               } else {\n" + 
-               "                       // property\n" + 
-               "                       $return = \"\\$this->_reg_objects[\'$object\'][0]->$obj_comp\";\n" + 
-               "               }\n" + 
-               "               \n" + 
-               "               if($tag_modifier != \'\') {\n" + 
-               "                       $this->_parse_modifiers($return, $tag_modifier);\n" + 
-               "               }\n" + 
-               "               \n" + 
-               "               if($_assign_var) {\n" + 
-               "                       return \"<?php \\$this->assign(\'\" . $this->_dequote($_assign_var) .\"\',  $return); ?>\\n\";\n" + 
-               "               } else {\n" + 
-               "               return \'<?php echo \' . $return . \"; ?>\\n\";\n" + 
-               "               }\n" + 
-               "    }\n" + 
-               "       \n" + 
-               "       \n" + 
-               "\n" + 
-               "       /**\n" + 
-               "        * Compile {insert ...} tag\n" + 
-               "        *\n" + 
-               "        * @access public\n" + 
-               "        * @param  $tag_args\n" + 
-               "        */\n" + 
-               "    function _compile_insert_tag($tag_args)\n" + 
-               "    {\n" + 
-               "        $attrs = $this->_parse_attrs($tag_args);\n" + 
-               "        $name = $this->_dequote($attrs[\'name\']);\n" + 
-               "\n" + 
-               "        if (empty($name)) {\n" + 
-               "            $this->_syntax_error(\"missing insert name\", E_USER_ERROR, __FILE__, __LINE__);\n" + 
-               "        }\n" + 
-               "\n" + 
-               "        if (!empty($attrs[\'script\'])) {\n" + 
-               "            $delayed_loading = true;\n" + 
-               "        } else {\n" + 
-               "            $delayed_loading = false;                  \n" + 
-               "               }\n" + 
-               "\n" + 
-               "        foreach ($attrs as $arg_name => $arg_value) {\n" + 
-               "            if (is_bool($arg_value))\n" + 
-               "                $arg_value = $arg_value ? \'true\' : \'false\';\n" + 
-               "            $arg_list[] = \"\'$arg_name\' => $arg_value\";\n" + 
-               "        }\n" + 
-               "\n" + 
-               "        $this->_add_plugin(\'insert\', $name, $delayed_loading);\n" + 
-               "\n" + 
-               "        return \"<?php echo \\$this->_run_insert_handler(array(\".implode(\', \', (array)$arg_list).\")); ?>\\n\";\n" + 
-               "    }\n" + 
-               "\n" + 
-               "\n" + 
-               "       /**\n" + 
-               "        * Compile {config_load ...} tag\n" + 
-               "        *\n" + 
-               "        * @access public\n" + 
-               "        * @param  $tag_args\n" + 
-               "        */\n" + 
-               "    function _compile_config_load_tag($tag_args)\n" + 
-               "    {\n" + 
-               "        $attrs = $this->_parse_attrs($tag_args);\n" + 
-               "\n" + 
-               "        if (empty($attrs[\'file\'])) {\n" + 
-               "            $this->_syntax_error(\"missing \'file\' attribute in config_load tag\", E_USER_ERROR, __FILE__, __LINE__);\n" + 
-               "        }\n" + 
-               "\n" + 
-               "        if (empty($attrs[\'section\'])) {\n" + 
-               "            $attrs[\'section\'] = \'null\';\n" + 
-               "        }\n" + 
-               "\n" + 
-               "        if (isset($attrs[\'scope\'])) {\n" + 
-               "                       $scope = @$this->_dequote($attrs[\'scope\']);\r\n" + 
-               "            if ($scope != \'local\' &&\r\n" + 
-               "                $scope != \'parent\' &&\r\n" + 
-               "                $scope != \'global\') {\r\n" + 
-               "                $this->_syntax_error(\"invalid \'scope\' attribute value\", E_USER_ERROR, __FILE__, __LINE__);\r\n" + 
-               "            }\r\n" + 
-               "        } else {\r\n" + 
-               "            if (isset($attrs[\'global\']) && $attrs[\'global\'])\r\n" + 
-               "                $scope = \'parent\';\r\n" + 
-               "            else\r\n" + 
-               "                $scope = \'local\';\r\n" + 
-               "        }\r\n" + 
-               "\r\n" + 
-               "        return \'<?php $this->config_load(\' . $attrs[\'file\'] . \', \' . $attrs[\'section\'] . \", \'$scope\'); ?>\";\r\n" + 
-               "    }\r\n" + 
-               "\r\n" + 
-               "\r\n" + 
-               "       /**\r\n" + 
-               "        * Compile {include ...} tag\r\n" + 
-               "        *\r\n" + 
-               "        * @access public\r\n" + 
-               "        * $param  $tag_args\r\n" + 
-               "        */\r\n" + 
-               "    function _compile_include_tag($tag_args)\r\n" + 
-               "    {\r\n" + 
-               "        $attrs = $this->_parse_attrs($tag_args);\r\n" + 
-               "        $arg_list = array();\r\n" + 
-               "\r\n" + 
-               "        if (empty($attrs[\'file\'])) {\r\n" + 
-               "            $this->_syntax_error(\"missing \'file\' attribute in include tag\", E_USER_ERROR, __FILE__, __LINE__);\r\n" + 
-               "        }\r\n" + 
-               "\r\n" + 
-               "        foreach ($attrs as $arg_name => $arg_value) {\r\n" + 
-               "            if ($arg_name == \'file\') {\r\n" + 
-               "                $include_file = $arg_value;\r\n" + 
-               "                continue;\r\n" + 
-               "            } else if ($arg_name == \'assign\') {\r\n" + 
-               "                $assign_var = $arg_value;\r\n" + 
-               "                continue;\r\n" + 
-               "            }\r\n" + 
-               "            if (is_bool($arg_value))\r\n" + 
-               "                $arg_value = $arg_value ? \'true\' : \'false\';\r\n" + 
-               "            $arg_list[] = \"\'$arg_name\' => $arg_value\";\r\n" + 
-               "        }\r\n" + 
-               "\r\n" + 
-               "        $output = \'<?php \';\r\n" + 
-               "\r\n" + 
-               "        if (isset($assign_var)) {\r\n" + 
-               "                       $output .= \"ob_start();\\n\";\r\n" + 
-               "        }\r\n" + 
-               "\r\n" + 
-               "        $output .=  \r\n" + 
-               "            \"\\$_smarty_tpl_vars = \\$this->_tpl_vars;\\n\" .\r\n" + 
-               "            \"\\$this->_smarty_include(\".$include_file.\", array(\".implode(\',\', (array)$arg_list).\"));\\n\" .\r\n" + 
-               "            \"\\$this->_tpl_vars = \\$_smarty_tpl_vars;\\n\" .\r\n" + 
-               "            \"unset(\\$_smarty_tpl_vars);\\n\";\r\n" + 
-               "\r\n" + 
-               "        if (isset($assign_var)) {\r\n" + 
-               "                       $output .= \"\\$this->assign(\" . $assign_var . \", ob_get_contents()); ob_end_clean();\\n\";\r\n" + 
-               "        }\r\n" + 
-               "\r\n" + 
-               "        $output .= \' ?>\';\r\n" + 
-               "\r\n" + 
-               "               return $output;\r\n" + 
-               "\r\n" + 
-               "    }\r\n" + 
-               "\r\n" + 
-               "       /**\r\n" + 
-               "        * Compile {include ...} tag\r\n" + 
-               "        *\r\n" + 
-               "        * @access public\r\n" + 
-               "        * @param $tag_args\r\n" + 
-               "        */\r\n" + 
-               "    function _compile_include_php_tag($tag_args)\r\n" + 
-               "    {\r\n" + 
-               "        $attrs = $this->_parse_attrs($tag_args);\r\n" + 
-               "\r\n" + 
-               "        if (empty($attrs[\'file\'])) {\r\n" + 
-               "            $this->_syntax_error(\"missing \'file\' attribute in include_php tag\", E_USER_ERROR, __FILE__, __LINE__);\r\n" + 
-               "        }\r\n" + 
-               "\r\n" + 
-               "        $assign_var = $this->_dequote($attrs[\'assign\']);\r\n" + 
-               "\r\n" + 
-               "               $once_var = ( $attrs[\'once\'] === false ) ? \'false\' : \'true\';\r\n" + 
-               "\r\n" + 
-               "       foreach($attrs as $arg_name => $arg_value) {\r\n" + 
-               "               if($arg_name != \'file\' AND $arg_name != \'once\' AND $arg_name != \'assign\') {\r\n" + 
-               "               if(is_bool($arg_value))\r\n" + 
-               "                       $arg_value = $arg_value ? \'true\' : \'false\';\r\n" + 
-               "               $arg_list[] = \"\'$arg_name\' => $arg_value\";\r\n" + 
-               "               }\r\n" + 
-               "       }\r\n" + 
-               "\r\n" + 
-               "       $output =\r\n" + 
-               "               \"<?php \\$this->_smarty_include_php($attrs[file], \'$assign_var\', $once_var, \" .\r\n" + 
-               "               \"array(\".implode(\',\', (array)$arg_list).\")); ?>\";\r\n" + 
-               "                               \r\n" + 
-               "               return $output;\r\n" + 
-               "    }\r\n" + 
-               "       \r\n" + 
-               "\r\n" + 
-               "       /**\r\n" + 
-               "        * Compile {section ...} tag\r\n" + 
-               "        *\r\n" + 
-               "        * @access public\r\n" + 
-               "        * @param  $tag_args\r\n" + 
-               "        */\r\n" + 
-               "    function _compile_section_start($tag_args)\r\n" + 
-               "    {\r\n" + 
-               "        $attrs = $this->_parse_attrs($tag_args);\r\n" + 
-               "        $arg_list = array();\r\n" + 
-               "\r\n" + 
-               "        $output = \'<?php \';\r\n" + 
-               "        $section_name = $attrs[\'name\']; \r\n" + 
-               "        if (empty($section_name)) {\r\n" + 
-               "            $this->_syntax_error(\"missing section name\", E_USER_ERROR, __FILE__, __LINE__);\r\n" + 
-               "        }\r\n" + 
-               "\r\n" + 
-               "        $output .= \"if (isset(\\$this->_sections[$section_name])) unset(\\$this->_sections[$section_name]);\\n\";\r\n" + 
-               "        $section_props = \"\\$this->_sections[$section_name]\";\r\n" + 
-               "\r\n" + 
-               "        foreach ($attrs as $attr_name => $attr_value) {\r\n" + 
-               "            switch ($attr_name) {\r\n" + 
-               "                case \'loop\':\r\n" + 
-               "                    $output .= \"{$section_props}[\'loop\'] = is_array($attr_value) ? count($attr_value) : max(0, (int)$attr_value);\\n\";\r\n" + 
-               "                    break;\r\n" + 
-               "\r\n" + 
-               "                case \'show\':\r\n" + 
-               "                    if (is_bool($attr_value))\r\n" + 
-               "                        $show_attr_value = $attr_value ? \'true\' : \'false\';\r\n" + 
-               "                    else\r\n" + 
-               "                        $show_attr_value = \"(bool)$attr_value\";\r\n" + 
-               "                    $output .= \"{$section_props}[\'show\'] = $show_attr_value;\\n\";\r\n" + 
-               "                    break;\r\n" + 
-               "\r\n" + 
-               "                case \'name\':\r\n" + 
-               "                    $output .= \"{$section_props}[\'$attr_name\'] = $attr_value;\\n\";\r\n" + 
-               "                    break;\r\n" + 
-               "\r\n" + 
-               "                case \'max\':\r\n" + 
-               "                case \'start\':\r\n" + 
-               "                    $output .= \"{$section_props}[\'$attr_name\'] = (int)$attr_value;\\n\";\r\n" + 
-               "                    break;\r\n" + 
-               "\r\n" + 
-               "                case \'step\':\r\n" + 
-               "                    $output .= \"{$section_props}[\'$attr_name\'] = ((int)$attr_value) == 0 ? 1 : (int)$attr_value;\\n\";\r\n" + 
-               "                    break;\r\n" + 
-               "\r\n" + 
-               "                default:\r\n" + 
-               "                    $this->_syntax_error(\"unknown section attribute - \'$attr_name\'\", E_USER_ERROR, __FILE__, __LINE__);\r\n" + 
-               "                    break;\r\n" + 
-               "            }\r\n" + 
-               "        }\r\n" + 
-               "\r\n" + 
-               "        if (!isset($attrs[\'show\']))\r\n" + 
-               "            $output .= \"{$section_props}[\'show\'] = true;\\n\";\r\n" + 
-               "\r\n" + 
-               "        if (!isset($attrs[\'loop\']))\r\n" + 
-               "            $output .= \"{$section_props}[\'loop\'] = 1;\\n\";\r\n" + 
-               "\r\n" + 
-               "        if (!isset($attrs[\'max\']))\r\n" + 
-               "            $output .= \"{$section_props}[\'max\'] = {$section_props}[\'loop\'];\\n\";\r\n" + 
-               "        else\r\n" + 
-               "            $output .= \"if ({$section_props}[\'max\'] < 0)\\n\" .\r\n" + 
-               "                       \"    {$section_props}[\'max\'] = {$section_props}[\'loop\'];\\n\";\r\n" + 
-               "\r\n" + 
-               "        if (!isset($attrs[\'step\']))\r\n" + 
-               "            $output .= \"{$section_props}[\'step\'] = 1;\\n\";\r\n" + 
-               "\r\n" + 
-               "        if (!isset($attrs[\'start\']))\r\n" + 
-               "            $output .= \"{$section_props}[\'start\'] = {$section_props}[\'step\'] > 0 ? 0 : {$section_props}[\'loop\']-1;\\n\";\r\n" + 
-               "        else {\r\n" + 
-               "            $output .= \"if ({$section_props}[\'start\'] < 0)\\n\" .\r\n" + 
-               "                       \"    {$section_props}[\'start\'] = max({$section_props}[\'step\'] > 0 ? 0 : -1, {$section_props}[\'loop\'] + {$section_props}[\'start\']);\\n\" .\r\n" + 
-               "                       \"else\\n\" .\r\n" + 
-               "                       \"    {$section_props}[\'start\'] = min({$section_props}[\'start\'], {$section_props}[\'step\'] > 0 ? {$section_props}[\'loop\'] : {$section_props}[\'loop\']-1);\\n\";\r\n" + 
-               "        }\r\n" + 
-               "\r\n" + 
-               "        $output .= \"if ({$section_props}[\'show\']) {\\n\";\r\n" + 
-               "        if (!isset($attrs[\'start\']) && !isset($attrs[\'step\']) && !isset($attrs[\'max\'])) {\r\n" + 
-               "            $output .= \"    {$section_props}[\'total\'] = {$section_props}[\'loop\'];\\n\";\r\n" + 
-               "        } else {\r\n" + 
-               "            $output .= \"    {$section_props}[\'total\'] = min(ceil(({$section_props}[\'step\'] > 0 ? {$section_props}[\'loop\'] - {$section_props}[\'start\'] : {$section_props}[\'start\']+1)/abs({$section_props}[\'step\'])), {$section_props}[\'max\']);\\n\";\r\n" + 
-               "        }\r\n" + 
-               "        $output .= \"    if ({$section_props}[\'total\'] == 0)\\n\" .\r\n" + 
-               "                   \"        {$section_props}[\'show\'] = false;\\n\" .\r\n" + 
-               "                   \"} else\\n\" .\r\n" + 
-               "                   \"    {$section_props}[\'total\'] = 0;\\n\";\r\n" + 
-               "\r\n" + 
-               "        $output .= \"if ({$section_props}[\'show\']):\\n\";\r\n" + 
-               "        $output .= \"\r\n" + 
-               "            for ({$section_props}[\'index\'] = {$section_props}[\'start\'], {$section_props}[\'iteration\'] = 1;\r\n" + 
-               "                 {$section_props}[\'iteration\'] <= {$section_props}[\'total\'];\r\n" + 
-               "                 {$section_props}[\'index\'] += {$section_props}[\'step\'], {$section_props}[\'iteration\']++):\\n\";\r\n" + 
-               "        $output .= \"{$section_props}[\'rownum\'] = {$section_props}[\'iteration\'];\\n\";\r\n" + 
-               "        $output .= \"{$section_props}[\'index_prev\'] = {$section_props}[\'index\'] - {$section_props}[\'step\'];\\n\";\r\n" + 
-               "        $output .= \"{$section_props}[\'index_next\'] = {$section_props}[\'index\'] + {$section_props}[\'step\'];\\n\";\r\n" + 
-               "        $output .= \"{$section_props}[\'first\']      = ({$section_props}[\'iteration\'] == 1);\\n\";\r\n" + 
-               "        $output .= \"{$section_props}[\'last\']       = ({$section_props}[\'iteration\'] == {$section_props}[\'total\']);\\n\";\r\n" + 
-               "\r\n" + 
-               "        $output .= \"?>\";\r\n" + 
-               "\r\n" + 
-               "        return $output;\r\n" + 
-               "    }\r\n" + 
-               "\r\n" + 
-               "    \r\n" + 
-               "       /**\r\n" + 
-               "        * Compile {foreach ...} tag.\r\n" + 
-               "        *\r\n" + 
-               "        * @access public\r\n" + 
-               "        * @param  $tag_args\r\n" + 
-               "        */\r\n" + 
-               "    function _compile_foreach_start($tag_args)\r\n" + 
-               "    {\r\n" + 
-               "        $attrs = $this->_parse_attrs($tag_args);\r\n" + 
-               "        $arg_list = array();\r\n" + 
-               "\r\n" + 
-               "        if (empty($attrs[\'from\'])) {\r\n" + 
-               "            $this->_syntax_error(\"missing \'from\' attribute\", E_USER_ERROR, __FILE__, __LINE__);\r\n" + 
-               "        }\r\n" + 
-               "\r\n" + 
-               "        if (empty($attrs[\'item\'])) {\r\n" + 
-               "            $this->_syntax_error(\"missing \'item\' attribute\", E_USER_ERROR, __FILE__, __LINE__);\r\n" + 
-               "        }\r\n" + 
-               "\r\n" + 
-               "        $from = $attrs[\'from\'];\r\n" + 
-               "        $item = $this->_dequote($attrs[\'item\']);\r\n" + 
-               "        if (isset($attrs[\'name\']))\r\n" + 
-               "            $name = $attrs[\'name\'];\r\n" + 
-               "\r\n" + 
-               "        $output = \'<?php \';\r\n" + 
-               "        if (isset($name)) {\r\n" + 
-               "            $output .= \"if (isset(\\$this->_foreach[$name])) unset(\\$this->_foreach[$name]);\\n\";\r\n" + 
-               "            $foreach_props = \"\\$this->_foreach[$name]\";\r\n" + 
-               "        }\r\n" + 
-               "\r\n" + 
-               "        $key_part = \'\';\r\n" + 
-               "\r\n" + 
-               "        foreach ($attrs as $attr_name => $attr_value) {\r\n" + 
-               "            switch ($attr_name) {\r\n" + 
-               "                case \'key\':\r\n" + 
-               "                    $key  = $this->_dequote($attrs[\'key\']);\r\n" + 
-               "                    $key_part = \"\\$this->_tpl_vars[\'$key\'] => \";\r\n" + 
-               "                    break;\r\n" + 
-               "\r\n" + 
-               "                case \'name\':\r\n" + 
-               "                    $output .= \"{$foreach_props}[\'$attr_name\'] = $attr_value;\\n\";\r\n" + 
-               "                    break;\r\n" + 
-               "            }\r\n" + 
-               "        }\r\n" + 
-               "\r\n" + 
-               "        if (isset($name)) {\r\n" + 
-               "            $output .= \"{$foreach_props}[\'total\'] = count((array)$from);\\n\";\r\n" + 
-               "            $output .= \"{$foreach_props}[\'show\'] = {$foreach_props}[\'total\'] > 0;\\n\";\r\n" + 
-               "            $output .= \"if ({$foreach_props}[\'show\']):\\n\";\r\n" + 
-               "            $output .= \"{$foreach_props}[\'iteration\'] = 0;\\n\";\r\n" + 
-               "            $output .= \"    foreach ((array)$from as $key_part\\$this->_tpl_vars[\'$item\']):\\n\";\r\n" + 
-               "            $output .= \"        {$foreach_props}[\'iteration\']++;\\n\";\r\n" + 
-               "            $output .= \"        {$foreach_props}[\'first\'] = ({$foreach_props}[\'iteration\'] == 1);\\n\";\r\n" + 
-               "            $output .= \"        {$foreach_props}[\'last\']  = ({$foreach_props}[\'iteration\'] == {$foreach_props}[\'total\']);\\n\";\r\n" + 
-               "        } else {\r\n" + 
-               "            $output .= \"if (count((array)$from)):\\n\";\r\n" + 
-               "            $output .= \"    foreach ((array)$from as $key_part\\$this->_tpl_vars[\'$item\']):\\n\";\r\n" + 
-               "        }\r\n" + 
-               "        $output .= \'?>\';\r\n" + 
-               "\r\n" + 
-               "        return $output;\r\n" + 
-               "    }\r\n" + 
-               "\r\n" + 
-               "\r\n" + 
-               "       /**\r\n" + 
-               "        * Compile {capture} .. {/capture} tags\r\n" + 
-               "        *\r\n" + 
-               "        * @access public\r\n" + 
-               "        * @param  $start\r\n" + 
-               "        * @param  $tag_args\r\n" + 
-               "        */\r\n" + 
-               "    function _compile_capture_tag($start, $tag_args = \'\')\r\n" + 
-               "    {\r\n" + 
-               "        $attrs = $this->_parse_attrs($tag_args);\r\n" + 
-               "\r\n" + 
-               "        if ($start) {\r\n" + 
-               "            if (isset($attrs[\'name\']))\r\n" + 
-               "                $buffer = $attrs[\'name\'];\r\n" + 
-               "            else\r\n" + 
-               "                $buffer = \"\'default\'\";\r\n" + 
-               "\r\n" + 
-               "            $output = \"<?php ob_start(); ?>\";\r\n" + 
-               "            $this->_capture_stack[] = $buffer;\r\n" + 
-               "        } else {\r\n" + 
-               "            $buffer = array_pop($this->_capture_stack);\r\n" + 
-               "            $output = \"<?php \\$this->_smarty_vars[\'capture\'][$buffer] = ob_get_contents(); ob_end_clean(); ?>\";\r\n" + 
-               "        }\r\n" + 
-               "\r\n" + 
-               "        return $output;\r\n" + 
-               "    }\r\n" + 
-               "\r\n" + 
-               "       /**\r\n" + 
-               "        * Compile {if ...} tag\r\n" + 
-               "        *\r\n" + 
-               "        * @access public\r\n" + 
-               "        * @param  $tag_args\r\n" + 
-               "        * @param  $elseif\r\n" + 
-               "        */\r\n" + 
-               "    function _compile_if_tag($tag_args, $elseif = false)\r\n" + 
-               "    {\r\n" + 
-               "\r\n" + 
-               "        /* Tokenize args for \'if\' tag. */\r\n" + 
-               "        preg_match_all(\'/(?>\r\n" + 
-               "                               \' . $this->_obj_call_regexp . \'(?:\' . $this->_mod_regexp . \'*) | # valid object call\r\n" + 
-               "                               \' . $this->_var_regexp . \'(?:\' . $this->_mod_regexp . \'*)   | # public or quoted string\r\n" + 
-               "                               \\-?\\d+|!==|<=>|==|!=|<=|>=|\\&\\&|\\|\\||\\(|\\)|,|\\!|\\^|=|<|>|\\||\\%|\\+|\\-|\\/|\\*      | # valid non-word token\r\n" + 
-               "                               \\b\\w+\\b                                                                                                              | # valid word token\r\n" + 
-               "                               \\S+                                                           # anything else\r\n" + 
-               "                               )/x\', $tag_args, $match);\r\n" + 
-               "                               \r\n" + 
-               "        $tokens = $match[0];\r\n" + 
-               "               \r\n" + 
-               "               // make sure we have balanced parenthesis\r\n" + 
-               "               $token_count = array_count_values($tokens);\r\n" + 
-               "               if(isset($token_count[\'(\']) && $token_count[\'(\'] != $token_count[\')\']) {\r\n" + 
-               "                       $this->_syntax_error(\"unbalanced parenthesis in if statement\", E_USER_ERROR, __FILE__, __LINE__);\r\n" + 
-               "               }\r\n" + 
-               "                                                                                               \r\n" + 
-               "        $is_arg_stack = array();\r\n" + 
-               "\r\n" + 
-               "        for ($i = 0; $i < count($tokens); $i++) {\r\n" + 
-               "\r\n" + 
-               "            $token = &$tokens[$i];\r\n" + 
-               "                       \r\n" + 
-               "            switch (strtolower($token)) {\r\n" + 
-               "                case \'!\':\r\n" + 
-               "                case \'%\':\r\n" + 
-               "                case \'!==\':\r\n" + 
-               "                case \'==\':\r\n" + 
-               "                case \'>\':\r\n" + 
-               "                case \'<\':\r\n" + 
-               "                case \'!=\':\r\n" + 
-               "                case \'<=\':\r\n" + 
-               "                case \'>=\':\r\n" + 
-               "                case \'&&\':\r\n" + 
-               "                case \'||\':\r\n" + 
-               "                               case \'|\':\r\n" + 
-               "                               case \'^\':\r\n" + 
-               "                               case \'&\':\r\n" + 
-               "                               case \'~\':\r\n" + 
-               "                               case \')\':\r\n" + 
-               "                               case \',\':\r\n" + 
-               "                               case \'+\':\r\n" + 
-               "                               case \'-\':\r\n" + 
-               "                               case \'*\':\r\n" + 
-               "                               case \'/\':\r\n" + 
-               "                                       break;                                  \r\n" + 
-               "\r\n" + 
-               "                case \'eq\':\r\n" + 
-               "                    $token = \'==\';\r\n" + 
-               "                    break;\r\n" + 
-               "\r\n" + 
-               "                case \'ne\':\r\n" + 
-               "                case \'neq\':\r\n" + 
-               "                    $token = \'!=\';\r\n" + 
-               "                    break;\r\n" + 
-               "\r\n" + 
-               "                case \'lt\':\r\n" + 
-               "                    $token = \'<\';\r\n" + 
-               "                    break;\r\n" + 
-               "\r\n" + 
-               "                case \'le\':\r\n" + 
-               "                case \'lte\':\r\n" + 
-               "                    $token = \'<=\';\r\n" + 
-               "                    break;\r\n" + 
-               "\r\n" + 
-               "                case \'gt\':\r\n" + 
-               "                    $token = \'>\';\r\n" + 
-               "                    break;\r\n" + 
-               "\r\n" + 
-               "                case \'ge\':\r\n" + 
-               "                case \'gte\':\r\n" + 
-               "                    $token = \'>=\';\r\n" + 
-               "                    break;\r\n" + 
-               "\r\n" + 
-               "                case \'and\':\r\n" + 
-               "                    $token = \'&&\';\r\n" + 
-               "                    break;\r\n" + 
-               "\r\n" + 
-               "                case \'or\':\r\n" + 
-               "                    $token = \'||\';\r\n" + 
-               "                    break;\r\n" + 
-               "\r\n" + 
-               "                case \'not\':\r\n" + 
-               "                    $token = \'!\';\r\n" + 
-               "                    break;\r\n" + 
-               "\r\n" + 
-               "                case \'mod\':\r\n" + 
-               "                    $token = \'%\';\r\n" + 
-               "                    break;\r\n" + 
-               "\r\n" + 
-               "                case \'(\':\r\n" + 
-               "                    array_push($is_arg_stack, $i);\r\n" + 
-               "                    break;\r\n" + 
-               "                                       \r\n" + 
-               "                case \'is\':\r\n" + 
-               "                    /* If last token was a \')\', we operate on the parenthesized\r\n" + 
-               "                       expression. The start of the expression is on the stack.\r\n" + 
-               "                       Otherwise, we operate on the last encountered token. */\r\n" + 
-               "                    if ($tokens[$i-1] == \')\')\r\n" + 
-               "                        $is_arg_start = array_pop($is_arg_stack);\r\n" + 
-               "                    else\r\n" + 
-               "                        $is_arg_start = $i-1;\r\n" + 
-               "                    /* Construct the argument for \'is\' expression, so it knows\r\n" + 
-               "                       what to operate on. */\r\n" + 
-               "                    $is_arg = implode(\' \', array_slice($tokens, $is_arg_start, $i - $is_arg_start));\r\n" + 
-               "                                       \r\n" + 
-               "                    /* Pass all tokens from next one until the end to the\r\n" + 
-               "                       \'is\' expression parsing function. The function will\r\n" + 
-               "                       return modified tokens, where the first one is the result\r\n" + 
-               "                       of the \'is\' expression and the rest are the tokens it\r\n" + 
-               "                       didn\'t touch. */                                       \r\n" + 
-               "                    $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1));\r\n" + 
-               "                                                                               \r\n" + 
-               "                    /* Replace the old tokens with the new ones. */\r\n" + 
-               "                    array_splice($tokens, $is_arg_start, count($tokens), $new_tokens);\r\n" + 
-               "\r\n" + 
-               "                    /* Adjust argument start so that it won\'t change from the\r\n" + 
-               "                       current position for the next iteration. */\r\n" + 
-               "                    $i = $is_arg_start;\r\n" + 
-               "                    break;\r\n" + 
-               "                                       \r\n" + 
-               "                default:\r\n" + 
-               "                                       if(preg_match(\'!^\' . $this->_func_regexp . \'$!\', $token) ) {\r\n" + 
-               "                                                       // function call        \r\n" + 
-               "                               if($this->security &&\r\n" + 
-               "                                  !in_array($token, $this->security_settings[\'IF_FUNCS\'])) {\r\n" + 
-               "                                       $this->_syntax_error(\"(secure mode) \'$token\' not allowed in if statement\", E_USER_ERROR, __FILE__, __LINE__);\r\n" + 
-               "                                                       }                                                       \r\n" + 
-               "                                       } elseif(preg_match(\'!^\' . $this->_var_regexp . \'(?:\' . $this->_mod_regexp . \'*)$!\', $token)) {\r\n" + 
-               "                                               // variable\r\n" + 
-               "                                       $token = $this->_parse_var_props($token);\r\n" + 
-               "                                       } elseif(preg_match(\'!^\' . $this->_obj_call_regexp . \'(?:\' . $this->_mod_regexp . \'*)$!\', $token)) {\r\n" + 
-               "                                               // object\r\n" + 
-               "                                       $token = $this->_parse_var_props($token);\r\n" + 
-               "                                       } elseif(is_numeric($token)) {\r\n" + 
-               "                                               // number, skip it\r\n" + 
-               "                                       } else {\r\n" + 
-               "                               $this->_syntax_error(\"unidentified token \'$token\'\", E_USER_ERROR, __FILE__, __LINE__);\r\n" + 
-               "                                       }\r\n" + 
-               "                    break;\r\n" + 
-               "            }\r\n" + 
-               "        }\r\n" + 
-               "                               \r\n" + 
-               "        if ($elseif)\r\n" + 
-               "            return \'<?php elseif (\'.implode(\' \', $tokens).\'): ?>\';\r\n" + 
-               "        else\r\n" + 
-               "            return \'<?php if (\'.implode(\' \', $tokens).\'): ?>\';\r\n" + 
-               "    }\r\n" + 
-               "\r\n" + 
-               "\r\n" + 
-               "       /**\r\n" + 
-               "        * Parse is expression\r\n" + 
-               "        *\r\n" + 
-               "        * @access public\r\n" + 
-               "        * @param  $is_arg\r\n" + 
-               "        * @param  $tokens\r\n" + 
-               "        */\r\n" + 
-               "    function _parse_is_expr($is_arg, $tokens)\r\n" + 
-               "    {\r\n" + 
-               "        $expr_end = 0;\r\n" + 
-               "        $negate_expr = false;\r\n" + 
-               "\r\n" + 
-               "        if (($first_token = array_shift($tokens)) == \'not\') {\r\n" + 
-               "            $negate_expr = true;\r\n" + 
-               "            $expr_type = array_shift($tokens);\r\n" + 
-               "        } else\r\n" + 
-               "            $expr_type = $first_token;\r\n" + 
-               "\r\n" + 
-               "        switch ($expr_type) {\r\n" + 
-               "            case \'even\':\r\n" + 
-               "                if (@$tokens[$expr_end] == \'by\') {\r\n" + 
-               "                    $expr_end++;\r\n" + 
-               "                    $expr_arg = $tokens[$expr_end++];\r\n" + 
-               "                    $expr = \"!(($is_arg / $expr_arg) % \" . $this->_parse_var_props($expr_arg) . \")\";\r\n" + 
-               "                } else\r\n" + 
-               "                    $expr = \"!($is_arg % 2)\";\r\n" + 
-               "                break;\r\n" + 
-               "\r\n" + 
-               "            case \'odd\':\r\n" + 
-               "                if (@$tokens[$expr_end] == \'by\') {\r\n" + 
-               "                    $expr_end++;\r\n" + 
-               "                    $expr_arg = $tokens[$expr_end++];\r\n" + 
-               "                    $expr = \"(($is_arg / $expr_arg) % \". $this->_parse_var_props($expr_arg) . \")\";\r\n" + 
-               "                } else\r\n" + 
-               "                    $expr = \"($is_arg % 2)\";\r\n" + 
-               "                break;\r\n" + 
-               "\r\n" + 
-               "            case \'div\':\r\n" + 
-               "                if (@$tokens[$expr_end] == \'by\') {\r\n" + 
-               "                    $expr_end++;\r\n" + 
-               "                    $expr_arg = $tokens[$expr_end++];\r\n" + 
-               "                    $expr = \"!($is_arg % \" . $this->_parse_var_props($expr_arg) . \")\";\r\n" + 
-               "                } else {\r\n" + 
-               "                    $this->_syntax_error(\"expecting \'by\' after \'div\'\", E_USER_ERROR, __FILE__, __LINE__);\r\n" + 
-               "                }\r\n" + 
-               "                break;\r\n" + 
-               "\r\n" + 
-               "            default:\r\n" + 
-               "                $this->_syntax_error(\"unknown \'is\' expression - \'$expr_type\'\", E_USER_ERROR, __FILE__, __LINE__);\r\n" + 
-               "                break;\r\n" + 
-               "        }\r\n" + 
-               "\r\n" + 
-               "        if ($negate_expr) {\r\n" + 
-               "            $expr = \"!($expr)\";\r\n" + 
-               "        }\r\n" + 
-               "               \r\n" + 
-               "        array_splice($tokens, 0, $expr_end, $expr);            \r\n" + 
-               "               \r\n" + 
-               "        return $tokens;\r\n" + 
-               "    }\r\n" + 
-               "\r\n" + 
-               "\r\n" + 
-               "       /**\r\n" + 
-               "        * Parse attribute string\r\n" + 
-               "        *\r\n" + 
-               "        * @access public\r\n" + 
-               "        * @param  $tag_args\r\n" + 
-               "        * @param  $quote\r\n" + 
-               "        */\r\n" + 
-               "    function _parse_attrs($tag_args, $quote = true)\r\n" + 
-               "    {\r\n" + 
-               "                               \r\n" + 
-               "        /* Tokenize tag attributes. */\r\n" + 
-               "        preg_match_all(\'/(?:\' . $this->_obj_call_regexp . \'|\' . $this->_qstr_regexp . \' | (?>[^\"\\\'=\\s]+)\r\n" + 
-               "                         )+ |\r\n" + 
-               "                         [=]\r\n" + 
-               "                        /x\', $tag_args, $match);\r\n" + 
-               "        $tokens       = $match[0];             \r\n" + 
-               "                               \r\n" + 
-               "        $attrs = array();\r\n" + 
-               "        /* Parse state:\r\n" + 
-               "            0 - expecting attribute name\r\n" + 
-               "            1 - expecting \'=\'\r\n" + 
-               "            2 - expecting attribute value (not \'=\') */\r\n" + 
-               "        $state = 0;\r\n" + 
-               "                               \r\n" + 
-               "        foreach ($tokens as $token) {\r\n" + 
-               "            switch ($state) {\r\n" + 
-               "                case 0:\r\n" + 
-               "                    /* If the token is a valid identifier, we set attribute name\r\n" + 
-               "                       and go to state 1. */\r\n" + 
-               "                    if (preg_match(\'!^\\w+$!\', $token)) {\r\n" + 
-               "                        $attr_name = $token;\r\n" + 
-               "                        $state = 1;\r\n" + 
-               "                    } else\r\n" + 
-               "                        $this->_syntax_error(\"invalid attribute name - \'$token\'\", E_USER_ERROR, __FILE__, __LINE__);\r\n" + 
-               "                    break;\r\n" + 
-               "\r\n" + 
-               "                case 1:\r\n" + 
-               "                    /* If the token is \'=\', then we go to state 2. */\r\n" + 
-               "                    if ($token == \'=\') {\r\n" + 
-               "                        $state = 2;\r\n" + 
-               "                    } else\r\n" + 
-               "                        $this->_syntax_error(\"expecting \'=\' after attribute name \'$last_token\'\", E_USER_ERROR, __FILE__, __LINE__);\r\n" + 
-               "                    break;\r\n" + 
-               "\r\n" + 
-               "                case 2:\r\n" + 
-               "                    /* If token is not \'=\', we set the attribute value and go to\r\n" + 
-               "                       state 0. */\r\n" + 
-               "                    if ($token != \'=\') {\r\n" + 
-               "                        /* We booleanize the token if it\'s a non-quoted possible\r\n" + 
-               "                           boolean value. */\r\n" + 
-               "                        if (preg_match(\'!^(on|yes|true)$!\', $token))\r\n" + 
-               "                            $token = true;\r\n" + 
-               "                        else if (preg_match(\'!^(off|no|false)$!\', $token))\r\n" + 
-               "                            $token = false;\r\n" + 
-               "                        /* If the token is just a string,\r\n" + 
-               "                           we double-quote it. */\r\n" + 
-               "                        else if (preg_match(\'!^\\w+$!\', $token)) {\r\n" + 
-               "                            $token = \'\"\'.$token.\'\"\';\r\n" + 
-               "                                               }\r\n" + 
-               "\r\n" + 
-               "                        $attrs[$attr_name] = $token;\r\n" + 
-               "                        $state = 0;\r\n" + 
-               "                    } else\r\n" + 
-               "                        $this->_syntax_error(\"\'=\' cannot be an attribute value\", E_USER_ERROR, __FILE__, __LINE__);\r\n" + 
-               "                    break;\r\n" + 
-               "            }\r\n" + 
-               "                       $last_token = $token;\r\n" + 
-               "        }\r\n" + 
-               "\r\n" + 
-               "               if($state != 0) {\r\n" + 
-               "                       if($state == 1) {\r\n" + 
-               "                               $this->_syntax_error(\"expecting \'=\' after attribute name \'$last_token\'\", E_USER_ERROR, __FILE__, __LINE__);                               \r\n" + 
-               "                       } else {\r\n" + 
-               "                               $this->_syntax_error(\"missing attribute value\", E_USER_ERROR, __FILE__, __LINE__);                                                            \r\n" + 
-               "                       }\r\n" + 
-               "               }\r\n" + 
-               "               \r\n" + 
-               "        $this->_parse_vars_props($attrs);\r\n" + 
-               "\r\n" + 
-               "        return $attrs;\r\n" + 
-               "    }\r\n" + 
-               "\r\n" + 
-               "       /**\r\n" + 
-               "        * compile multiple variables and section properties tokens into\r\n" + 
-               "        * PHP code\r\n" + 
-               "        *\r\n" + 
-               "        * @access public\r\n" + 
-               "        * @param  $tokens\r\n" + 
-               "        */\r\n" + 
-               "    function _parse_vars_props(&$tokens)\r\n" + 
-               "    {\r\n" + 
-               "               foreach($tokens as $key => $val) {                      \r\n" + 
-               "               $tokens[$key] = $this->_parse_var_props($val);\r\n" + 
-               "               }\r\n" + 
-               "       }\r\n" + 
-               "               \r\n" + 
-               "       /**\r\n" + 
-               "        * compile single variable and section properties token into\r\n" + 
-               "        * PHP code\r\n" + 
-               "        *\r\n" + 
-               "        * @access public\r\n" + 
-               "        * @param  $val\r\n" + 
-               "        * @param  $tag_attrs\r\n" + 
-               "        */\r\n" + 
-               "    function _parse_var_props($val, $tag_attrs = null)\r\n" + 
-               "    {                                  \r\n" + 
-               "\r\n" + 
-               "               $val = trim($val);\r\n" + 
-               "\r\n" + 
-               "        if(preg_match(\'!^(\' . $this->_obj_call_regexp . \'|\' . $this->_dvar_regexp . \')(?:\' . $this->_mod_regexp . \'*)$!\', $val)) {\r\n" + 
-               "                               // $ variable or object\r\n" + 
-               "                return $this->_parse_var($val, $tag_attrs);\r\n" + 
-               "                       }                       \r\n" + 
-               "        elseif(preg_match(\'!^\' . $this->_db_qstr_regexp . \'(?:\' . $this->_mod_regexp . \'*)$!\', $val)) {\r\n" + 
-               "                               // double quoted text\r\n" + 
-               "                               preg_match(\'!^(\' . $this->_db_qstr_regexp . \')(\'. $this->_mod_regexp . \'*)$!\', $val, $match);\r\n" + 
-               "                $return = $this->_expand_quoted_text($match[1]);\r\n" + 
-               "                               if($match[2] != \'\') {\r\n" + 
-               "                                       $this->_parse_modifiers($return, $match[2]);\r\n" + 
-               "                               }\r\n" + 
-               "                               return $return;\r\n" + 
-               "                       }                       \r\n" + 
-               "        elseif(preg_match(\'!^\' . $this->_si_qstr_regexp . \'(?:\' . $this->_mod_regexp . \'*)$!\', $val)) {\r\n" + 
-               "                               // single quoted text\r\n" + 
-               "                               preg_match(\'!^(\' . $this->_si_qstr_regexp . \')(\'. $this->_mod_regexp . \'*)$!\', $val, $match);\r\n" + 
-               "                               if($match[2] != \'\') {\r\n" + 
-               "                                       $this->_parse_modifiers($match[1], $match[2]);\r\n" + 
-               "                       return $match[1];\r\n" + 
-               "                               }       \r\n" + 
-               "                       }                       \r\n" + 
-               "        elseif(preg_match(\'!^\' . $this->_cvar_regexp . \'(?:\' . $this->_mod_regexp . \'*)$!\', $val)) {\r\n" + 
-               "                               // config var\r\n" + 
-               "                return $this->_parse_conf_var($val);\r\n" + 
-               "                       }                       \r\n" + 
-               "        elseif(preg_match(\'!^\' . $this->_svar_regexp . \'(?:\' . $this->_mod_regexp . \'*)$!\', $val)) {\r\n" + 
-               "                               // section var\r\n" + 
-               "                return $this->_parse_section_prop($val);\r\n" + 
-               "                       }\r\n" + 
-               "               elseif(!in_array($val, $this->_permitted_tokens) && !is_numeric($val)) {\r\n" + 
-               "                       // literal string\r\n" + 
-               "                       return $this->_expand_quoted_text(\'\"\' . $val .\'\"\');\r\n" + 
-               "               }\r\n" + 
-               "               return $val;\r\n" + 
-               "    }\r\n" + 
-               "\r\n" + 
-               "       /**\r\n" + 
-               "        * expand quoted text with embedded variables\r\n" + 
-               "        *\r\n" + 
-               "        * @access public\r\n" + 
-               "        * @param  $var_expr\r\n" + 
-               "        */\r\n" + 
-               "    function _expand_quoted_text($var_expr)\r\n" + 
-               "    {\r\n" + 
-               "               // if contains unescaped $, expand it\r\n" + 
-               "               if(preg_match_all(\'|(?<!\\\\\\\\)\\$\' . $this->_dvar_guts_regexp . \'|\', $var_expr, $match)) {\r\n" + 
-               "                       rsort($match[0]);\r\n" + 
-               "                       reset($match[0]);\r\n" + 
-               "                       foreach($match[0] as $var) {\r\n" + 
-               "                $var_expr = str_replace ($var, \'\".\' . $this->_parse_var($var) . \'.\"\', $var_expr);\r\n" + 
-               "                       }\r\n" + 
-               "            return preg_replace(\'!\\.\"\"|\"\"\\.!\', \'\', $var_expr);\r\n" + 
-               "               } else {\r\n" + 
-               "                       return $var_expr;\r\n" + 
-               "               }\r\n" + 
-               "       }\r\n" + 
-               "       \r\n" + 
-               "       /**\r\n" + 
-               "        * parse variable expression into PHP code\r\n" + 
-               "        *\r\n" + 
-               "        * @access public\r\n" + 
-               "        * @param  $var_expr\r\n" + 
-               "        */\r\n" + 
-               "    function _parse_var($var_expr)\r\n" + 
-               "    {\r\n" + 
-               "                               \r\n" + 
-               "               preg_match(\'!(\' . $this->_obj_call_regexp . \'|\' . $this->_var_regexp . \')(\' . $this->_mod_regexp . \'*)$!\', $var_expr, $match);\r\n" + 
-               "                               \r\n" + 
-               "        $var_ref = substr($match[1],1);\r\n" + 
-               "        $modifiers = $match[2];\r\n" + 
-               "                                               \r\n" + 
-               "               if(!empty($this->default_modifiers) && !preg_match(\'!(^|\\|)smarty:nodefaults($|\\|)!\',$modifiers)) {\r\n" + 
-               "                       $_default_mod_string = implode(\'|\',(array)$this->default_modifiers);\r\n" + 
-               "                       $modifiers = empty($modifiers) ? $_default_mod_string : $_default_mod_string . \'|\' . $modifiers;\r\n" + 
-               "               }\r\n" + 
-               "\r\n" + 
-               "               // get [foo] and .foo and ->foo() pieces                        \r\n" + 
-               "        preg_match_all(\'!(?:^\\w+)|(?:\' . $this->_obj_ext_regexp . \')+(?:\' . $this->_obj_params_regexp . \')?|(?:\' . $this->_var_bracket_regexp . \')|\\.\\$?\\w+!\', $var_ref, $match);          \r\n" + 
-               "               \r\n" + 
-               "        $indexes = $match[0];\r\n" + 
-               "        $var_name = array_shift($indexes);\r\n" + 
-               "                               \r\n" + 
-               "        /* Handle $smarty.* variable references as a special case. */\r\n" + 
-               "        if ($var_name == \'smarty\') {\r\n" + 
-               "            /*\r\n" + 
-               "             * If the reference could be compiled, use the compiled output;\r\n" + 
-               "             * otherwise, fall back on the $smarty variable generated at\r\n" + 
-               "             * run-time.\r\n" + 
-               "             */\r\n" + 
-               "            if (($smarty_ref = $this->_compile_smarty_ref($indexes)) !== null) {\r\n" + 
-               "                $output = $smarty_ref;\r\n" + 
-               "            } else {\r\n" + 
-               "                $var_name = substr(array_shift($indexes), 1);\r\n" + 
-               "                $output = \"\\$this->_smarty_vars[\'$var_name\']\";\r\n" + 
-               "            }\r\n" + 
-               "        } else {\r\n" + 
-               "            $output = \"\\$this->_tpl_vars[\'$var_name\']\";\r\n" + 
-               "        }\r\n" + 
-               "\r\n" + 
-               "        foreach ($indexes as $index) {                 \r\n" + 
-               "            if ($index{0} == \'[\') {\r\n" + 
-               "                $index = substr($index, 1, -1);\r\n" + 
-               "                if (is_numeric($index)) {\r\n" + 
-               "                    $output .= \"[$index]\";\r\n" + 
-               "                } elseif ($index{0} == \'$\') {\r\n" + 
-               "                    $output .= \"[\\$this->_tpl_vars[\'\" . substr($index, 1) . \"\']]\";\r\n" + 
-               "                } else {\r\n" + 
-               "                    $parts = explode(\'.\', $index);\r\n" + 
-               "                    $section = $parts[0];\r\n" + 
-               "                    $section_prop = isset($parts[1]) ? $parts[1] : \'index\';\r\n" + 
-               "                    $output .= \"[\\$this->_sections[\'$section\'][\'$section_prop\']]\";\r\n" + 
-               "                }\r\n" + 
-               "            } else if ($index{0} == \'.\') {\r\n" + 
-               "                if ($index{1} == \'$\')\r\n" + 
-               "                    $output .= \"[\\$this->_tpl_vars[\'\" . substr($index, 2) . \"\']]\";\r\n" + 
-               "                else\r\n" + 
-               "                    $output .= \"[\'\" . substr($index, 1) . \"\']\";\r\n" + 
-               "            } else if (substr($index,0,2) == \'->\') {\r\n" + 
-               "                               if(substr($index,2,2) == \'__\') {\r\n" + 
-               "                                       $this->_syntax_error(\'call to internal object members is not allowed\', E_USER_ERROR, __FILE__, __LINE__);\r\n" + 
-               "                               } elseif($this->security && substr($index,2,1) == \'_\') {\r\n" + 
-               "                                       $this->_syntax_error(\'(secure) call to private object member is not allowed\', E_USER_ERROR, __FILE__, __LINE__);\r\n" + 
-               "                               } else {\r\n" + 
-               "                                       if(preg_match(\'!((?:\' . $this->_obj_ext_regexp . \')+)(\' . $this->_obj_params_regexp . \')?!\', $index, $match)) {\r\n" + 
-               "                                               if(!empty($match[2])) {\r\n" + 
-               "                                                       // parse object parameters\r\n" + 
-               "                                                       $index = str_replace($match[2], $this->_parse_parenth_args($match[2]), $index);\r\n" + 
-               "                                               }\r\n" + 
-               "                                               if(preg_match_all(\'!\' . $this->_dvar_regexp . \'!\', $match[1], $_dvar_match)) {\r\n" + 
-               "                                                       // parse embedded variables\r\n" + 
-               "                                                       $_match_replace = $match[1];\r\n" + 
-               "                                                       foreach($_dvar_match[0] as $_curr_var) {\r\n" + 
-               "                                                               $_match_replace = str_replace($_curr_var, \'{\' . $this->_parse_var($_curr_var) . \'}\', $_match_replace);\r\n" + 
-               "                                                       }\r\n" + 
-               "                                                       $index = str_replace($match[1], $_match_replace, $index);\r\n" + 
-               "                                               }\r\n" + 
-               "                                       }\r\n" + 
-               "                                       $output .= $index;\r\n" + 
-               "                               }\r\n" + 
-               "            } else {\r\n" + 
-               "                $output .= $index;\r\n" + 
-               "            }\r\n" + 
-               "        }\r\n" + 
-               "\r\n" + 
-               "               // look for variables imbedded in quoted strings, replace them\r\n" + 
-               "        if(preg_match(\'!\' . $this->_qstr_regexp . \'!\', $output, $match)) {\r\n" + 
-               "                       $output = str_replace($match[0], $this->_expand_quoted_text($match[0]), $output);\r\n" + 
-               "               }\r\n" + 
-               "               \r\n" + 
-               "        $this->_parse_modifiers($output, $modifiers);\r\n" + 
-               "\r\n" + 
-               "        return $output;\r\n" + 
-               "    }\r\n" + 
-               "\r\n" + 
-               "       /**\r\n" + 
-               "        * parse arguments in function call parenthesis\r\n" + 
-               "        *\r\n" + 
-               "        * @access public\r\n" + 
-               "        * @param  $parenth_args\r\n" + 
-               "        */\r\n" + 
-               "    function _parse_parenth_args($parenth_args)\r\n" + 
-               "    {\r\n" + 
-               "               preg_match_all(\'!\' . $this->_param_regexp . \'!\',$parenth_args, $match);\r\n" + 
-               "               $match = $match[0];\r\n" + 
-               "               rsort($match);\r\n" + 
-               "               reset($match);                                          \r\n" + 
-               "               $orig_vals = $match;\r\n" + 
-               "               $this->_parse_vars_props($match);\r\n" + 
-               "               return str_replace($orig_vals, $match, $parenth_args);\r\n" + 
-               "       }       \r\n" + 
-               "               \r\n" + 
-               "       /**\r\n" + 
-               "        * parse configuration variable expression into PHP code\r\n" + 
-               "        *\r\n" + 
-               "        * @access public\r\n" + 
-               "        * @param  $conf_var_expr\r\n" + 
-               "        */\r\n" + 
-               "    function _parse_conf_var($conf_var_expr)\r\n" + 
-               "    {\r\n" + 
-               "        $parts = explode(\'|\', $conf_var_expr, 2);\r\n" + 
-               "        $var_ref = $parts[0];\r\n" + 
-               "        $modifiers = isset($parts[1]) ? $parts[1] : \'\';\r\n" + 
-               "\r\n" + 
-               "        $var_name = substr($var_ref, 1, -1);\r\n" + 
-               "\r\n" + 
-               "        $output = \"\\$this->_config[0][\'vars\'][\'$var_name\']\";\r\n" + 
-               "\r\n" + 
-               "        $this->_parse_modifiers($output, $modifiers);\r\n" + 
-               "\r\n" + 
-               "        return $output;\r\n" + 
-               "    }\r\n" + 
-               "\r\n" + 
-               "\r\n" + 
-               "       /**\r\n" + 
-               "        * parse section property expression into PHP code\r\n" + 
-               "        *\r\n" + 
-               "        * @access public\r\n" + 
-               "        * @param  $section_prop_expr\r\n" + 
-               "        */\r\n" + 
-               "    function _parse_section_prop($section_prop_expr)\r\n" + 
-               "    {\r\n" + 
-               "        $parts = explode(\'|\', $section_prop_expr, 2);\r\n" + 
-               "        $var_ref = $parts[0];\r\n" + 
-               "        $modifiers = isset($parts[1]) ? $parts[1] : \'\';\r\n" + 
-               "\r\n" + 
-               "        preg_match(\'!%(\\w+)\\.(\\w+)%!\', $var_ref, $match);\r\n" + 
-               "        $section_name = $match[1];\r\n" + 
-               "        $prop_name = $match[2];\r\n" + 
-               "\r\n" + 
-               "        $output = \"\\$this->_sections[\'$section_name\'][\'$prop_name\']\";\r\n" + 
-               "\r\n" + 
-               "        $this->_parse_modifiers($output, $modifiers);\r\n" + 
-               "\r\n" + 
-               "        return $output;\r\n" + 
-               "    }\r\n" + 
-               "\r\n" + 
-               "\r\n" + 
-               "       /**\r\n" + 
-               "        * parse modifier chain into PHP code\r\n" + 
-               "        *\r\n" + 
-               "        * @access public\r\n" + 
-               "        * @param  $output\r\n" + 
-               "        * @param  $modifier_string\r\n" + 
-               "        */\r\n" + 
-               "    function _parse_modifiers(&$output, $modifier_string)\r\n" + 
-               "    {\r\n" + 
-               "        preg_match_all(\'!\\|(@?\\w+)((?>:(?:\'. $this->_qstr_regexp . \'|[^|]+))*)!\', \'|\' . $modifier_string, $match);\r\n" + 
-               "        list(, $modifiers, $modifier_arg_strings) = $match;\r\n" + 
-               "\r\n" + 
-               "        for ($i = 0, $for_max = count($modifiers); $i < $for_max; $i++) {\r\n" + 
-               "            $modifier_name = $modifiers[$i];\r\n" + 
-               "                       \r\n" + 
-               "                       if($modifier_name == \'smarty\') {\r\n" + 
-               "                               // skip smarty modifier\r\n" + 
-               "                               continue;\r\n" + 
-               "                       }\r\n" + 
-               "                       \r\n" + 
-               "            preg_match_all(\'!:(\' . $this->_qstr_regexp . \'|[^:]+)!\', $modifier_arg_strings[$i], $match);\r\n" + 
-               "            $modifier_args = $match[1];\r\n" + 
-               "\r\n" + 
-               "            if ($modifier_name{0} == \'@\') {\r\n" + 
-               "                $map_array = \'false\';\r\n" + 
-               "                $modifier_name = substr($modifier_name, 1);\r\n" + 
-               "            } else {\r\n" + 
-               "                $map_array = \'true\';\r\n" + 
-               "            }\r\n" + 
-               "                       \r\n" + 
-               "            $this->_add_plugin(\'modifier\', $modifier_name);\r\n" + 
-               "\r\n" + 
-               "            $this->_parse_vars_props($modifier_args);\r\n" + 
-               "\r\n" + 
-               "            if (count($modifier_args) > 0)\r\n" + 
-               "                $modifier_args = \', \'.implode(\', \', $modifier_args);\r\n" + 
-               "            else\r\n" + 
-               "                $modifier_args = \'\';\r\n" + 
-               "\r\n" + 
-               "            $output = \"\\$this->_run_mod_handler(\'$modifier_name\', $map_array, $output$modifier_args)\";\r\n" + 
-               "        }\r\n" + 
-               "    }\r\n" + 
-               "\r\n" + 
-               "\r\n" + 
-               "       /**\r\n" + 
-               "        * add plugin\r\n" + 
-               "        *\r\n" + 
-               "        * @access public\r\n" + 
-               "        * @param  $type\r\n" + 
-               "        * @param  $name\r\n" + 
-               "        * @param  $delayed_loading\r\n" + 
-               "        */\r\n" + 
-               "    function _add_plugin($type, $name, $delayed_loading = null)\r\n" + 
-               "    {\r\n" + 
-               "        if (!isset($this->_plugin_info[$type])) {\r\n" + 
-               "            $this->_plugin_info[$type] = array();\r\n" + 
-               "        }\r\n" + 
-               "        if (!isset($this->_plugin_info[$type][$name])) {\r\n" + 
-               "            $this->_plugin_info[$type][$name] = array($this->_current_file,\r\n" + 
-               "                                                      $this->_current_line_no,\r\n" + 
-               "                                                      $delayed_loading);\r\n" + 
-               "        }\r\n" + 
-               "    }\r\n" + 
-               "    \r\n" + 
-               "\r\n" + 
-               "       /**\r\n" + 
-               "        * Compiles references of type $smarty.foo\r\n" + 
-               "        *\r\n" + 
-               "        * @access public\r\n" + 
-               "        * @param  $indexes\r\n" + 
-               "        */\r\n" + 
-               "    function _compile_smarty_ref(&$indexes)\r\n" + 
-               "    {\r\n" + 
-               "        /* Extract the reference name. */\r\n" + 
-               "        $ref = substr($indexes[0], 1);\r\n" + 
-               "\r\n" + 
-               "        switch ($ref) {\r\n" + 
-               "            case \'now\':\r\n" + 
-               "                $compiled_ref = \'time()\';\r\n" + 
-               "                if (count($indexes) > 1) {\r\n" + 
-               "                    $this->_syntax_error(\'$smarty\' . implode(\'\', $indexes) .\' is an invalid reference\', E_USER_ERROR, __FILE__, __LINE__);\r\n" + 
-               "                }\r\n" + 
-               "                break;\r\n" + 
-               "\r\n" + 
-               "            case \'foreach\':\r\n" + 
-               "            case \'section\':\r\n" + 
-               "                if ($indexes[1]{0} != \'.\') {\r\n" + 
-               "                    $this->_syntax_error(\'$smarty\' . implode(\'\', array_slice($indexes, 0, 2)) . \' is an invalid reference\', E_USER_ERROR, __FILE__, __LINE__);\r\n" + 
-               "                }\r\n" + 
-               "                $name = substr($indexes[1], 1);\r\n" + 
-               "                array_shift($indexes);\r\n" + 
-               "                if ($ref == \'foreach\')\r\n" + 
-               "                    $compiled_ref = \"\\$this->_foreach[\'$name\']\";\r\n" + 
-               "                else\r\n" + 
-               "                    $compiled_ref = \"\\$this->_sections[\'$name\']\";\r\n" + 
-               "                break;\r\n" + 
-               "\r\n" + 
-               "            case \'get\':\r\n" + 
-               "                array_shift($indexes);\r\n" + 
-               "                $compiled_ref = \"\\$_GET\";\r\n" + 
-               "                if ($name = substr($indexes[0], 1))\r\n" + 
-               "                    $compiled_ref .= \"[\'$name\']\";\r\n" + 
-               "                break;\r\n" + 
-               "\r\n" + 
-               "            case \'post\':\r\n" + 
-               "                array_shift($indexes);\r\n" + 
-               "                $name = substr($indexes[0], 1);\r\n" + 
-               "                $compiled_ref = \"\\$_POST\";\r\n" + 
-               "                if ($name = substr($indexes[0], 1))\r\n" + 
-               "                    $compiled_ref .= \"[\'$name\']\";\r\n" + 
-               "                break;\r\n" + 
-               "\r\n" + 
-               "            case \'cookies\':\r\n" + 
-               "                array_shift($indexes);\r\n" + 
-               "                $name = substr($indexes[0], 1);\r\n" + 
-               "                $compiled_ref = \"\\$_COOKIE\";\r\n" + 
-               "                if ($name = substr($indexes[0], 1))\r\n" + 
-               "                    $compiled_ref .= \"[\'$name\']\";\r\n" + 
-               "                break;\r\n" + 
-               "\r\n" + 
-               "            case \'env\':\r\n" + 
-               "                array_shift($indexes);\r\n" + 
-               "                $compiled_ref = \"\\$_ENV\";\r\n" + 
-               "                if ($name = substr($indexes[0], 1))\r\n" + 
-               "                    $compiled_ref .= \"[\'$name\']\";\r\n" + 
-               "                break;\r\n" + 
-               "\r\n" + 
-               "            case \'server\':\r\n" + 
-               "                array_shift($indexes);\r\n" + 
-               "                $name = substr($indexes[0], 1);\r\n" + 
-               "                $compiled_ref = \"\\$_SERVER\";\r\n" + 
-               "                if ($name = substr($indexes[0], 1))\r\n" + 
-               "                    $compiled_ref .= \"[\'$name\']\";\r\n" + 
-               "                break;\r\n" + 
-               "\r\n" + 
-               "            case \'session\':\r\n" + 
-               "                array_shift($indexes);\r\n" + 
-               "                $name = substr($indexes[0], 1);\r\n" + 
-               "                $compiled_ref = \"\\$_SESSION\";\r\n" + 
-               "                if ($name = substr($indexes[0], 1))\r\n" + 
-               "                    $compiled_ref .= \"[\'$name\']\";\r\n" + 
-               "                break;\r\n" + 
-               "\r\n" + 
-               "            /*\r\n" + 
-               "             * These cases are handled either at run-time or elsewhere in the\r\n" + 
-               "             * compiler.\r\n" + 
-               "             */\r\n" + 
-               "            case \'request\':\r\n" + 
-               "                $this->_init_smarty_vars = true;\r\n" + 
-               "                return null;\r\n" + 
-               "\r\n" + 
-               "            case \'capture\':\r\n" + 
-               "                return null;\r\n" + 
-               "\r\n" + 
-               "            case \'template\':\r\n" + 
-               "                $compiled_ref = \"\'$this->_current_file\'\";\r\n" + 
-               "                if (count($indexes) > 1) {\r\n" + 
-               "                    $this->_syntax_error(\'$smarty\' . implode(\'\', $indexes) .\' is an invalid reference\', E_USER_ERROR, __FILE__, __LINE__);\r\n" + 
-               "                }\r\n" + 
-               "                break;\r\n" + 
-               "                               \r\n" + 
-               "                       case \'version\':\r\n" + 
-               "                               $compiled_ref = \"\'$this->_version\'\";\r\n" + 
-               "                               break;\r\n" + 
-               "\r\n" + 
-               "                       case \'const\':\r\n" + 
-               "                array_shift($indexes);\r\n" + 
-               "                               $compiled_ref = \'defined(\\\'\' . substr($indexes[0],1) . \'\\\') ? \' . substr($indexes[0],1) . \' : null\';\r\n" + 
-               "                break;\r\n" + 
-               "\r\n" + 
-               "            default:\r\n" + 
-               "                $this->_syntax_error(\'$smarty.\' . $ref . \' is an unknown reference\', E_USER_ERROR, __FILE__, __LINE__);\r\n" + 
-               "                break;\r\n" + 
-               "        }\r\n" + 
-               "\r\n" + 
-               "        array_shift($indexes);\r\n" + 
-               "        return $compiled_ref;\r\n" + 
-               "    }\r\n" + 
-               "\r\n" + 
-               "\r\n" + 
-               "       /**\r\n" + 
-               "        * load pre- and post-filters\r\n" + 
-               "        *\r\n" + 
-               "        * @access public\r\n" + 
-               "        */\r\n" + 
-               "    function _load_filters()\r\n" + 
-               "    {\r\n" + 
-               "        if (count($this->_plugins[\'prefilter\']) > 0) {\r\n" + 
-               "            foreach ($this->_plugins[\'prefilter\'] as $filter_name => $prefilter) {\r\n" + 
-               "                if ($prefilter === false) {\r\n" + 
-               "                    unset($this->_plugins[\'prefilter\'][$filter_name]);\r\n" + 
-               "                    $this->_load_plugins(array(array(\'prefilter\', $filter_name, null, null, false)));\r\n" + 
-               "                }\r\n" + 
-               "            }\r\n" + 
-               "        }\r\n" + 
-               "        if (count($this->_plugins[\'postfilter\']) > 0) {\r\n" + 
-               "            foreach ($this->_plugins[\'postfilter\'] as $filter_name => $postfilter) {\r\n" + 
-               "                if ($postfilter === false) {\r\n" + 
-               "                    unset($this->_plugins[\'postfilter\'][$filter_name]);\r\n" + 
-               "                    $this->_load_plugins(array(array(\'postfilter\', $filter_name, null, null, false)));\r\n" + 
-               "                }\r\n" + 
-               "            }\r\n" + 
-               "        }\r\n" + 
-               "    }\r\n" + 
-               "\r\n" + 
-               "\r\n" + 
-               "       /**\r\n" + 
-               "        * display Smarty syntax error\r\n" + 
-               "        *\r\n" + 
-               "        * @access public\r\n" + 
-               "        * @param  $error_msg\r\n" + 
-               "        * @param  $error_type\r\n" + 
-               "        * @param  $file\r\n" + 
-               "        * @param  $line\r\n" + 
-               "        */\r\n" + 
-               "    function _syntax_error($error_msg, $error_type = E_USER_ERROR, $file=null, $line=null)\r\n" + 
-               "    {\r\n" + 
-               "               if(isset($file) && isset($line)) {\r\n" + 
-               "                       $info = \' (\'.basename($file).\", line $line)\";\r\n" + 
-               "               } else {\r\n" + 
-               "                       $info = null;\r\n" + 
-               "               }\r\n" + 
-               "        trigger_error(\'Smarty: [in \' . $this->_current_file . \' line \' .\r\n" + 
-               "                      $this->_current_line_no . \"]: syntax error: $error_msg$info\", $error_type);\r\n" + 
-               "    }\r\n" + 
-               "}\r\n" + 
-               "\r\n" + 
-               "/**\r\n" + 
-               " * compare to values by their string length\r\n" + 
-               " *\r\n" + 
-               " * @access private\r\n" + 
-               " * @param  $a\r\n" + 
-               " * @param  $b\r\n" + 
-               " */\r\n" + 
-               "function _smarty_sort_length($a, $b)\r\n" + 
-               "{\r\n" + 
-               "       if($a == $b)\r\n" + 
-               "               return 0;\r\n" + 
-               "\r\n" + 
-               "       if(strlen($a) == strlen($b))\r\n" + 
-               "               return ($a > $b) ? -1 : 1;\r\n" + 
-               "\r\n" + 
-               "       return (strlen($a) > strlen($b)) ? -1 : 1;\r\n" + 
-               "}\r\n" + 
-               "\r\n" + 
-               "\r\n" + 
-               "/* vim: set et: */\r\n" + 
-               "\r\n" + 
-               "?>\r\n" + 
+    checkHTML("<?php\n" +
+               "\n" +
+               "/**\n" +
+               " * Project:     Smarty: the PHP compiling template engine\n" +
+               " * File:        Smarty_Compiler.class.php\n" +
+               " * Author:      Monte Ohrt <monte@ispi.net>\n" +
+               " *              Andrei Zmievski <andrei@php.net>\n" +
+               " *\n" +
+               " * Version:     2.4.2\n" +
+               " * Copyright:   2001,2002 ispi of Lincoln, Inc.\n" +
+               " *\n" +
+               " * This library is free software; you can redistribute it and/or\n" +
+               " * modify it under the terms of the GNU Lesser General Public\n" +
+               " * License as published by the Free Software Foundation; either\n" +
+               " * version 2.1 of the License, or (at your option) any later version.\n" +
+               " *\n" +
+               " * This library is distributed in the hope that it will be useful,\n" +
+               " * but WITHOUT ANY WARRANTY; without even the implied warranty of\n" +
+               " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n" +
+               " * Lesser General Public License for more details.\n" +
+               " *\n" +
+               " * You should have received a copy of the GNU Lesser General Public\n" +
+               " * License along with this library; if not, write to the Free Software\n" +
+               " * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n" +
+               " *\n" +
+               " * You may contact the authors of Smarty by e-mail at:\n" +
+               " * monte@ispi.net\n" +
+               " * andrei@php.net\n" +
+               " *\n" +
+               " * Or, write to:\n" +
+               " * Monte Ohrt\n" +
+               " * Director of Technology, ispi\n" +
+               " * 237 S. 70th suite 220\n" +
+               " * Lincoln, NE 68510\n" +
+               " *\n" +
+               " * The latest version of Smarty can be obtained from:\n" +
+               " * http://www.phpinsider.com/\n" +
+               " *\n" +
+               " */\n" +
+               "\n" +
+               "class Smarty_Compiler extends Smarty {\n" +
+               "       \n" +
+               "    // internal vars\n" +
+               "    public $_sectionelse_stack     =   array();    // keeps track of whether section had \'else\' part\n" +
+               "    public $_foreachelse_stack     =   array();    // keeps track of whether foreach had \'else\' part\n" +
+               "    public $_literal_blocks        =   array();    // keeps literal template blocks\n" +
+               "    public $_php_blocks            =   array();    // keeps php code blocks\n" +
+               "    public $_current_file          =   null;       // the current template being compiled\n" +
+               "    public $_current_line_no       =   1;          // line number for error messages\n" +
+               "    public $_capture_stack         =   array();    // keeps track of nested capture buffers\n" +
+               "    public $_plugin_info           =   array();    // keeps track of plugins to load\n" +
+               "    public $_init_smarty_vars      =   false;\n" +
+               "       public $_permitted_tokens               =       array(\'true\',\'false\',\'yes\',\'no\',\'on\',\'off\');\n" +
+               "    public $_db_qstr_regexp            =       null;           // regexps are setup in the constructor\n" +
+               "    public $_si_qstr_regexp            =       null;\n" +
+               "    public $_qstr_regexp                       =       null;\n" +
+               "    public $_func_regexp                       =       null;\n" +
+               "    public $_var_bracket_regexp        =       null;\n" +
+               "    public $_dvar_guts_regexp          =       null;\n" +
+               "    public $_dvar_regexp                       =       null;\n" +
+               "    public $_cvar_regexp                       =       null;\n" +
+               "    public $_svar_regexp                       =       null;\n" +
+               "    public $_avar_regexp                       =       null;\n" +
+               "    public $_mod_regexp                        =       null;\n" +
+               "    public $_var_regexp                    =   null;\n" +
+               "    public $_parenth_param_regexp      =       null;\n" +
+               "       public $_func_call_regexp               =       null;\n" +
+               "       public $_obj_ext_regexp         =       null;\n" +
+               "       public $_obj_start_regexp               =       null;\n" +
+               "       public $_obj_params_regexp              =       null;\n" +
+               "       public $_obj_call_regexp                =       null;\n" +
+               "\n" +
+               "       /**\n" +
+               "        * The class constructor.\n" +
+               "        *\n" +
+               "        * @access public\n" +
+               "        */\n" +
+               "    function Smarty_Compiler()\n" +
+               "    {\n" +
+               "               // matches double quoted strings:\n" +
+               "               // \"foobar\"\n" +
+               "               // \"foo\\\"bar\"\n" +
+               "       $this->_db_qstr_regexp = \'\"[^\"\\\\\\\\]*(?:\\\\\\\\.[^\"\\\\\\\\]*)*\"\';\n" +
+               "\n" +
+               "               // matches single quoted strings:\n" +
+               "               // \'foobar\'\n" +
+               "               // \'foo\\\'bar\'\n" +
+               "       $this->_si_qstr_regexp = \'\\\'[^\\\'\\\\\\\\]*(?:\\\\\\\\.[^\\\'\\\\\\\\]*)*\\\'\';\n" +
+               "\n" +
+               "               // matches single or double quoted strings\n" +
+               "       $this->_qstr_regexp = \'(?:\' . $this->_db_qstr_regexp . \'|\' . $this->_si_qstr_regexp . \')\';\n" +
+               "\n" +
+               "               // matches bracket portion of vars\n" +
+               "               // [0]\n" +
+               "               // [foo]\n" +
+               "               // [$bar]\n" +
+               "               $this->_var_bracket_regexp = \'\\[\\$?[\\w\\.]+\\]\';\n" +
+               "                               \n" +
+               "               // matches $ vars (not objects):\n" +
+               "               // $foo\n" +
+               "               // $foo.bar\n" +
+               "               // $foo.bar.foobar\n" +
+               "               // $foo[0]\n" +
+               "               // $foo[$bar]\n" +
+               "               // $foo[5][blah]\n" +
+               "               // $foo[5].bar[$foobar][4]\n" +
+               "               $this->_dvar_guts_regexp = \'\\w+(?:\' . $this->_var_bracket_regexp\n" +
+               "                               . \')*(?:\\.\\$?\\w+(?:\' . $this->_var_bracket_regexp . \')*)*\';\n" +
+               "               $this->_dvar_regexp = \'\\$\' . $this->_dvar_guts_regexp;\n" +
+               "\n" +
+               "               // matches config vars:\n" +
+               "               // #foo#\n" +
+               "               // #foobar123_foo#\n" +
+               "               $this->_cvar_regexp = \'\\#\\w+\\#\';\n" +
+               "\n" +
+               "               // matches section vars:\n" +
+               "               // %foo.bar%\n" +
+               "               $this->_svar_regexp = \'\\%\\w+\\.\\w+\\%\';\n" +
+               "\n" +
+               "               // matches all valid variables (no quotes, no modifiers)\n" +
+               "               $this->_avar_regexp = \'(?:\' . $this->_dvar_regexp . \'|\'\n" +
+               "                  . $this->_cvar_regexp . \'|\' . $this->_svar_regexp . \')\';\n" +
+               "\n" +
+               "               // matches valid modifier syntax:\n" +
+               "               // |foo\n" +
+               "               // |@foo\n" +
+               "               // |foo:\"bar\"\n" +
+               "               // |foo:$bar\n" +
+               "               // |foo:\"bar\":$foobar\n" +
+               "               // |foo|bar\n" +
+               "               // |foo\n" +
+               "               $this->_mod_regexp = \'(?:\\|@?\\w+(?::(?>\\w+|\'\n" +
+               "                  . $this->_avar_regexp . \'|\' . $this->_qstr_regexp .\'))*)\';\n" +
+               "\n" +
+               "               // matches valid variable syntax:\n" +
+               "               // $foo\n" +
+               "               // $foo\n" +
+               "               // #foo#\n" +
+               "               // #foo#\n" +
+               "               // \"text\"\n" +
+               "               // \"text\"\n" +
+               "               $this->_var_regexp = \'(?:\' . $this->_avar_regexp . \'|\' . $this->_qstr_regexp . \')\';\n" +
+               "                               \n" +
+               "               // matches valid object call (no objects allowed in parameters):\n" +
+               "               // $foo->bar\n" +
+               "               // $foo->bar()\n" +
+               "               // $foo->bar(\"text\")\n" +
+               "               // $foo->bar($foo, $bar, \"text\")\n" +
+               "               // $foo->bar($foo|bar, \"foo\"|bar)\n" +
+               "               // $foo->bar->foo()\n" +
+               "               // $foo->bar->foo->bar()\n" +
+               "               $this->_obj_ext_regexp = \'\\->(?:\\w+|\' . $this->_dvar_regexp . \')\';\n" +
+               "       $this->_obj_params_regexp = \'\\((?:\\w+|\'\n" +
+               "                               . $this->_var_regexp . \'(?>\' . $this->_mod_regexp . \'*)(?:\\s*,\\s*(?:(?:\\w+|\'\n" +
+               "                               . $this->_var_regexp . \'(?>\' . $this->_mod_regexp . \'*))))*)?\\)\';          \n" +
+               "       $this->_obj_start_regexp = \'(?:\' . $this->_dvar_regexp . \'(?:\' . $this->_obj_ext_regexp . \')+)\';\n" +
+               "               $this->_obj_call_regexp = \'(?:\' . $this->_obj_start_regexp . \'(?:\' . $this->_obj_params_regexp . \')?)\';\n" +
+               "               \n" +
+               "               // matches valid function name:\n" +
+               "               // foo123\n" +
+               "               // _foo_bar\n" +
+               "               $this->_func_regexp = \'[a-zA-Z_]\\w*\';\n" +
+               "\n" +
+               "               // matches valid registered object:\n" +
+               "               // foo.bar\n" +
+               "               $this->_reg_obj_regexp = \'[a-zA-Z_]\\w*->[a-zA-Z_]\\w*\';\n" +
+               "                               \n" +
+               "               // matches valid parameter values:\n" +
+               "               // true\n" +
+               "               // $foo\n" +
+               "               // $foo|bar\n" +
+               "               // #foo#\n" +
+               "               // #foo#|bar\n" +
+               "               // \"text\"\n" +
+               "               // \"text\"|bar\n" +
+               "               // $foo->bar\n" +
+               "               $this->_param_regexp = \'(?:\\s*(?:\' . $this->_obj_call_regexp . \'|\'\n" +
+               "                  . $this->_var_regexp  . \'|\\w+)(?>\' . $this->_mod_regexp . \'*)\\s*)\';            \n" +
+               "               \n" +
+               "               // matches valid parenthesised function parameters:\n" +
+               "               // \n" +
+               "               // \"text\"\n" +
+               "               //      $foo, $bar, \"text\"\n" +
+               "               // $foo|bar, \"foo\"|bar, $foo->bar($foo)|bar\n" +
+               "       $this->_parenth_param_regexp = \'(?:\\((?:\\w+|\'\n" +
+               "                               . $this->_param_regexp . \'(?:\\s*,\\s*(?:(?:\\w+|\'\n" +
+               "                               . $this->_param_regexp . \')))*)?\\))\';\n" +
+               "       \n" +
+               "               // matches valid function call:\n" +
+               "               // foo()\n" +
+               "               // foo_bar($foo)\n" +
+               "               // _foo_bar($foo,\"bar\")\n" +
+               "               // foo123($foo,$foo->bar(),\"foo\")\n" +
+               "       $this->_func_call_regexp = \'(?:\' . $this->_func_regexp . \'\\s*(?:\'\n" +
+               "                  . $this->_parenth_param_regexp . \'))\';             \n" +
+               "\n" +
+               "       }                       \n" +
+               "                       \n" +
+               "       /**\n" +
+               "        * compile a template file\n" +
+               "        *\n" +
+               "        * @access public\n" +
+               "        * @param  $tpl_file\n" +
+               "        * @param  $template_source\n" +
+               "        * @param  $template_compiled\n" +
+               "        */\n" +
+               "    function _compile_file($tpl_file, $template_source, &$template_compiled)\n" +
+               "    {\n" +
+               "        if ($this->security) {\n" +
+               "            // do not allow php syntax to be executed unless specified\n" +
+               "            if ($this->php_handling == SMARTY_PHP_ALLOW &&\n" +
+               "                !$this->security_settings[\'PHP_HANDLING\']) {\n" +
+               "                $this->php_handling = SMARTY_PHP_PASSTHRU;\n" +
+               "            }\n" +
+               "        }\n" +
+               "\n" +
+               "        $this->_load_filters();\n" +
+               "\n" +
+               "        $this->_current_file = $tpl_file;\n" +
+               "        $this->_current_line_no = 1;\n" +
+               "        $ldq = preg_quote($this->left_delimiter, \'!\');\n" +
+               "        $rdq = preg_quote($this->right_delimiter, \'!\');\n" +
+               "\n" +
+               "        // run template source through prefilter functions\n" +
+               "        if (count($this->_plugins[\'prefilter\']) > 0) {\n" +
+               "            foreach ($this->_plugins[\'prefilter\'] as $filter_name => $prefilter) {\n" +
+               "                if ($prefilter === false) continue; \n" +
+               "                if ($prefilter[3] || function_exists($prefilter[0])) {\n" +
+               "                    $template_source = $prefilter[0]($template_source, $this);\n" +
+               "                    $this->_plugins[\'prefilter\'][$filter_name][3] = true;\n" +
+               "                } else {\n" +
+               "                    $this->_trigger_fatal_error(\"[plugin] prefilter \'$filter_name\' is not implemented\");\n" +
+               "                }\n" +
+               "            }\n" +
+               "        }\n" +
+               "\n" +
+               "        /* Annihilate the comments. */\n" +
+               "        $template_source = preg_replace(\"!({$ldq})\\*(.*?)\\*({$rdq})!se\",\n" +
+               "                                        \"\'\\\\1*\'.str_repeat(\\\"\\n\\\", substr_count(\'\\\\2\', \\\"\\n\\\")) .\'*\\\\3\'\",\n" +
+               "                                        $template_source);\n" +
+               "\n" +
+               "        /* Pull out the literal blocks. */\n" +
+               "        preg_match_all(\"!{$ldq}literal{$rdq}(.*?){$ldq}/literal{$rdq}!s\", $template_source, $match);\n" +
+               "        $this->_literal_blocks = $match[1];\n" +
+               "        $template_source = preg_replace(\"!{$ldq}literal{$rdq}(.*?){$ldq}/literal{$rdq}!s\",\n" +
+               "                                        $this->quote_replace($this->left_delimiter.\'literal\'.$this->right_delimiter), $template_source);\n" +
+               "\n" +
+               "        /* Pull out the php code blocks. */\n" +
+               "        preg_match_all(\"!{$ldq}php{$rdq}(.*?){$ldq}/php{$rdq}!s\", $template_source, $match);\n" +
+               "        $this->_php_blocks = $match[1];\n" +
+               "        $template_source = preg_replace(\"!{$ldq}php{$rdq}(.*?){$ldq}/php{$rdq}!s\",\n" +
+               "                                        $this->quote_replace($this->left_delimiter.\'php\'.$this->right_delimiter), $template_source);\n" +
+               "\n" +
+               "        /* Gather all template tags. */\n" +
+               "        preg_match_all(\"!{$ldq}\\s*(.*?)\\s*{$rdq}!s\", $template_source, $match);\n" +
+               "        $template_tags = $match[1];\n" +
+               "        /* Split content by template tags to obtain non-template content. */\n" +
+               "        $text_blocks = preg_split(\"!{$ldq}.*?{$rdq}!s\", $template_source);\n" +
+               "               \n" +
+               "        /* loop through text blocks */\n" +
+               "        for ($curr_tb = 0, $for_max = count($text_blocks); $curr_tb < $for_max; $curr_tb++) {\n" +
+               "            /* match anything resembling php tags */\n" +
+               "            if (preg_match_all(\'!(<\\?(?:\\w+|=)?|\\?>|language\\s*=\\s*[\\\"\\\']?php[\\\"\\\']?)!is\', $text_blocks[$curr_tb], $sp_match)) {\n" +
+               "                               /* replace tags with placeholders to prevent recursive replacements */\n" +
+               "                               $sp_match[1] = array_unique($sp_match[1]);\n" +
+               "                               usort($sp_match[1], \'_smarty_sort_length\');\n" +
+               "                for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) {\n" +
+               "                                       $text_blocks[$curr_tb] = str_replace($sp_match[1][$curr_sp],\'%%%SMARTYSP\'.$curr_sp.\'%%%\',$text_blocks[$curr_tb]);\n" +
+               "                               }\n" +
+               "                /* process each one */\n" +
+               "                for ($curr_sp = 0, $for_max2 = count($sp_match[0]); $curr_sp < $for_max2; $curr_sp++) {\n" +
+               "                    if ($this->php_handling == SMARTY_PHP_PASSTHRU) {\n" +
+               "                        /* echo php contents */\n" +
+               "                        $text_blocks[$curr_tb] = str_replace(\'%%%SMARTYSP\'.$curr_sp.\'%%%\', \'<?php echo \\\'\'.str_replace(\"\'\", \"\\\'\", $sp_match[1][$curr_sp]).\'\\\'; ?>\'.\"\\n\", $text_blocks[$curr_tb]);\n" +
+               "                    } else if ($this->php_handling == SMARTY_PHP_QUOTE) {\n" +
+               "                        /* quote php tags */\n" +
+               "                        $text_blocks[$curr_tb] = str_replace(\'%%%SMARTYSP\'.$curr_sp.\'%%%\', htmlspecialchars($sp_match[1][$curr_sp]), $text_blocks[$curr_tb]);\n" +
+               "                    } else if ($this->php_handling == SMARTY_PHP_REMOVE) {\n" +
+               "                        /* remove php tags */\n" +
+               "                        $text_blocks[$curr_tb] = str_replace(\'%%%SMARTYSP\'.$curr_sp.\'%%%\', \'\', $text_blocks[$curr_tb]);\n" +
+               "                    } else {\n" +
+               "                                               /* SMARTY_PHP_ALLOW, but echo non php starting tags */\n" +
+               "                                               $sp_match[1][$curr_sp] = preg_replace(\'%(<\\?(?!php|=|$))%i\', \'<?php echo \\\'\\\\1\\\'?>\'.\"\\n\", $sp_match[1][$curr_sp]);\n" +
+               "                                               $text_blocks[$curr_tb] = str_replace(\'%%%SMARTYSP\'.$curr_sp.\'%%%\', $sp_match[1][$curr_sp], $text_blocks[$curr_tb]);\n" +
+               "                                       }\n" +
+               "                }\n" +
+               "            }\n" +
+               "        }\n" +
+               "\n" +
+               "        /* Compile the template tags into PHP code. */\n" +
+               "        $compiled_tags = array();\n" +
+               "        for ($i = 0, $for_max = count($template_tags); $i < $for_max; $i++) {\n" +
+               "            $this->_current_line_no += substr_count($text_blocks[$i], \"\\n\");\n" +
+               "            $compiled_tags[] = $this->_compile_tag($template_tags[$i]);\n" +
+               "            $this->_current_line_no += substr_count($template_tags[$i], \"\\n\");\n" +
+               "        }\n" +
+               "\n" +
+               "        $template_compiled = \'\';\n" +
+               "\n" +
+               "        /* Interleave the compiled contents and text blocks to get the final result. */\n" +
+               "        for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) {\n" +
+               "            $template_compiled .= $text_blocks[$i].$compiled_tags[$i];\n" +
+               "        }\n" +
+               "        $template_compiled .= $text_blocks[$i];\n" +
+               "\n" +
+               "        /* Reformat data between \'strip\' and \'/strip\' tags, removing spaces, tabs and newlines. */\n" +
+               "        if (preg_match_all(\"!{$ldq}strip{$rdq}.*?{$ldq}/strip{$rdq}!s\", $template_compiled, $match)) {\n" +
+               "            $strip_tags = $match[0];\n" +
+               "            $strip_tags_modified = preg_replace(\"!{$ldq}/?strip{$rdq}|[\\t ]+$|^[\\t ]+!m\", \'\', $strip_tags);\n" +
+               "            $strip_tags_modified = preg_replace(\'![\\r\\n]+!m\', \'\', $strip_tags_modified);\n" +
+               "            for ($i = 0, $for_max = count($strip_tags); $i < $for_max; $i++)\n" +
+               "                $template_compiled = preg_replace(\"!{$ldq}strip{$rdq}.*?{$ldq}/strip{$rdq}!s\",\n" +
+               "                                                  $this->quote_replace($strip_tags_modified[$i]),\n" +
+               "                                                  $template_compiled, 1);\n" +
+               "        }\n" +
+               "\n" +
+               "        // remove \\n from the end of the file, if any\n" +
+               "        if ($template_compiled{strlen($template_compiled) - 1} == \"\\n\" ) {\n" +
+               "            $template_compiled = substr($template_compiled, 0, -1);\n" +
+               "        }\n" +
+               "\n" +
+               "        // run compiled template through postfilter functions\n" +
+               "        if (count($this->_plugins[\'postfilter\']) > 0) {\n" +
+               "            foreach ($this->_plugins[\'postfilter\'] as $filter_name => $postfilter) {\n" +
+               "                if ($postfilter === false) continue;\n" +
+               "                if ($postfilter[3] || function_exists($postfilter[0])) {\n" +
+               "                    $template_compiled = $postfilter[0]($template_compiled, $this);\n" +
+               "                    $this->_plugins[\'postfilter\'][$filter_name][3] = true;\n" +
+               "                } else {\n" +
+               "                    $this->_trigger_plugin_error(\"Smarty plugin error: postfilter \'$filter_name\' is not implemented\");\n" +
+               "                }\n" +
+               "            }\n" +
+               "        }\n" +
+               "\n" +
+               "        // put header at the top of the compiled template\n" +
+               "        $template_header = \"<?php /* Smarty version \".$this->_version.\", created on \".strftime(\"%Y-%m-%d %H:%M:%S\").\"\\n\";\n" +
+               "        $template_header .= \"         compiled from \".$tpl_file.\" */ ?>\\n\";\n" +
+               "\n" +
+               "        /* Emit code to load needed plugins. */\n" +
+               "        if (count($this->_plugin_info)) {\n" +
+               "            $plugins_code = \'<?php $this->_load_plugins(array(\';\n" +
+               "            foreach ($this->_plugin_info as $plugin_type => $plugins) {\n" +
+               "                foreach ($plugins as $plugin_name => $plugin_info) {\n" +
+               "                    $plugins_code .= \"\\narray(\'$plugin_type\', \'$plugin_name\', \'$plugin_info[0]\', $plugin_info[1], \";\n" +
+               "                    $plugins_code .= $plugin_info[2] ? \'true),\' : \'false),\';\n" +
+               "                }\n" +
+               "            }\n" +
+               "            $plugins_code .= \")); ?>\";\n" +
+               "            $template_header .= $plugins_code;\n" +
+               "            $this->_plugin_info = array();\n" +
+               "        }\n" +
+               "\n" +
+               "        if ($this->_init_smarty_vars) {\n" +
+               "            $template_header .= \"<?php \\$this->_assign_smarty_interface(); ?>\\n\";\n" +
+               "            $this->_init_smarty_vars = false;\n" +
+               "        }\n" +
+               "\n" +
+               "        $template_compiled = $template_header . $template_compiled;\n" +
+               "\n" +
+               "        return true;\n" +
+               "    }\n" +
+               "\n" +
+               "       /**\n" +
+               "        * Compile a template tag\n" +
+               "        *\n" +
+               "        * @access public\n" +
+               "        * @param  $template_tag\n" +
+               "        */\n" +
+               "    function _compile_tag($template_tag)\n" +
+               "    {          \n" +
+               "                               \n" +
+               "        /* Matched comment. */\n" +
+               "        if ($template_tag{0} == \'*\' && $template_tag{strlen($template_tag) - 1} == \'*\')\n" +
+               "            return \'\';\n" +
+               "               \n" +
+               "        /* Split tag into two three parts: command, command modifiers and the arguments. */\n" +
+               "        if(! preg_match(\'/^(?:(\' . $this->_obj_call_regexp . \'|\' . $this->_var_regexp\n" +
+               "                               . \'|\' . $this->_reg_obj_regexp . \'|\\/?\' . $this->_func_regexp . \')(\' . $this->_mod_regexp . \'*))\n" +
+               "                      (?:\\s+(.*))?$\n" +
+               "                    /xs\', $template_tag, $match)) {\n" +
+               "                       $this->_syntax_error(\"unrecognized tag: $template_tag\", E_USER_ERROR, __FILE__, __LINE__);\n" +
+               "               }\n" +
+               "\n" +
+               "        $tag_command = $match[1];\n" +
+               "        $tag_modifier = isset($match[2]) ? $match[2] : null;\n" +
+               "        $tag_args = isset($match[3]) ? $match[3] : null;\n" +
+               "               \n" +
+               "               \n" +
+               "        /* If the tag name is a variable or object, we process it. */\n" +
+               "        if (preg_match(\'!^\' . $this->_obj_call_regexp . \'|\' . $this->_var_regexp . \'$!\', $tag_command)) {\n" +
+               "            $return = $this->_parse_var_props($tag_command . $tag_modifier, $this->_parse_attrs($tag_args));\n" +
+               "                       if(isset($_tag_attrs[\'assign\'])) {\n" +
+               "                               return \"<?php \\$this->assign(\'\" . $this->_dequote($_tag_attrs[\'assign\']) . \"\', $return ); ?>\\n\";  \n" +
+               "                       } else {\n" +
+               "               return \"<?php echo $return; ?>\\n\";\n" +
+               "                       }\n" +
+               "               }\n" +
+               "               \n" +
+               "           /* If the tag name is a registered object, we process it. */\n" +
+               "        if (preg_match(\'!^\' . $this->_reg_obj_regexp . \'$!\', $tag_command)) {\n" +
+               "                       return $this->_compile_registered_object_tag($tag_command, $this->_parse_attrs($tag_args), $tag_modifier);\n" +
+               "               }\n" +
+               "\n" +
+               "        switch ($tag_command) {\n" +
+               "            case \'include\':\n" +
+               "                return $this->_compile_include_tag($tag_args);\n" +
+               "\n" +
+               "            case \'include_php\':\n" +
+               "                return $this->_compile_include_php_tag($tag_args);\n" +
+               "\n" +
+               "            case \'if\':\n" +
+               "                return $this->_compile_if_tag($tag_args);\n" +
+               "\n" +
+               "            case \'else\':\n" +
+               "                return \'<?php else: ?>\';\n" +
+               "\n" +
+               "            case \'elseif\':\n" +
+               "                return $this->_compile_if_tag($tag_args, true);\n" +
+               "\n" +
+               "            case \'/if\':\n" +
+               "                return \'<?php endif; ?>\';\n" +
+               "\n" +
+               "            case \'capture\':\n" +
+               "                return $this->_compile_capture_tag(true, $tag_args);\n" +
+               "\n" +
+               "            case \'/capture\':\n" +
+               "                return $this->_compile_capture_tag(false);\n" +
+               "\n" +
+               "            case \'ldelim\':\n" +
+               "                return $this->left_delimiter;\n" +
+               "\n" +
+               "            case \'rdelim\':\n" +
+               "                return $this->right_delimiter;\n" +
+               "\n" +
+               "            case \'section\':\n" +
+               "                array_push($this->_sectionelse_stack, false);\n" +
+               "                return $this->_compile_section_start($tag_args);\n" +
+               "\n" +
+               "            case \'sectionelse\':\n" +
+               "                $this->_sectionelse_stack[count($this->_sectionelse_stack)-1] = true;\n" +
+               "                return \"<?php endfor; else: ?>\";\n" +
+               "\n" +
+               "            case \'/section\':\n" +
+               "                if (array_pop($this->_sectionelse_stack))\n" +
+               "                    return \"<?php endif; ?>\";\n" +
+               "                else\n" +
+               "                    return \"<?php endfor; endif; ?>\";\n" +
+               "\n" +
+               "            case \'foreach\':\n" +
+               "                array_push($this->_foreachelse_stack, false);\n" +
+               "                return $this->_compile_foreach_start($tag_args);\n" +
+               "                break;\n" +
+               "\n" +
+               "            case \'foreachelse\':\n" +
+               "                $this->_foreachelse_stack[count($this->_foreachelse_stack)-1] = true;\n" +
+               "                return \"<?php endforeach; else: ?>\";\n" +
+               "\n" +
+               "            case \'/foreach\':\n" +
+               "                if (array_pop($this->_foreachelse_stack))\n" +
+               "                    return \"<?php endif; ?>\";\n" +
+               "                else\n" +
+               "                    return \"<?php endforeach; endif; ?>\";\n" +
+               "\n" +
+               "            case \'config_load\':\n" +
+               "                return $this->_compile_config_load_tag($tag_args);\n" +
+               "\n" +
+               "            case \'strip\':\n" +
+               "            case \'/strip\':\n" +
+               "                return $this->left_delimiter.$tag_command.$this->right_delimiter;\n" +
+               "\n" +
+               "            case \'literal\':\n" +
+               "                list (,$literal_block) = each($this->_literal_blocks);\n" +
+               "                $this->_current_line_no += substr_count($literal_block, \"\\n\");\n" +
+               "                return \"<?php echo \'\".str_replace(\"\'\", \"\\\'\", str_replace(\"\\\\\", \"\\\\\\\\\", $literal_block)).\"\'; ?>\\n\";\n" +
+               "\n" +
+               "            case \'php\':\n" +
+               "                if ($this->security && !$this->security_settings[\'PHP_TAGS\']) {\n" +
+               "                    $this->_syntax_error(\"(secure mode) php tags not permitted\", E_USER_WARNING, __FILE__, __LINE__);\n" +
+               "                    return;\n" +
+               "                }\n" +
+               "                list (,$php_block) = each($this->_php_blocks);\n" +
+               "                $this->_current_line_no += substr_count($php_block, \"\\n\");\n" +
+               "                return \'<?php \'.$php_block.\' ?>\';\n" +
+               "\n" +
+               "            case \'insert\':\n" +
+               "                return $this->_compile_insert_tag($tag_args);\n" +
+               "\n" +
+               "            default:\n" +
+               "                if ($this->_compile_compiler_tag($tag_command, $tag_args, $output)) {\n" +
+               "                    return $output;\n" +
+               "                } else if ($this->_compile_block_tag($tag_command, $tag_args, $tag_modifier, $output)) {\n" +
+               "                    return $output;\n" +
+               "                } else {\n" +
+               "                    return $this->_compile_custom_tag($tag_command, $tag_args, $tag_modifier);\n" +
+               "                }\n" +
+               "        }\n" +
+               "    }\n" +
+               "\n" +
+               "\n" +
+               "       /**\n" +
+               "        * compile the custom compiler tag\n" +
+               "        *\n" +
+               "        * @access public\n" +
+               "        * @param  $tag_command\n" +
+               "        * @param  $tag_args\n" +
+               "        * @param  $output\n" +
+               "        */\n" +
+               "    function _compile_compiler_tag($tag_command, $tag_args, &$output)\n" +
+               "    {\n" +
+               "        $found = false;\n" +
+               "        $have_function = true;\n" +
+               "\n" +
+               "        /*\n" +
+               "         * First we check if the compiler function has already been registered\n" +
+               "         * or loaded from a plugin file.\n" +
+               "         */\n" +
+               "        if (isset($this->_plugins[\'compiler\'][$tag_command])) {\n" +
+               "            $found = true;\n" +
+               "            $plugin_func = $this->_plugins[\'compiler\'][$tag_command][0];\n" +
+               "            if (!function_exists($plugin_func)) {\n" +
+               "                $message = \"compiler function \'$tag_command\' is not implemented\";\n" +
+               "                $have_function = false;\n" +
+               "            }\n" +
+               "        }\n" +
+               "        /*\n" +
+               "         * Otherwise we need to load plugin file and look for the function\n" +
+               "         * inside it.\n" +
+               "         */\n" +
+               "        else if ($plugin_file = $this->_get_plugin_filepath(\'compiler\', $tag_command)) {\n" +
+               "            $found = true;\n" +
+               "\n" +
+               "            include_once $plugin_file;\n" +
+               "\n" +
+               "            $plugin_func = \'smarty_compiler_\' . $tag_command;\n" +
+               "            if (!function_exists($plugin_func)) {\n" +
+               "                $message = \"plugin function $plugin_func() not found in $plugin_file\\n\";\n" +
+               "                $have_function = false;\n" +
+               "            } else {\n" +
+               "                $this->_plugins[\'compiler\'][$tag_command] = array($plugin_func, null, null);\n" +
+               "            }\n" +
+               "        }\n" +
+               "\n" +
+               "        /*\n" +
+               "         * True return value means that we either found a plugin or a\n" +
+               "         * dynamically registered function. False means that we didn\'t and the\n" +
+               "         * compiler should now emit code to load custom function plugin for this\n" +
+               "         * tag.\n" +
+               "         */\n" +
+               "        if ($found) {\n" +
+               "            if ($have_function) {\n" +
+               "                $output = \'<?php \' . $plugin_func($tag_args, $this) . \' ?>\';\n" +
+               "            } else {\n" +
+               "                $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);\n" +
+               "            }\n" +
+               "            return true;\n" +
+               "        } else {\n" +
+               "            return false;\n" +
+               "        }\n" +
+               "    }\n" +
+               "\n" +
+               "\n" +
+               "       /**\n" +
+               "        * compile block function tag\n" +
+               "        *\n" +
+               "        * @access public\n" +
+               "        * @param  $tag_command\n" +
+               "        * @param  $tag_args\n" +
+               "        * @param  $tag_modifier\n" +
+               "        * @param  $output\n" +
+               "        */\n" +
+               "    function _compile_block_tag($tag_command, $tag_args, $tag_modifier, &$output)\n" +
+               "    {\n" +
+               "        if ($tag_command{0} == \'/\') {\n" +
+               "            $start_tag = false;\n" +
+               "            $tag_command = substr($tag_command, 1);\n" +
+               "        } else\n" +
+               "            $start_tag = true;\n" +
+               "\n" +
+               "        $found = false;\n" +
+               "        $have_function = true;\n" +
+               "\n" +
+               "        /*\n" +
+               "         * First we check if the block function has already been registered\n" +
+               "         * or loaded from a plugin file.\n" +
+               "         */\n" +
+               "        if (isset($this->_plugins[\'block\'][$tag_command])) {\n" +
+               "            $found = true;\n" +
+               "            $plugin_func = $this->_plugins[\'block\'][$tag_command][0];\n" +
+               "            if (!function_exists($plugin_func)) {\n" +
+               "                $message = \"block function \'$tag_command\' is not implemented\";\n" +
+               "                $have_function = false;\n" +
+               "            }\n" +
+               "        }\n" +
+               "        /*\n" +
+               "         * Otherwise we need to load plugin file and look for the function\n" +
+               "         * inside it.\n" +
+               "         */\n" +
+               "        else if ($plugin_file = $this->_get_plugin_filepath(\'block\', $tag_command)) {\n" +
+               "            $found = true;\n" +
+               "\n" +
+               "            include_once $plugin_file;\n" +
+               "\n" +
+               "            $plugin_func = \'smarty_block_\' . $tag_command;\n" +
+               "            if (!function_exists($plugin_func)) {\n" +
+               "                $message = \"plugin function $plugin_func() not found in $plugin_file\\n\";\n" +
+               "                $have_function = false;\n" +
+               "            } else {\n" +
+               "                $this->_plugins[\'block\'][$tag_command] = array($plugin_func, null, null);\n" +
+               "            }\n" +
+               "        }\n" +
+               "\n" +
+               "        if (!$found) {\n" +
+               "            return false;\n" +
+               "        } else if (!$have_function) {\n" +
+               "            $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);\n" +
+               "            return true;\n" +
+               "        }\n" +
+               "\n" +
+               "        /*\n" +
+               "         * Even though we\'ve located the plugin function, compilation\n" +
+               "         * happens only once, so the plugin will still need to be loaded\n" +
+               "         * at runtime for future requests.\n" +
+               "         */\n" +
+               "        $this->_add_plugin(\'block\', $tag_command);\n" +
+               "\n" +
+               "        if ($start_tag) {\n" +
+               "            $arg_list = array();\n" +
+               "            $attrs = $this->_parse_attrs($tag_args);\n" +
+               "            foreach ($attrs as $arg_name => $arg_value) {\n" +
+               "                if (is_bool($arg_value))\n" +
+               "                    $arg_value = $arg_value ? \'true\' : \'false\';\n" +
+               "                $arg_list[] = \"\'$arg_name\' => $arg_value\";\n" +
+               "            }\n" +
+               "\n" +
+               "            $output = \"<?php \\$this->_tag_stack[] = array(\'$tag_command\', array(\".implode(\',\', (array)$arg_list).\")); \\$this->_plugins[\'block\'][\'$tag_command\'][0](array(\".implode(\',\', (array)$arg_list).\"), null, \\$this); ob_start(); ?>\";\n" +
+               "        } else {\n" +
+               "            $output = \"<?php \\$this->_block_content = ob_get_contents(); ob_end_clean(); \";\n" +
+               "                       $out_tag_text = \"\\$this->_plugins[\'block\'][\'$tag_command\'][0](\\$this->_tag_stack[count(\\$this->_tag_stack)-1][1], \\$this->_block_content, \\$this)\";\n" +
+               "                       if($tag_modifier != \'\') {\n" +
+               "                               $this->_parse_modifiers($out_tag_text, $tag_modifier);\n" +
+               "                       }\n" +
+               "                       $output .= \'echo \' . $out_tag_text . \';\';\n" +
+               "                       $output .= \" array_pop(\\$this->_tag_stack); ?>\";\n" +
+               "        }\n" +
+               "\n" +
+               "        return true;\n" +
+               "    }\n" +
+               "\n" +
+               "\n" +
+               "       /**\n" +
+               "        * compile custom function tag\n" +
+               "        *\n" +
+               "        * @access public\n" +
+               "        * @param  $tag_command\n" +
+               "        * @param  $tag_args\n" +
+               "        * @param  $tag_modifier\n" +
+               "        */\n" +
+               "    function _compile_custom_tag($tag_command, $tag_args, $tag_modifier)\n" +
+               "    {\n" +
+               "        $this->_add_plugin(\'function\', $tag_command);\n" +
+               "\n" +
+               "        $arg_list = array();\n" +
+               "        $attrs = $this->_parse_attrs($tag_args);\n" +
+               "        foreach ($attrs as $arg_name => $arg_value) {\n" +
+               "            if (is_bool($arg_value))\n" +
+               "                $arg_value = $arg_value ? \'true\' : \'false\';\n" +
+               "            $arg_list[] = \"\'$arg_name\' => $arg_value\";\n" +
+               "        }\n" +
+               "               \n" +
+               "               $return = \"\\$this->_plugins[\'function\'][\'$tag_command\'][0](array(\".implode(\',\', (array)$arg_list).\"), \\$this)\";\n" +
+               "               \n" +
+               "               if($tag_modifier != \'\') {\n" +
+               "                       $this->_parse_modifiers($return, $tag_modifier);\n" +
+               "               }\n" +
+               "               \n" +
+               "        return \'<?php echo \' . $return . \" ; ?>\\n\";\n" +
+               "    }\n" +
+               "\n" +
+               "       /**\n" +
+               "        * compile a registered object tag\n" +
+               "        *\n" +
+               "        * @access public\n" +
+               "        * @param  $tag_command\n" +
+               "        * @param  $attrs\n" +
+               "        * @param  $tag_modifier\n" +
+               "        */\n" +
+               "    function _compile_registered_object_tag($tag_command, $attrs, $tag_modifier)\n" +
+               "    {\n" +
+               "               list($object, $obj_comp) = explode(\'->\', $tag_command);\n" +
+               "\n" +
+               "        $arg_list = array();\n" +
+               "               if(count($attrs)) {\n" +
+               "                       $_assign_var = false;\n" +
+               "               foreach ($attrs as $arg_name => $arg_value) {\n" +
+               "                               if($arg_name == \'assign\') {\n" +
+               "                                       $_assign_var = $arg_value;\n" +
+               "                                       unset($attrs[\'assign\']);\n" +
+               "                                       continue;\n" +
+               "                               }\n" +
+               "               if (is_bool($arg_value))\n" +
+               "                       $arg_value = $arg_value ? \'true\' : \'false\';\n" +
+               "               $arg_list[] = \"\'$arg_name\' => $arg_value\";\n" +
+               "               }\n" +
+               "               }\n" +
+               "                               \n" +
+               "               if(!is_object($this->_reg_objects[$object][0])) {\n" +
+               "                       $this->_trigger_fatal_error(\"registered \'$object\' is not an object\");\n" +
+               "               } elseif(!empty($this->_reg_objects[$object][1]) && !in_array($obj_comp, $this->_reg_objects[$object][1])) {\n" +
+               "                       $this->_trigger_fatal_error(\"\'$obj_comp\' is not a registered component of object \'$object\'\");\n" +
+               "               } elseif(method_exists($this->_reg_objects[$object][0], $obj_comp)) {\n" +
+               "                       // method\n" +
+               "                       if($this->_reg_objects[$object][2]) {\n" +
+               "                               // smarty object argument format\n" +
+               "                               $return = \"\\$this->_reg_objects[\'$object\'][0]->$obj_comp(array(\".implode(\',\', (array)$arg_list).\"), \\$this)\";\n" +
+               "                       } else {\n" +
+               "                               // traditional argument format\n" +
+               "                               $return = \"\\$this->_reg_objects[\'$object\'][0]->$obj_comp(\".implode(\',\', array_values($attrs)).\")\";\n" +
+               "                       }\n" +
+               "               } else {\n" +
+               "                       // property\n" +
+               "                       $return = \"\\$this->_reg_objects[\'$object\'][0]->$obj_comp\";\n" +
+               "               }\n" +
+               "               \n" +
+               "               if($tag_modifier != \'\') {\n" +
+               "                       $this->_parse_modifiers($return, $tag_modifier);\n" +
+               "               }\n" +
+               "               \n" +
+               "               if($_assign_var) {\n" +
+               "                       return \"<?php \\$this->assign(\'\" . $this->_dequote($_assign_var) .\"\',  $return); ?>\\n\";\n" +
+               "               } else {\n" +
+               "               return \'<?php echo \' . $return . \"; ?>\\n\";\n" +
+               "               }\n" +
+               "    }\n" +
+               "       \n" +
+               "       \n" +
+               "\n" +
+               "       /**\n" +
+               "        * Compile {insert ...} tag\n" +
+               "        *\n" +
+               "        * @access public\n" +
+               "        * @param  $tag_args\n" +
+               "        */\n" +
+               "    function _compile_insert_tag($tag_args)\n" +
+               "    {\n" +
+               "        $attrs = $this->_parse_attrs($tag_args);\n" +
+               "        $name = $this->_dequote($attrs[\'name\']);\n" +
+               "\n" +
+               "        if (empty($name)) {\n" +
+               "            $this->_syntax_error(\"missing insert name\", E_USER_ERROR, __FILE__, __LINE__);\n" +
+               "        }\n" +
+               "\n" +
+               "        if (!empty($attrs[\'script\'])) {\n" +
+               "            $delayed_loading = true;\n" +
+               "        } else {\n" +
+               "            $delayed_loading = false;                  \n" +
+               "               }\n" +
+               "\n" +
+               "        foreach ($attrs as $arg_name => $arg_value) {\n" +
+               "            if (is_bool($arg_value))\n" +
+               "                $arg_value = $arg_value ? \'true\' : \'false\';\n" +
+               "            $arg_list[] = \"\'$arg_name\' => $arg_value\";\n" +
+               "        }\n" +
+               "\n" +
+               "        $this->_add_plugin(\'insert\', $name, $delayed_loading);\n" +
+               "\n" +
+               "        return \"<?php echo \\$this->_run_insert_handler(array(\".implode(\', \', (array)$arg_list).\")); ?>\\n\";\n" +
+               "    }\n" +
+               "\n" +
+               "\n" +
+               "       /**\n" +
+               "        * Compile {config_load ...} tag\n" +
+               "        *\n" +
+               "        * @access public\n" +
+               "        * @param  $tag_args\n" +
+               "        */\n" +
+               "    function _compile_config_load_tag($tag_args)\n" +
+               "    {\n" +
+               "        $attrs = $this->_parse_attrs($tag_args);\n" +
+               "\n" +
+               "        if (empty($attrs[\'file\'])) {\n" +
+               "            $this->_syntax_error(\"missing \'file\' attribute in config_load tag\", E_USER_ERROR, __FILE__, __LINE__);\n" +
+               "        }\n" +
+               "\n" +
+               "        if (empty($attrs[\'section\'])) {\n" +
+               "            $attrs[\'section\'] = \'null\';\n" +
+               "        }\n" +
+               "\n" +
+               "        if (isset($attrs[\'scope\'])) {\n" +
+               "                       $scope = @$this->_dequote($attrs[\'scope\']);\r\n" +
+               "            if ($scope != \'local\' &&\r\n" +
+               "                $scope != \'parent\' &&\r\n" +
+               "                $scope != \'global\') {\r\n" +
+               "                $this->_syntax_error(\"invalid \'scope\' attribute value\", E_USER_ERROR, __FILE__, __LINE__);\r\n" +
+               "            }\r\n" +
+               "        } else {\r\n" +
+               "            if (isset($attrs[\'global\']) && $attrs[\'global\'])\r\n" +
+               "                $scope = \'parent\';\r\n" +
+               "            else\r\n" +
+               "                $scope = \'local\';\r\n" +
+               "        }\r\n" +
+               "\r\n" +
+               "        return \'<?php $this->config_load(\' . $attrs[\'file\'] . \', \' . $attrs[\'section\'] . \", \'$scope\'); ?>\";\r\n" +
+               "    }\r\n" +
+               "\r\n" +
+               "\r\n" +
+               "       /**\r\n" +
+               "        * Compile {include ...} tag\r\n" +
+               "        *\r\n" +
+               "        * @access public\r\n" +
+               "        * $param  $tag_args\r\n" +
+               "        */\r\n" +
+               "    function _compile_include_tag($tag_args)\r\n" +
+               "    {\r\n" +
+               "        $attrs = $this->_parse_attrs($tag_args);\r\n" +
+               "        $arg_list = array();\r\n" +
+               "\r\n" +
+               "        if (empty($attrs[\'file\'])) {\r\n" +
+               "            $this->_syntax_error(\"missing \'file\' attribute in include tag\", E_USER_ERROR, __FILE__, __LINE__);\r\n" +
+               "        }\r\n" +
+               "\r\n" +
+               "        foreach ($attrs as $arg_name => $arg_value) {\r\n" +
+               "            if ($arg_name == \'file\') {\r\n" +
+               "                $include_file = $arg_value;\r\n" +
+               "                continue;\r\n" +
+               "            } else if ($arg_name == \'assign\') {\r\n" +
+               "                $assign_var = $arg_value;\r\n" +
+               "                continue;\r\n" +
+               "            }\r\n" +
+               "            if (is_bool($arg_value))\r\n" +
+               "                $arg_value = $arg_value ? \'true\' : \'false\';\r\n" +
+               "            $arg_list[] = \"\'$arg_name\' => $arg_value\";\r\n" +
+               "        }\r\n" +
+               "\r\n" +
+               "        $output = \'<?php \';\r\n" +
+               "\r\n" +
+               "        if (isset($assign_var)) {\r\n" +
+               "                       $output .= \"ob_start();\\n\";\r\n" +
+               "        }\r\n" +
+               "\r\n" +
+               "        $output .=  \r\n" +
+               "            \"\\$_smarty_tpl_vars = \\$this->_tpl_vars;\\n\" .\r\n" +
+               "            \"\\$this->_smarty_include(\".$include_file.\", array(\".implode(\',\', (array)$arg_list).\"));\\n\" .\r\n" +
+               "            \"\\$this->_tpl_vars = \\$_smarty_tpl_vars;\\n\" .\r\n" +
+               "            \"unset(\\$_smarty_tpl_vars);\\n\";\r\n" +
+               "\r\n" +
+               "        if (isset($assign_var)) {\r\n" +
+               "                       $output .= \"\\$this->assign(\" . $assign_var . \", ob_get_contents()); ob_end_clean();\\n\";\r\n" +
+               "        }\r\n" +
+               "\r\n" +
+               "        $output .= \' ?>\';\r\n" +
+               "\r\n" +
+               "               return $output;\r\n" +
+               "\r\n" +
+               "    }\r\n" +
+               "\r\n" +
+               "       /**\r\n" +
+               "        * Compile {include ...} tag\r\n" +
+               "        *\r\n" +
+               "        * @access public\r\n" +
+               "        * @param $tag_args\r\n" +
+               "        */\r\n" +
+               "    function _compile_include_php_tag($tag_args)\r\n" +
+               "    {\r\n" +
+               "        $attrs = $this->_parse_attrs($tag_args);\r\n" +
+               "\r\n" +
+               "        if (empty($attrs[\'file\'])) {\r\n" +
+               "            $this->_syntax_error(\"missing \'file\' attribute in include_php tag\", E_USER_ERROR, __FILE__, __LINE__);\r\n" +
+               "        }\r\n" +
+               "\r\n" +
+               "        $assign_var = $this->_dequote($attrs[\'assign\']);\r\n" +
+               "\r\n" +
+               "               $once_var = ( $attrs[\'once\'] === false ) ? \'false\' : \'true\';\r\n" +
+               "\r\n" +
+               "       foreach($attrs as $arg_name => $arg_value) {\r\n" +
+               "               if($arg_name != \'file\' AND $arg_name != \'once\' AND $arg_name != \'assign\') {\r\n" +
+               "               if(is_bool($arg_value))\r\n" +
+               "                       $arg_value = $arg_value ? \'true\' : \'false\';\r\n" +
+               "               $arg_list[] = \"\'$arg_name\' => $arg_value\";\r\n" +
+               "               }\r\n" +
+               "       }\r\n" +
+               "\r\n" +
+               "       $output =\r\n" +
+               "               \"<?php \\$this->_smarty_include_php($attrs[file], \'$assign_var\', $once_var, \" .\r\n" +
+               "               \"array(\".implode(\',\', (array)$arg_list).\")); ?>\";\r\n" +
+               "                               \r\n" +
+               "               return $output;\r\n" +
+               "    }\r\n" +
+               "       \r\n" +
+               "\r\n" +
+               "       /**\r\n" +
+               "        * Compile {section ...} tag\r\n" +
+               "        *\r\n" +
+               "        * @access public\r\n" +
+               "        * @param  $tag_args\r\n" +
+               "        */\r\n" +
+               "    function _compile_section_start($tag_args)\r\n" +
+               "    {\r\n" +
+               "        $attrs = $this->_parse_attrs($tag_args);\r\n" +
+               "        $arg_list = array();\r\n" +
+               "\r\n" +
+               "        $output = \'<?php \';\r\n" +
+               "        $section_name = $attrs[\'name\']; \r\n" +
+               "        if (empty($section_name)) {\r\n" +
+               "            $this->_syntax_error(\"missing section name\", E_USER_ERROR, __FILE__, __LINE__);\r\n" +
+               "        }\r\n" +
+               "\r\n" +
+               "        $output .= \"if (isset(\\$this->_sections[$section_name])) unset(\\$this->_sections[$section_name]);\\n\";\r\n" +
+               "        $section_props = \"\\$this->_sections[$section_name]\";\r\n" +
+               "\r\n" +
+               "        foreach ($attrs as $attr_name => $attr_value) {\r\n" +
+               "            switch ($attr_name) {\r\n" +
+               "                case \'loop\':\r\n" +
+               "                    $output .= \"{$section_props}[\'loop\'] = is_array($attr_value) ? count($attr_value) : max(0, (int)$attr_value);\\n\";\r\n" +
+               "                    break;\r\n" +
+               "\r\n" +
+               "                case \'show\':\r\n" +
+               "                    if (is_bool($attr_value))\r\n" +
+               "                        $show_attr_value = $attr_value ? \'true\' : \'false\';\r\n" +
+               "                    else\r\n" +
+               "                        $show_attr_value = \"(bool)$attr_value\";\r\n" +
+               "                    $output .= \"{$section_props}[\'show\'] = $show_attr_value;\\n\";\r\n" +
+               "                    break;\r\n" +
+               "\r\n" +
+               "                case \'name\':\r\n" +
+               "                    $output .= \"{$section_props}[\'$attr_name\'] = $attr_value;\\n\";\r\n" +
+               "                    break;\r\n" +
+               "\r\n" +
+               "                case \'max\':\r\n" +
+               "                case \'start\':\r\n" +
+               "                    $output .= \"{$section_props}[\'$attr_name\'] = (int)$attr_value;\\n\";\r\n" +
+               "                    break;\r\n" +
+               "\r\n" +
+               "                case \'step\':\r\n" +
+               "                    $output .= \"{$section_props}[\'$attr_name\'] = ((int)$attr_value) == 0 ? 1 : (int)$attr_value;\\n\";\r\n" +
+               "                    break;\r\n" +
+               "\r\n" +
+               "                default:\r\n" +
+               "                    $this->_syntax_error(\"unknown section attribute - \'$attr_name\'\", E_USER_ERROR, __FILE__, __LINE__);\r\n" +
+               "                    break;\r\n" +
+               "            }\r\n" +
+               "        }\r\n" +
+               "\r\n" +
+               "        if (!isset($attrs[\'show\']))\r\n" +
+               "            $output .= \"{$section_props}[\'show\'] = true;\\n\";\r\n" +
+               "\r\n" +
+               "        if (!isset($attrs[\'loop\']))\r\n" +
+               "            $output .= \"{$section_props}[\'loop\'] = 1;\\n\";\r\n" +
+               "\r\n" +
+               "        if (!isset($attrs[\'max\']))\r\n" +
+               "            $output .= \"{$section_props}[\'max\'] = {$section_props}[\'loop\'];\\n\";\r\n" +
+               "        else\r\n" +
+               "            $output .= \"if ({$section_props}[\'max\'] < 0)\\n\" .\r\n" +
+               "                       \"    {$section_props}[\'max\'] = {$section_props}[\'loop\'];\\n\";\r\n" +
+               "\r\n" +
+               "        if (!isset($attrs[\'step\']))\r\n" +
+               "            $output .= \"{$section_props}[\'step\'] = 1;\\n\";\r\n" +
+               "\r\n" +
+               "        if (!isset($attrs[\'start\']))\r\n" +
+               "            $output .= \"{$section_props}[\'start\'] = {$section_props}[\'step\'] > 0 ? 0 : {$section_props}[\'loop\']-1;\\n\";\r\n" +
+               "        else {\r\n" +
+               "            $output .= \"if ({$section_props}[\'start\'] < 0)\\n\" .\r\n" +
+               "                       \"    {$section_props}[\'start\'] = max({$section_props}[\'step\'] > 0 ? 0 : -1, {$section_props}[\'loop\'] + {$section_props}[\'start\']);\\n\" .\r\n" +
+               "                       \"else\\n\" .\r\n" +
+               "                       \"    {$section_props}[\'start\'] = min({$section_props}[\'start\'], {$section_props}[\'step\'] > 0 ? {$section_props}[\'loop\'] : {$section_props}[\'loop\']-1);\\n\";\r\n" +
+               "        }\r\n" +
+               "\r\n" +
+               "        $output .= \"if ({$section_props}[\'show\']) {\\n\";\r\n" +
+               "        if (!isset($attrs[\'start\']) && !isset($attrs[\'step\']) && !isset($attrs[\'max\'])) {\r\n" +
+               "            $output .= \"    {$section_props}[\'total\'] = {$section_props}[\'loop\'];\\n\";\r\n" +
+               "        } else {\r\n" +
+               "            $output .= \"    {$section_props}[\'total\'] = min(ceil(({$section_props}[\'step\'] > 0 ? {$section_props}[\'loop\'] - {$section_props}[\'start\'] : {$section_props}[\'start\']+1)/abs({$section_props}[\'step\'])), {$section_props}[\'max\']);\\n\";\r\n" +
+               "        }\r\n" +
+               "        $output .= \"    if ({$section_props}[\'total\'] == 0)\\n\" .\r\n" +
+               "                   \"        {$section_props}[\'show\'] = false;\\n\" .\r\n" +
+               "                   \"} else\\n\" .\r\n" +
+               "                   \"    {$section_props}[\'total\'] = 0;\\n\";\r\n" +
+               "\r\n" +
+               "        $output .= \"if ({$section_props}[\'show\']):\\n\";\r\n" +
+               "        $output .= \"\r\n" +
+               "            for ({$section_props}[\'index\'] = {$section_props}[\'start\'], {$section_props}[\'iteration\'] = 1;\r\n" +
+               "                 {$section_props}[\'iteration\'] <= {$section_props}[\'total\'];\r\n" +
+               "                 {$section_props}[\'index\'] += {$section_props}[\'step\'], {$section_props}[\'iteration\']++):\\n\";\r\n" +
+               "        $output .= \"{$section_props}[\'rownum\'] = {$section_props}[\'iteration\'];\\n\";\r\n" +
+               "        $output .= \"{$section_props}[\'index_prev\'] = {$section_props}[\'index\'] - {$section_props}[\'step\'];\\n\";\r\n" +
+               "        $output .= \"{$section_props}[\'index_next\'] = {$section_props}[\'index\'] + {$section_props}[\'step\'];\\n\";\r\n" +
+               "        $output .= \"{$section_props}[\'first\']      = ({$section_props}[\'iteration\'] == 1);\\n\";\r\n" +
+               "        $output .= \"{$section_props}[\'last\']       = ({$section_props}[\'iteration\'] == {$section_props}[\'total\']);\\n\";\r\n" +
+               "\r\n" +
+               "        $output .= \"?>\";\r\n" +
+               "\r\n" +
+               "        return $output;\r\n" +
+               "    }\r\n" +
+               "\r\n" +
+               "    \r\n" +
+               "       /**\r\n" +
+               "        * Compile {foreach ...} tag.\r\n" +
+               "        *\r\n" +
+               "        * @access public\r\n" +
+               "        * @param  $tag_args\r\n" +
+               "        */\r\n" +
+               "    function _compile_foreach_start($tag_args)\r\n" +
+               "    {\r\n" +
+               "        $attrs = $this->_parse_attrs($tag_args);\r\n" +
+               "        $arg_list = array();\r\n" +
+               "\r\n" +
+               "        if (empty($attrs[\'from\'])) {\r\n" +
+               "            $this->_syntax_error(\"missing \'from\' attribute\", E_USER_ERROR, __FILE__, __LINE__);\r\n" +
+               "        }\r\n" +
+               "\r\n" +
+               "        if (empty($attrs[\'item\'])) {\r\n" +
+               "            $this->_syntax_error(\"missing \'item\' attribute\", E_USER_ERROR, __FILE__, __LINE__);\r\n" +
+               "        }\r\n" +
+               "\r\n" +
+               "        $from = $attrs[\'from\'];\r\n" +
+               "        $item = $this->_dequote($attrs[\'item\']);\r\n" +
+               "        if (isset($attrs[\'name\']))\r\n" +
+               "            $name = $attrs[\'name\'];\r\n" +
+               "\r\n" +
+               "        $output = \'<?php \';\r\n" +
+               "        if (isset($name)) {\r\n" +
+               "            $output .= \"if (isset(\\$this->_foreach[$name])) unset(\\$this->_foreach[$name]);\\n\";\r\n" +
+               "            $foreach_props = \"\\$this->_foreach[$name]\";\r\n" +
+               "        }\r\n" +
+               "\r\n" +
+               "        $key_part = \'\';\r\n" +
+               "\r\n" +
+               "        foreach ($attrs as $attr_name => $attr_value) {\r\n" +
+               "            switch ($attr_name) {\r\n" +
+               "                case \'key\':\r\n" +
+               "                    $key  = $this->_dequote($attrs[\'key\']);\r\n" +
+               "                    $key_part = \"\\$this->_tpl_vars[\'$key\'] => \";\r\n" +
+               "                    break;\r\n" +
+               "\r\n" +
+               "                case \'name\':\r\n" +
+               "                    $output .= \"{$foreach_props}[\'$attr_name\'] = $attr_value;\\n\";\r\n" +
+               "                    break;\r\n" +
+               "            }\r\n" +
+               "        }\r\n" +
+               "\r\n" +
+               "        if (isset($name)) {\r\n" +
+               "            $output .= \"{$foreach_props}[\'total\'] = count((array)$from);\\n\";\r\n" +
+               "            $output .= \"{$foreach_props}[\'show\'] = {$foreach_props}[\'total\'] > 0;\\n\";\r\n" +
+               "            $output .= \"if ({$foreach_props}[\'show\']):\\n\";\r\n" +
+               "            $output .= \"{$foreach_props}[\'iteration\'] = 0;\\n\";\r\n" +
+               "            $output .= \"    foreach ((array)$from as $key_part\\$this->_tpl_vars[\'$item\']):\\n\";\r\n" +
+               "            $output .= \"        {$foreach_props}[\'iteration\']++;\\n\";\r\n" +
+               "            $output .= \"        {$foreach_props}[\'first\'] = ({$foreach_props}[\'iteration\'] == 1);\\n\";\r\n" +
+               "            $output .= \"        {$foreach_props}[\'last\']  = ({$foreach_props}[\'iteration\'] == {$foreach_props}[\'total\']);\\n\";\r\n" +
+               "        } else {\r\n" +
+               "            $output .= \"if (count((array)$from)):\\n\";\r\n" +
+               "            $output .= \"    foreach ((array)$from as $key_part\\$this->_tpl_vars[\'$item\']):\\n\";\r\n" +
+               "        }\r\n" +
+               "        $output .= \'?>\';\r\n" +
+               "\r\n" +
+               "        return $output;\r\n" +
+               "    }\r\n" +
+               "\r\n" +
+               "\r\n" +
+               "       /**\r\n" +
+               "        * Compile {capture} .. {/capture} tags\r\n" +
+               "        *\r\n" +
+               "        * @access public\r\n" +
+               "        * @param  $start\r\n" +
+               "        * @param  $tag_args\r\n" +
+               "        */\r\n" +
+               "    function _compile_capture_tag($start, $tag_args = \'\')\r\n" +
+               "    {\r\n" +
+               "        $attrs = $this->_parse_attrs($tag_args);\r\n" +
+               "\r\n" +
+               "        if ($start) {\r\n" +
+               "            if (isset($attrs[\'name\']))\r\n" +
+               "                $buffer = $attrs[\'name\'];\r\n" +
+               "            else\r\n" +
+               "                $buffer = \"\'default\'\";\r\n" +
+               "\r\n" +
+               "            $output = \"<?php ob_start(); ?>\";\r\n" +
+               "            $this->_capture_stack[] = $buffer;\r\n" +
+               "        } else {\r\n" +
+               "            $buffer = array_pop($this->_capture_stack);\r\n" +
+               "            $output = \"<?php \\$this->_smarty_vars[\'capture\'][$buffer] = ob_get_contents(); ob_end_clean(); ?>\";\r\n" +
+               "        }\r\n" +
+               "\r\n" +
+               "        return $output;\r\n" +
+               "    }\r\n" +
+               "\r\n" +
+               "       /**\r\n" +
+               "        * Compile {if ...} tag\r\n" +
+               "        *\r\n" +
+               "        * @access public\r\n" +
+               "        * @param  $tag_args\r\n" +
+               "        * @param  $elseif\r\n" +
+               "        */\r\n" +
+               "    function _compile_if_tag($tag_args, $elseif = false)\r\n" +
+               "    {\r\n" +
+               "\r\n" +
+               "        /* Tokenize args for \'if\' tag. */\r\n" +
+               "        preg_match_all(\'/(?>\r\n" +
+               "                               \' . $this->_obj_call_regexp . \'(?:\' . $this->_mod_regexp . \'*) | # valid object call\r\n" +
+               "                               \' . $this->_var_regexp . \'(?:\' . $this->_mod_regexp . \'*)   | # public or quoted string\r\n" +
+               "                               \\-?\\d+|!==|<=>|==|!=|<=|>=|\\&\\&|\\|\\||\\(|\\)|,|\\!|\\^|=|<|>|\\||\\%|\\+|\\-|\\/|\\*      | # valid non-word token\r\n" +
+               "                               \\b\\w+\\b                                                                                                              | # valid word token\r\n" +
+               "                               \\S+                                                           # anything else\r\n" +
+               "                               )/x\', $tag_args, $match);\r\n" +
+               "                               \r\n" +
+               "        $tokens = $match[0];\r\n" +
+               "               \r\n" +
+               "               // make sure we have balanced parenthesis\r\n" +
+               "               $token_count = array_count_values($tokens);\r\n" +
+               "               if(isset($token_count[\'(\']) && $token_count[\'(\'] != $token_count[\')\']) {\r\n" +
+               "                       $this->_syntax_error(\"unbalanced parenthesis in if statement\", E_USER_ERROR, __FILE__, __LINE__);\r\n" +
+               "               }\r\n" +
+               "                                                                                               \r\n" +
+               "        $is_arg_stack = array();\r\n" +
+               "\r\n" +
+               "        for ($i = 0; $i < count($tokens); $i++) {\r\n" +
+               "\r\n" +
+               "            $token = &$tokens[$i];\r\n" +
+               "                       \r\n" +
+               "            switch (strtolower($token)) {\r\n" +
+               "                case \'!\':\r\n" +
+               "                case \'%\':\r\n" +
+               "                case \'!==\':\r\n" +
+               "                case \'==\':\r\n" +
+               "                case \'>\':\r\n" +
+               "                case \'<\':\r\n" +
+               "                case \'!=\':\r\n" +
+               "                case \'<=\':\r\n" +
+               "                case \'>=\':\r\n" +
+               "                case \'&&\':\r\n" +
+               "                case \'||\':\r\n" +
+               "                               case \'|\':\r\n" +
+               "                               case \'^\':\r\n" +
+               "                               case \'&\':\r\n" +
+               "                               case \'~\':\r\n" +
+               "                               case \')\':\r\n" +
+               "                               case \',\':\r\n" +
+               "                               case \'+\':\r\n" +
+               "                               case \'-\':\r\n" +
+               "                               case \'*\':\r\n" +
+               "                               case \'/\':\r\n" +
+               "                                       break;                                  \r\n" +
+               "\r\n" +
+               "                case \'eq\':\r\n" +
+               "                    $token = \'==\';\r\n" +
+               "                    break;\r\n" +
+               "\r\n" +
+               "                case \'ne\':\r\n" +
+               "                case \'neq\':\r\n" +
+               "                    $token = \'!=\';\r\n" +
+               "                    break;\r\n" +
+               "\r\n" +
+               "                case \'lt\':\r\n" +
+               "                    $token = \'<\';\r\n" +
+               "                    break;\r\n" +
+               "\r\n" +
+               "                case \'le\':\r\n" +
+               "                case \'lte\':\r\n" +
+               "                    $token = \'<=\';\r\n" +
+               "                    break;\r\n" +
+               "\r\n" +
+               "                case \'gt\':\r\n" +
+               "                    $token = \'>\';\r\n" +
+               "                    break;\r\n" +
+               "\r\n" +
+               "                case \'ge\':\r\n" +
+               "                case \'gte\':\r\n" +
+               "                    $token = \'>=\';\r\n" +
+               "                    break;\r\n" +
+               "\r\n" +
+               "                case \'and\':\r\n" +
+               "                    $token = \'&&\';\r\n" +
+               "                    break;\r\n" +
+               "\r\n" +
+               "                case \'or\':\r\n" +
+               "                    $token = \'||\';\r\n" +
+               "                    break;\r\n" +
+               "\r\n" +
+               "                case \'not\':\r\n" +
+               "                    $token = \'!\';\r\n" +
+               "                    break;\r\n" +
+               "\r\n" +
+               "                case \'mod\':\r\n" +
+               "                    $token = \'%\';\r\n" +
+               "                    break;\r\n" +
+               "\r\n" +
+               "                case \'(\':\r\n" +
+               "                    array_push($is_arg_stack, $i);\r\n" +
+               "                    break;\r\n" +
+               "                                       \r\n" +
+               "                case \'is\':\r\n" +
+               "                    /* If last token was a \')\', we operate on the parenthesized\r\n" +
+               "                       expression. The start of the expression is on the stack.\r\n" +
+               "                       Otherwise, we operate on the last encountered token. */\r\n" +
+               "                    if ($tokens[$i-1] == \')\')\r\n" +
+               "                        $is_arg_start = array_pop($is_arg_stack);\r\n" +
+               "                    else\r\n" +
+               "                        $is_arg_start = $i-1;\r\n" +
+               "                    /* Construct the argument for \'is\' expression, so it knows\r\n" +
+               "                       what to operate on. */\r\n" +
+               "                    $is_arg = implode(\' \', array_slice($tokens, $is_arg_start, $i - $is_arg_start));\r\n" +
+               "                                       \r\n" +
+               "                    /* Pass all tokens from next one until the end to the\r\n" +
+               "                       \'is\' expression parsing function. The function will\r\n" +
+               "                       return modified tokens, where the first one is the result\r\n" +
+               "                       of the \'is\' expression and the rest are the tokens it\r\n" +
+               "                       didn\'t touch. */                                       \r\n" +
+               "                    $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1));\r\n" +
+               "                                                                               \r\n" +
+               "                    /* Replace the old tokens with the new ones. */\r\n" +
+               "                    array_splice($tokens, $is_arg_start, count($tokens), $new_tokens);\r\n" +
+               "\r\n" +
+               "                    /* Adjust argument start so that it won\'t change from the\r\n" +
+               "                       current position for the next iteration. */\r\n" +
+               "                    $i = $is_arg_start;\r\n" +
+               "                    break;\r\n" +
+               "                                       \r\n" +
+               "                default:\r\n" +
+               "                                       if(preg_match(\'!^\' . $this->_func_regexp . \'$!\', $token) ) {\r\n" +
+               "                                                       // function call        \r\n" +
+               "                               if($this->security &&\r\n" +
+               "                                  !in_array($token, $this->security_settings[\'IF_FUNCS\'])) {\r\n" +
+               "                                       $this->_syntax_error(\"(secure mode) \'$token\' not allowed in if statement\", E_USER_ERROR, __FILE__, __LINE__);\r\n" +
+               "                                                       }                                                       \r\n" +
+               "                                       } elseif(preg_match(\'!^\' . $this->_var_regexp . \'(?:\' . $this->_mod_regexp . \'*)$!\', $token)) {\r\n" +
+               "                                               // variable\r\n" +
+               "                                       $token = $this->_parse_var_props($token);\r\n" +
+               "                                       } elseif(preg_match(\'!^\' . $this->_obj_call_regexp . \'(?:\' . $this->_mod_regexp . \'*)$!\', $token)) {\r\n" +
+               "                                               // object\r\n" +
+               "                                       $token = $this->_parse_var_props($token);\r\n" +
+               "                                       } elseif(is_numeric($token)) {\r\n" +
+               "                                               // number, skip it\r\n" +
+               "                                       } else {\r\n" +
+               "                               $this->_syntax_error(\"unidentified token \'$token\'\", E_USER_ERROR, __FILE__, __LINE__);\r\n" +
+               "                                       }\r\n" +
+               "                    break;\r\n" +
+               "            }\r\n" +
+               "        }\r\n" +
+               "                               \r\n" +
+               "        if ($elseif)\r\n" +
+               "            return \'<?php elseif (\'.implode(\' \', $tokens).\'): ?>\';\r\n" +
+               "        else\r\n" +
+               "            return \'<?php if (\'.implode(\' \', $tokens).\'): ?>\';\r\n" +
+               "    }\r\n" +
+               "\r\n" +
+               "\r\n" +
+               "       /**\r\n" +
+               "        * Parse is expression\r\n" +
+               "        *\r\n" +
+               "        * @access public\r\n" +
+               "        * @param  $is_arg\r\n" +
+               "        * @param  $tokens\r\n" +
+               "        */\r\n" +
+               "    function _parse_is_expr($is_arg, $tokens)\r\n" +
+               "    {\r\n" +
+               "        $expr_end = 0;\r\n" +
+               "        $negate_expr = false;\r\n" +
+               "\r\n" +
+               "        if (($first_token = array_shift($tokens)) == \'not\') {\r\n" +
+               "            $negate_expr = true;\r\n" +
+               "            $expr_type = array_shift($tokens);\r\n" +
+               "        } else\r\n" +
+               "            $expr_type = $first_token;\r\n" +
+               "\r\n" +
+               "        switch ($expr_type) {\r\n" +
+               "            case \'even\':\r\n" +
+               "                if (@$tokens[$expr_end] == \'by\') {\r\n" +
+               "                    $expr_end++;\r\n" +
+               "                    $expr_arg = $tokens[$expr_end++];\r\n" +
+               "                    $expr = \"!(($is_arg / $expr_arg) % \" . $this->_parse_var_props($expr_arg) . \")\";\r\n" +
+               "                } else\r\n" +
+               "                    $expr = \"!($is_arg % 2)\";\r\n" +
+               "                break;\r\n" +
+               "\r\n" +
+               "            case \'odd\':\r\n" +
+               "                if (@$tokens[$expr_end] == \'by\') {\r\n" +
+               "                    $expr_end++;\r\n" +
+               "                    $expr_arg = $tokens[$expr_end++];\r\n" +
+               "                    $expr = \"(($is_arg / $expr_arg) % \". $this->_parse_var_props($expr_arg) . \")\";\r\n" +
+               "                } else\r\n" +
+               "                    $expr = \"($is_arg % 2)\";\r\n" +
+               "                break;\r\n" +
+               "\r\n" +
+               "            case \'div\':\r\n" +
+               "                if (@$tokens[$expr_end] == \'by\') {\r\n" +
+               "                    $expr_end++;\r\n" +
+               "                    $expr_arg = $tokens[$expr_end++];\r\n" +
+               "                    $expr = \"!($is_arg % \" . $this->_parse_var_props($expr_arg) . \")\";\r\n" +
+               "                } else {\r\n" +
+               "                    $this->_syntax_error(\"expecting \'by\' after \'div\'\", E_USER_ERROR, __FILE__, __LINE__);\r\n" +
+               "                }\r\n" +
+               "                break;\r\n" +
+               "\r\n" +
+               "            default:\r\n" +
+               "                $this->_syntax_error(\"unknown \'is\' expression - \'$expr_type\'\", E_USER_ERROR, __FILE__, __LINE__);\r\n" +
+               "                break;\r\n" +
+               "        }\r\n" +
+               "\r\n" +
+               "        if ($negate_expr) {\r\n" +
+               "            $expr = \"!($expr)\";\r\n" +
+               "        }\r\n" +
+               "               \r\n" +
+               "        array_splice($tokens, 0, $expr_end, $expr);            \r\n" +
+               "               \r\n" +
+               "        return $tokens;\r\n" +
+               "    }\r\n" +
+               "\r\n" +
+               "\r\n" +
+               "       /**\r\n" +
+               "        * Parse attribute string\r\n" +
+               "        *\r\n" +
+               "        * @access public\r\n" +
+               "        * @param  $tag_args\r\n" +
+               "        * @param  $quote\r\n" +
+               "        */\r\n" +
+               "    function _parse_attrs($tag_args, $quote = true)\r\n" +
+               "    {\r\n" +
+               "                               \r\n" +
+               "        /* Tokenize tag attributes. */\r\n" +
+               "        preg_match_all(\'/(?:\' . $this->_obj_call_regexp . \'|\' . $this->_qstr_regexp . \' | (?>[^\"\\\'=\\s]+)\r\n" +
+               "                         )+ |\r\n" +
+               "                         [=]\r\n" +
+               "                        /x\', $tag_args, $match);\r\n" +
+               "        $tokens       = $match[0];             \r\n" +
+               "                               \r\n" +
+               "        $attrs = array();\r\n" +
+               "        /* Parse state:\r\n" +
+               "            0 - expecting attribute name\r\n" +
+               "            1 - expecting \'=\'\r\n" +
+               "            2 - expecting attribute value (not \'=\') */\r\n" +
+               "        $state = 0;\r\n" +
+               "                               \r\n" +
+               "        foreach ($tokens as $token) {\r\n" +
+               "            switch ($state) {\r\n" +
+               "                case 0:\r\n" +
+               "                    /* If the token is a valid identifier, we set attribute name\r\n" +
+               "                       and go to state 1. */\r\n" +
+               "                    if (preg_match(\'!^\\w+$!\', $token)) {\r\n" +
+               "                        $attr_name = $token;\r\n" +
+               "                        $state = 1;\r\n" +
+               "                    } else\r\n" +
+               "                        $this->_syntax_error(\"invalid attribute name - \'$token\'\", E_USER_ERROR, __FILE__, __LINE__);\r\n" +
+               "                    break;\r\n" +
+               "\r\n" +
+               "                case 1:\r\n" +
+               "                    /* If the token is \'=\', then we go to state 2. */\r\n" +
+               "                    if ($token == \'=\') {\r\n" +
+               "                        $state = 2;\r\n" +
+               "                    } else\r\n" +
+               "                        $this->_syntax_error(\"expecting \'=\' after attribute name \'$last_token\'\", E_USER_ERROR, __FILE__, __LINE__);\r\n" +
+               "                    break;\r\n" +
+               "\r\n" +
+               "                case 2:\r\n" +
+               "                    /* If token is not \'=\', we set the attribute value and go to\r\n" +
+               "                       state 0. */\r\n" +
+               "                    if ($token != \'=\') {\r\n" +
+               "                        /* We booleanize the token if it\'s a non-quoted possible\r\n" +
+               "                           boolean value. */\r\n" +
+               "                        if (preg_match(\'!^(on|yes|true)$!\', $token))\r\n" +
+               "                            $token = true;\r\n" +
+               "                        else if (preg_match(\'!^(off|no|false)$!\', $token))\r\n" +
+               "                            $token = false;\r\n" +
+               "                        /* If the token is just a string,\r\n" +
+               "                           we double-quote it. */\r\n" +
+               "                        else if (preg_match(\'!^\\w+$!\', $token)) {\r\n" +
+               "                            $token = \'\"\'.$token.\'\"\';\r\n" +
+               "                                               }\r\n" +
+               "\r\n" +
+               "                        $attrs[$attr_name] = $token;\r\n" +
+               "                        $state = 0;\r\n" +
+               "                    } else\r\n" +
+               "                        $this->_syntax_error(\"\'=\' cannot be an attribute value\", E_USER_ERROR, __FILE__, __LINE__);\r\n" +
+               "                    break;\r\n" +
+               "            }\r\n" +
+               "                       $last_token = $token;\r\n" +
+               "        }\r\n" +
+               "\r\n" +
+               "               if($state != 0) {\r\n" +
+               "                       if($state == 1) {\r\n" +
+               "                               $this->_syntax_error(\"expecting \'=\' after attribute name \'$last_token\'\", E_USER_ERROR, __FILE__, __LINE__);                               \r\n" +
+               "                       } else {\r\n" +
+               "                               $this->_syntax_error(\"missing attribute value\", E_USER_ERROR, __FILE__, __LINE__);                                                            \r\n" +
+               "                       }\r\n" +
+               "               }\r\n" +
+               "               \r\n" +
+               "        $this->_parse_vars_props($attrs);\r\n" +
+               "\r\n" +
+               "        return $attrs;\r\n" +
+               "    }\r\n" +
+               "\r\n" +
+               "       /**\r\n" +
+               "        * compile multiple variables and section properties tokens into\r\n" +
+               "        * PHP code\r\n" +
+               "        *\r\n" +
+               "        * @access public\r\n" +
+               "        * @param  $tokens\r\n" +
+               "        */\r\n" +
+               "    function _parse_vars_props(&$tokens)\r\n" +
+               "    {\r\n" +
+               "               foreach($tokens as $key => $val) {                      \r\n" +
+               "               $tokens[$key] = $this->_parse_var_props($val);\r\n" +
+               "               }\r\n" +
+               "       }\r\n" +
+               "               \r\n" +
+               "       /**\r\n" +
+               "        * compile single variable and section properties token into\r\n" +
+               "        * PHP code\r\n" +
+               "        *\r\n" +
+               "        * @access public\r\n" +
+               "        * @param  $val\r\n" +
+               "        * @param  $tag_attrs\r\n" +
+               "        */\r\n" +
+               "    function _parse_var_props($val, $tag_attrs = null)\r\n" +
+               "    {                                  \r\n" +
+               "\r\n" +
+               "               $val = trim($val);\r\n" +
+               "\r\n" +
+               "        if(preg_match(\'!^(\' . $this->_obj_call_regexp . \'|\' . $this->_dvar_regexp . \')(?:\' . $this->_mod_regexp . \'*)$!\', $val)) {\r\n" +
+               "                               // $ variable or object\r\n" +
+               "                return $this->_parse_var($val, $tag_attrs);\r\n" +
+               "                       }                       \r\n" +
+               "        elseif(preg_match(\'!^\' . $this->_db_qstr_regexp . \'(?:\' . $this->_mod_regexp . \'*)$!\', $val)) {\r\n" +
+               "                               // double quoted text\r\n" +
+               "                               preg_match(\'!^(\' . $this->_db_qstr_regexp . \')(\'. $this->_mod_regexp . \'*)$!\', $val, $match);\r\n" +
+               "                $return = $this->_expand_quoted_text($match[1]);\r\n" +
+               "                               if($match[2] != \'\') {\r\n" +
+               "                                       $this->_parse_modifiers($return, $match[2]);\r\n" +
+               "                               }\r\n" +
+               "                               return $return;\r\n" +
+               "                       }                       \r\n" +
+               "        elseif(preg_match(\'!^\' . $this->_si_qstr_regexp . \'(?:\' . $this->_mod_regexp . \'*)$!\', $val)) {\r\n" +
+               "                               // single quoted text\r\n" +
+               "                               preg_match(\'!^(\' . $this->_si_qstr_regexp . \')(\'. $this->_mod_regexp . \'*)$!\', $val, $match);\r\n" +
+               "                               if($match[2] != \'\') {\r\n" +
+               "                                       $this->_parse_modifiers($match[1], $match[2]);\r\n" +
+               "                       return $match[1];\r\n" +
+               "                               }       \r\n" +
+               "                       }                       \r\n" +
+               "        elseif(preg_match(\'!^\' . $this->_cvar_regexp . \'(?:\' . $this->_mod_regexp . \'*)$!\', $val)) {\r\n" +
+               "                               // config var\r\n" +
+               "                return $this->_parse_conf_var($val);\r\n" +
+               "                       }                       \r\n" +
+               "        elseif(preg_match(\'!^\' . $this->_svar_regexp . \'(?:\' . $this->_mod_regexp . \'*)$!\', $val)) {\r\n" +
+               "                               // section var\r\n" +
+               "                return $this->_parse_section_prop($val);\r\n" +
+               "                       }\r\n" +
+               "               elseif(!in_array($val, $this->_permitted_tokens) && !is_numeric($val)) {\r\n" +
+               "                       // literal string\r\n" +
+               "                       return $this->_expand_quoted_text(\'\"\' . $val .\'\"\');\r\n" +
+               "               }\r\n" +
+               "               return $val;\r\n" +
+               "    }\r\n" +
+               "\r\n" +
+               "       /**\r\n" +
+               "        * expand quoted text with embedded variables\r\n" +
+               "        *\r\n" +
+               "        * @access public\r\n" +
+               "        * @param  $var_expr\r\n" +
+               "        */\r\n" +
+               "    function _expand_quoted_text($var_expr)\r\n" +
+               "    {\r\n" +
+               "               // if contains unescaped $, expand it\r\n" +
+               "               if(preg_match_all(\'|(?<!\\\\\\\\)\\$\' . $this->_dvar_guts_regexp . \'|\', $var_expr, $match)) {\r\n" +
+               "                       rsort($match[0]);\r\n" +
+               "                       reset($match[0]);\r\n" +
+               "                       foreach($match[0] as $var) {\r\n" +
+               "                $var_expr = str_replace ($var, \'\".\' . $this->_parse_var($var) . \'.\"\', $var_expr);\r\n" +
+               "                       }\r\n" +
+               "            return preg_replace(\'!\\.\"\"|\"\"\\.!\', \'\', $var_expr);\r\n" +
+               "               } else {\r\n" +
+               "                       return $var_expr;\r\n" +
+               "               }\r\n" +
+               "       }\r\n" +
+               "       \r\n" +
+               "       /**\r\n" +
+               "        * parse variable expression into PHP code\r\n" +
+               "        *\r\n" +
+               "        * @access public\r\n" +
+               "        * @param  $var_expr\r\n" +
+               "        */\r\n" +
+               "    function _parse_var($var_expr)\r\n" +
+               "    {\r\n" +
+               "                               \r\n" +
+               "               preg_match(\'!(\' . $this->_obj_call_regexp . \'|\' . $this->_var_regexp . \')(\' . $this->_mod_regexp . \'*)$!\', $var_expr, $match);\r\n" +
+               "                               \r\n" +
+               "        $var_ref = substr($match[1],1);\r\n" +
+               "        $modifiers = $match[2];\r\n" +
+               "                                               \r\n" +
+               "               if(!empty($this->default_modifiers) && !preg_match(\'!(^|\\|)smarty:nodefaults($|\\|)!\',$modifiers)) {\r\n" +
+               "                       $_default_mod_string = implode(\'|\',(array)$this->default_modifiers);\r\n" +
+               "                       $modifiers = empty($modifiers) ? $_default_mod_string : $_default_mod_string . \'|\' . $modifiers;\r\n" +
+               "               }\r\n" +
+               "\r\n" +
+               "               // get [foo] and .foo and ->foo() pieces                        \r\n" +
+               "        preg_match_all(\'!(?:^\\w+)|(?:\' . $this->_obj_ext_regexp . \')+(?:\' . $this->_obj_params_regexp . \')?|(?:\' . $this->_var_bracket_regexp . \')|\\.\\$?\\w+!\', $var_ref, $match);          \r\n" +
+               "               \r\n" +
+               "        $indexes = $match[0];\r\n" +
+               "        $var_name = array_shift($indexes);\r\n" +
+               "                               \r\n" +
+               "        /* Handle $smarty.* variable references as a special case. */\r\n" +
+               "        if ($var_name == \'smarty\') {\r\n" +
+               "            /*\r\n" +
+               "             * If the reference could be compiled, use the compiled output;\r\n" +
+               "             * otherwise, fall back on the $smarty variable generated at\r\n" +
+               "             * run-time.\r\n" +
+               "             */\r\n" +
+               "            if (($smarty_ref = $this->_compile_smarty_ref($indexes)) !== null) {\r\n" +
+               "                $output = $smarty_ref;\r\n" +
+               "            } else {\r\n" +
+               "                $var_name = substr(array_shift($indexes), 1);\r\n" +
+               "                $output = \"\\$this->_smarty_vars[\'$var_name\']\";\r\n" +
+               "            }\r\n" +
+               "        } else {\r\n" +
+               "            $output = \"\\$this->_tpl_vars[\'$var_name\']\";\r\n" +
+               "        }\r\n" +
+               "\r\n" +
+               "        foreach ($indexes as $index) {                 \r\n" +
+               "            if ($index{0} == \'[\') {\r\n" +
+               "                $index = substr($index, 1, -1);\r\n" +
+               "                if (is_numeric($index)) {\r\n" +
+               "                    $output .= \"[$index]\";\r\n" +
+               "                } elseif ($index{0} == \'$\') {\r\n" +
+               "                    $output .= \"[\\$this->_tpl_vars[\'\" . substr($index, 1) . \"\']]\";\r\n" +
+               "                } else {\r\n" +
+               "                    $parts = explode(\'.\', $index);\r\n" +
+               "                    $section = $parts[0];\r\n" +
+               "                    $section_prop = isset($parts[1]) ? $parts[1] : \'index\';\r\n" +
+               "                    $output .= \"[\\$this->_sections[\'$section\'][\'$section_prop\']]\";\r\n" +
+               "                }\r\n" +
+               "            } else if ($index{0} == \'.\') {\r\n" +
+               "                if ($index{1} == \'$\')\r\n" +
+               "                    $output .= \"[\\$this->_tpl_vars[\'\" . substr($index, 2) . \"\']]\";\r\n" +
+               "                else\r\n" +
+               "                    $output .= \"[\'\" . substr($index, 1) . \"\']\";\r\n" +
+               "            } else if (substr($index,0,2) == \'->\') {\r\n" +
+               "                               if(substr($index,2,2) == \'__\') {\r\n" +
+               "                                       $this->_syntax_error(\'call to internal object members is not allowed\', E_USER_ERROR, __FILE__, __LINE__);\r\n" +
+               "                               } elseif($this->security && substr($index,2,1) == \'_\') {\r\n" +
+               "                                       $this->_syntax_error(\'(secure) call to private object member is not allowed\', E_USER_ERROR, __FILE__, __LINE__);\r\n" +
+               "                               } else {\r\n" +
+               "                                       if(preg_match(\'!((?:\' . $this->_obj_ext_regexp . \')+)(\' . $this->_obj_params_regexp . \')?!\', $index, $match)) {\r\n" +
+               "                                               if(!empty($match[2])) {\r\n" +
+               "                                                       // parse object parameters\r\n" +
+               "                                                       $index = str_replace($match[2], $this->_parse_parenth_args($match[2]), $index);\r\n" +
+               "                                               }\r\n" +
+               "                                               if(preg_match_all(\'!\' . $this->_dvar_regexp . \'!\', $match[1], $_dvar_match)) {\r\n" +
+               "                                                       // parse embedded variables\r\n" +
+               "                                                       $_match_replace = $match[1];\r\n" +
+               "                                                       foreach($_dvar_match[0] as $_curr_var) {\r\n" +
+               "                                                               $_match_replace = str_replace($_curr_var, \'{\' . $this->_parse_var($_curr_var) . \'}\', $_match_replace);\r\n" +
+               "                                                       }\r\n" +
+               "                                                       $index = str_replace($match[1], $_match_replace, $index);\r\n" +
+               "                                               }\r\n" +
+               "                                       }\r\n" +
+               "                                       $output .= $index;\r\n" +
+               "                               }\r\n" +
+               "            } else {\r\n" +
+               "                $output .= $index;\r\n" +
+               "            }\r\n" +
+               "        }\r\n" +
+               "\r\n" +
+               "               // look for variables imbedded in quoted strings, replace them\r\n" +
+               "        if(preg_match(\'!\' . $this->_qstr_regexp . \'!\', $output, $match)) {\r\n" +
+               "                       $output = str_replace($match[0], $this->_expand_quoted_text($match[0]), $output);\r\n" +
+               "               }\r\n" +
+               "               \r\n" +
+               "        $this->_parse_modifiers($output, $modifiers);\r\n" +
+               "\r\n" +
+               "        return $output;\r\n" +
+               "    }\r\n" +
+               "\r\n" +
+               "       /**\r\n" +
+               "        * parse arguments in function call parenthesis\r\n" +
+               "        *\r\n" +
+               "        * @access public\r\n" +
+               "        * @param  $parenth_args\r\n" +
+               "        */\r\n" +
+               "    function _parse_parenth_args($parenth_args)\r\n" +
+               "    {\r\n" +
+               "               preg_match_all(\'!\' . $this->_param_regexp . \'!\',$parenth_args, $match);\r\n" +
+               "               $match = $match[0];\r\n" +
+               "               rsort($match);\r\n" +
+               "               reset($match);                                          \r\n" +
+               "               $orig_vals = $match;\r\n" +
+               "               $this->_parse_vars_props($match);\r\n" +
+               "               return str_replace($orig_vals, $match, $parenth_args);\r\n" +
+               "       }       \r\n" +
+               "               \r\n" +
+               "       /**\r\n" +
+               "        * parse configuration variable expression into PHP code\r\n" +
+               "        *\r\n" +
+               "        * @access public\r\n" +
+               "        * @param  $conf_var_expr\r\n" +
+               "        */\r\n" +
+               "    function _parse_conf_var($conf_var_expr)\r\n" +
+               "    {\r\n" +
+               "        $parts = explode(\'|\', $conf_var_expr, 2);\r\n" +
+               "        $var_ref = $parts[0];\r\n" +
+               "        $modifiers = isset($parts[1]) ? $parts[1] : \'\';\r\n" +
+               "\r\n" +
+               "        $var_name = substr($var_ref, 1, -1);\r\n" +
+               "\r\n" +
+               "        $output = \"\\$this->_config[0][\'vars\'][\'$var_name\']\";\r\n" +
+               "\r\n" +
+               "        $this->_parse_modifiers($output, $modifiers);\r\n" +
+               "\r\n" +
+               "        return $output;\r\n" +
+               "    }\r\n" +
+               "\r\n" +
+               "\r\n" +
+               "       /**\r\n" +
+               "        * parse section property expression into PHP code\r\n" +
+               "        *\r\n" +
+               "        * @access public\r\n" +
+               "        * @param  $section_prop_expr\r\n" +
+               "        */\r\n" +
+               "    function _parse_section_prop($section_prop_expr)\r\n" +
+               "    {\r\n" +
+               "        $parts = explode(\'|\', $section_prop_expr, 2);\r\n" +
+               "        $var_ref = $parts[0];\r\n" +
+               "        $modifiers = isset($parts[1]) ? $parts[1] : \'\';\r\n" +
+               "\r\n" +
+               "        preg_match(\'!%(\\w+)\\.(\\w+)%!\', $var_ref, $match);\r\n" +
+               "        $section_name = $match[1];\r\n" +
+               "        $prop_name = $match[2];\r\n" +
+               "\r\n" +
+               "        $output = \"\\$this->_sections[\'$section_name\'][\'$prop_name\']\";\r\n" +
+               "\r\n" +
+               "        $this->_parse_modifiers($output, $modifiers);\r\n" +
+               "\r\n" +
+               "        return $output;\r\n" +
+               "    }\r\n" +
+               "\r\n" +
+               "\r\n" +
+               "       /**\r\n" +
+               "        * parse modifier chain into PHP code\r\n" +
+               "        *\r\n" +
+               "        * @access public\r\n" +
+               "        * @param  $output\r\n" +
+               "        * @param  $modifier_string\r\n" +
+               "        */\r\n" +
+               "    function _parse_modifiers(&$output, $modifier_string)\r\n" +
+               "    {\r\n" +
+               "        preg_match_all(\'!\\|(@?\\w+)((?>:(?:\'. $this->_qstr_regexp . \'|[^|]+))*)!\', \'|\' . $modifier_string, $match);\r\n" +
+               "        list(, $modifiers, $modifier_arg_strings) = $match;\r\n" +
+               "\r\n" +
+               "        for ($i = 0, $for_max = count($modifiers); $i < $for_max; $i++) {\r\n" +
+               "            $modifier_name = $modifiers[$i];\r\n" +
+               "                       \r\n" +
+               "                       if($modifier_name == \'smarty\') {\r\n" +
+               "                               // skip smarty modifier\r\n" +
+               "                               continue;\r\n" +
+               "                       }\r\n" +
+               "                       \r\n" +
+               "            preg_match_all(\'!:(\' . $this->_qstr_regexp . \'|[^:]+)!\', $modifier_arg_strings[$i], $match);\r\n" +
+               "            $modifier_args = $match[1];\r\n" +
+               "\r\n" +
+               "            if ($modifier_name{0} == \'@\') {\r\n" +
+               "                $map_array = \'false\';\r\n" +
+               "                $modifier_name = substr($modifier_name, 1);\r\n" +
+               "            } else {\r\n" +
+               "                $map_array = \'true\';\r\n" +
+               "            }\r\n" +
+               "                       \r\n" +
+               "            $this->_add_plugin(\'modifier\', $modifier_name);\r\n" +
+               "\r\n" +
+               "            $this->_parse_vars_props($modifier_args);\r\n" +
+               "\r\n" +
+               "            if (count($modifier_args) > 0)\r\n" +
+               "                $modifier_args = \', \'.implode(\', \', $modifier_args);\r\n" +
+               "            else\r\n" +
+               "                $modifier_args = \'\';\r\n" +
+               "\r\n" +
+               "            $output = \"\\$this->_run_mod_handler(\'$modifier_name\', $map_array, $output$modifier_args)\";\r\n" +
+               "        }\r\n" +
+               "    }\r\n" +
+               "\r\n" +
+               "\r\n" +
+               "       /**\r\n" +
+               "        * add plugin\r\n" +
+               "        *\r\n" +
+               "        * @access public\r\n" +
+               "        * @param  $type\r\n" +
+               "        * @param  $name\r\n" +
+               "        * @param  $delayed_loading\r\n" +
+               "        */\r\n" +
+               "    function _add_plugin($type, $name, $delayed_loading = null)\r\n" +
+               "    {\r\n" +
+               "        if (!isset($this->_plugin_info[$type])) {\r\n" +
+               "            $this->_plugin_info[$type] = array();\r\n" +
+               "        }\r\n" +
+               "        if (!isset($this->_plugin_info[$type][$name])) {\r\n" +
+               "            $this->_plugin_info[$type][$name] = array($this->_current_file,\r\n" +
+               "                                                      $this->_current_line_no,\r\n" +
+               "                                                      $delayed_loading);\r\n" +
+               "        }\r\n" +
+               "    }\r\n" +
+               "    \r\n" +
+               "\r\n" +
+               "       /**\r\n" +
+               "        * Compiles references of type $smarty.foo\r\n" +
+               "        *\r\n" +
+               "        * @access public\r\n" +
+               "        * @param  $indexes\r\n" +
+               "        */\r\n" +
+               "    function _compile_smarty_ref(&$indexes)\r\n" +
+               "    {\r\n" +
+               "        /* Extract the reference name. */\r\n" +
+               "        $ref = substr($indexes[0], 1);\r\n" +
+               "\r\n" +
+               "        switch ($ref) {\r\n" +
+               "            case \'now\':\r\n" +
+               "                $compiled_ref = \'time()\';\r\n" +
+               "                if (count($indexes) > 1) {\r\n" +
+               "                    $this->_syntax_error(\'$smarty\' . implode(\'\', $indexes) .\' is an invalid reference\', E_USER_ERROR, __FILE__, __LINE__);\r\n" +
+               "                }\r\n" +
+               "                break;\r\n" +
+               "\r\n" +
+               "            case \'foreach\':\r\n" +
+               "            case \'section\':\r\n" +
+               "                if ($indexes[1]{0} != \'.\') {\r\n" +
+               "                    $this->_syntax_error(\'$smarty\' . implode(\'\', array_slice($indexes, 0, 2)) . \' is an invalid reference\', E_USER_ERROR, __FILE__, __LINE__);\r\n" +
+               "                }\r\n" +
+               "                $name = substr($indexes[1], 1);\r\n" +
+               "                array_shift($indexes);\r\n" +
+               "                if ($ref == \'foreach\')\r\n" +
+               "                    $compiled_ref = \"\\$this->_foreach[\'$name\']\";\r\n" +
+               "                else\r\n" +
+               "                    $compiled_ref = \"\\$this->_sections[\'$name\']\";\r\n" +
+               "                break;\r\n" +
+               "\r\n" +
+               "            case \'get\':\r\n" +
+               "                array_shift($indexes);\r\n" +
+               "                $compiled_ref = \"\\$_GET\";\r\n" +
+               "                if ($name = substr($indexes[0], 1))\r\n" +
+               "                    $compiled_ref .= \"[\'$name\']\";\r\n" +
+               "                break;\r\n" +
+               "\r\n" +
+               "            case \'post\':\r\n" +
+               "                array_shift($indexes);\r\n" +
+               "                $name = substr($indexes[0], 1);\r\n" +
+               "                $compiled_ref = \"\\$_POST\";\r\n" +
+               "                if ($name = substr($indexes[0], 1))\r\n" +
+               "                    $compiled_ref .= \"[\'$name\']\";\r\n" +
+               "                break;\r\n" +
+               "\r\n" +
+               "            case \'cookies\':\r\n" +
+               "                array_shift($indexes);\r\n" +
+               "                $name = substr($indexes[0], 1);\r\n" +
+               "                $compiled_ref = \"\\$_COOKIE\";\r\n" +
+               "                if ($name = substr($indexes[0], 1))\r\n" +
+               "                    $compiled_ref .= \"[\'$name\']\";\r\n" +
+               "                break;\r\n" +
+               "\r\n" +
+               "            case \'env\':\r\n" +
+               "                array_shift($indexes);\r\n" +
+               "                $compiled_ref = \"\\$_ENV\";\r\n" +
+               "                if ($name = substr($indexes[0], 1))\r\n" +
+               "                    $compiled_ref .= \"[\'$name\']\";\r\n" +
+               "                break;\r\n" +
+               "\r\n" +
+               "            case \'server\':\r\n" +
+               "                array_shift($indexes);\r\n" +
+               "                $name = substr($indexes[0], 1);\r\n" +
+               "                $compiled_ref = \"\\$_SERVER\";\r\n" +
+               "                if ($name = substr($indexes[0], 1))\r\n" +
+               "                    $compiled_ref .= \"[\'$name\']\";\r\n" +
+               "                break;\r\n" +
+               "\r\n" +
+               "            case \'session\':\r\n" +
+               "                array_shift($indexes);\r\n" +
+               "                $name = substr($indexes[0], 1);\r\n" +
+               "                $compiled_ref = \"\\$_SESSION\";\r\n" +
+               "                if ($name = substr($indexes[0], 1))\r\n" +
+               "                    $compiled_ref .= \"[\'$name\']\";\r\n" +
+               "                break;\r\n" +
+               "\r\n" +
+               "            /*\r\n" +
+               "             * These cases are handled either at run-time or elsewhere in the\r\n" +
+               "             * compiler.\r\n" +
+               "             */\r\n" +
+               "            case \'request\':\r\n" +
+               "                $this->_init_smarty_vars = true;\r\n" +
+               "                return null;\r\n" +
+               "\r\n" +
+               "            case \'capture\':\r\n" +
+               "                return null;\r\n" +
+               "\r\n" +
+               "            case \'template\':\r\n" +
+               "                $compiled_ref = \"\'$this->_current_file\'\";\r\n" +
+               "                if (count($indexes) > 1) {\r\n" +
+               "                    $this->_syntax_error(\'$smarty\' . implode(\'\', $indexes) .\' is an invalid reference\', E_USER_ERROR, __FILE__, __LINE__);\r\n" +
+               "                }\r\n" +
+               "                break;\r\n" +
+               "                               \r\n" +
+               "                       case \'version\':\r\n" +
+               "                               $compiled_ref = \"\'$this->_version\'\";\r\n" +
+               "                               break;\r\n" +
+               "\r\n" +
+               "                       case \'const\':\r\n" +
+               "                array_shift($indexes);\r\n" +
+               "                               $compiled_ref = \'defined(\\\'\' . substr($indexes[0],1) . \'\\\') ? \' . substr($indexes[0],1) . \' : null\';\r\n" +
+               "                break;\r\n" +
+               "\r\n" +
+               "            default:\r\n" +
+               "                $this->_syntax_error(\'$smarty.\' . $ref . \' is an unknown reference\', E_USER_ERROR, __FILE__, __LINE__);\r\n" +
+               "                break;\r\n" +
+               "        }\r\n" +
+               "\r\n" +
+               "        array_shift($indexes);\r\n" +
+               "        return $compiled_ref;\r\n" +
+               "    }\r\n" +
+               "\r\n" +
+               "\r\n" +
+               "       /**\r\n" +
+               "        * load pre- and post-filters\r\n" +
+               "        *\r\n" +
+               "        * @access public\r\n" +
+               "        */\r\n" +
+               "    function _load_filters()\r\n" +
+               "    {\r\n" +
+               "        if (count($this->_plugins[\'prefilter\']) > 0) {\r\n" +
+               "            foreach ($this->_plugins[\'prefilter\'] as $filter_name => $prefilter) {\r\n" +
+               "                if ($prefilter === false) {\r\n" +
+               "                    unset($this->_plugins[\'prefilter\'][$filter_name]);\r\n" +
+               "                    $this->_load_plugins(array(array(\'prefilter\', $filter_name, null, null, false)));\r\n" +
+               "                }\r\n" +
+               "            }\r\n" +
+               "        }\r\n" +
+               "        if (count($this->_plugins[\'postfilter\']) > 0) {\r\n" +
+               "            foreach ($this->_plugins[\'postfilter\'] as $filter_name => $postfilter) {\r\n" +
+               "                if ($postfilter === false) {\r\n" +
+               "                    unset($this->_plugins[\'postfilter\'][$filter_name]);\r\n" +
+               "                    $this->_load_plugins(array(array(\'postfilter\', $filter_name, null, null, false)));\r\n" +
+               "                }\r\n" +
+               "            }\r\n" +
+               "        }\r\n" +
+               "    }\r\n" +
+               "\r\n" +
+               "\r\n" +
+               "       /**\r\n" +
+               "        * display Smarty syntax error\r\n" +
+               "        *\r\n" +
+               "        * @access public\r\n" +
+               "        * @param  $error_msg\r\n" +
+               "        * @param  $error_type\r\n" +
+               "        * @param  $file\r\n" +
+               "        * @param  $line\r\n" +
+               "        */\r\n" +
+               "    function _syntax_error($error_msg, $error_type = E_USER_ERROR, $file=null, $line=null)\r\n" +
+               "    {\r\n" +
+               "               if(isset($file) && isset($line)) {\r\n" +
+               "                       $info = \' (\'.basename($file).\", line $line)\";\r\n" +
+               "               } else {\r\n" +
+               "                       $info = null;\r\n" +
+               "               }\r\n" +
+               "        trigger_error(\'Smarty: [in \' . $this->_current_file . \' line \' .\r\n" +
+               "                      $this->_current_line_no . \"]: syntax error: $error_msg$info\", $error_type);\r\n" +
+               "    }\r\n" +
+               "}\r\n" +
+               "\r\n" +
+               "/**\r\n" +
+               " * compare to values by their string length\r\n" +
+               " *\r\n" +
+               " * @access private\r\n" +
+               " * @param  $a\r\n" +
+               " * @param  $b\r\n" +
+               " */\r\n" +
+               "function _smarty_sort_length($a, $b)\r\n" +
+               "{\r\n" +
+               "       if($a == $b)\r\n" +
+               "               return 0;\r\n" +
+               "\r\n" +
+               "       if(strlen($a) == strlen($b))\r\n" +
+               "               return ($a > $b) ? -1 : 1;\r\n" +
+               "\r\n" +
+               "       return (strlen($a) > strlen($b)) ? -1 : 1;\r\n" +
+               "}\r\n" +
+               "\r\n" +
+               "\r\n" +
+               "/* vim: set et: */\r\n" +
+               "\r\n" +
+               "?>\r\n" +
                "");
   }
   private void checkPHP(String strEval) {
@@ -1913,27 +1913,4 @@ public class SmartyCompilerTestCase extends AbstractCompilerTest {
                "");
 //    parser.phpParserTester(strEval, 1);
   }
-  private void checkHTML(String strEval) {
-    if (Scanner.DEBUG) {
-      System.out.println("\n------------------------------------");
-      System.out.println(strEval);
-    }
-    checkParseHTML(
-        strEval.toCharArray(),
-               "");
-//    parser.phpParserTester(strEval, 1);
-  }
-//  private void checkHTML(String strEval) {
-//    if (Scanner.DEBUG) {
-//      System.out.println("\n------------------------------------");
-//      System.out.println(strEval);
-//    }
-//    parser.parse(strEval);
-//  }
-//  /**
-//   * The JUnit setup method
-//   */
-//  protected void setUp() {
-//    parser = new Parser(null);
-//  }
 }
index 4dcd0f8..1a3da1e 100644 (file)
@@ -745,39 +745,27 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI
                        if (token == TokenNameSEMICOLON) {
                                getNextToken();
                        } else {
-                               if (token != TokenNameINLINE_HTML) {
+                               if (token != TokenNameINLINE_HTML ) {
                                        throwSyntaxError("';' expected after 'echo' statement.");
                                }
                                getNextToken();
                        }
                        return statement;
                } else if (token == TokenNameINLINE_HTML) {
-                       if (scanner.phpExpressionTag) {
-                               // start of <?= ... ?> block
-                               getNextToken();
-                               expr();
-                               if (token == TokenNameSEMICOLON) {
-                                       getNextToken();
-                               }
-                               if (token != TokenNameINLINE_HTML) {
-                                       throwSyntaxError("Missing '?>' for open PHP expression block ('<?=').");
-                               }
-                       } else {
+//                     if (scanner.phpExpressionTag) {
+//                             // start of <?= ... ?> block
+//                             getNextToken();
+//                             expr();
+//                             if (token == TokenNameSEMICOLON) {
+//                                     getNextToken();
+//                             }
+//                             if (token != TokenNameINLINE_HTML) {
+//                                     throwSyntaxError("Missing '?>' for open PHP expression block ('<?=').");
+//                             }
+//                     } else {
                                getNextToken();
-                       }
+//                     }
                        return statement;
-                       // } else if (token == TokenNameprint) {
-                       // getNextToken();
-                       // expression();
-                       // if (token == TokenNameSEMICOLON) {
-                       // getNextToken();
-                       // } else {
-                       // if (token != TokenNameStopPHP) {
-                       // throwSyntaxError("';' expected after 'print' statement.");
-                       // }
-                       // getNextToken();
-                       // }
-                       // return;
                } else if (token == TokenNameglobal) {
                        getNextToken();
                        global_var_list();
index a19a44d..30e835c 100644 (file)
@@ -39,8 +39,9 @@ public class Scanner implements IScanner, ITerminalSymbols {
 
        public boolean phpMode = false;
 
-       public boolean phpExpressionTag = false;
+//     public boolean phpExpressionTag = false;
 
+       int fFillerToken = TokenNameEOF;
        // public Stack encapsedStringStack = null;
 
        public char currentCharacter;
@@ -1288,11 +1289,15 @@ public class Scanner implements IScanner, ITerminalSymbols {
        }
 
        public int getNextToken() throws InvalidInputException {
-               phpExpressionTag = false;
                if (!phpMode) {
                        return getInlinedHTMLToken(currentPosition);
-               }
-               if (phpMode) {
+               } else {
+                       if (fFillerToken!=TokenNameEOF) {
+                               int tempToken;
+                               tempToken = fFillerToken;
+                               fFillerToken=TokenNameEOF;
+                               return tempToken;
+                       }
                        this.wasAcr = false;
                        if (diet) {
                                jumpOverMethodBody();
@@ -1951,6 +1956,7 @@ public class Scanner implements IScanner, ITerminalSymbols {
         * @throws InvalidInputException
         */
        private int getInlinedHTMLToken(int start) throws InvalidInputException {
+               boolean phpShortTag = false;  // true, if <?= detected
                if (currentPosition > source.length) {
                        currentPosition = source.length;
                        return TokenNameEOF;
@@ -1965,23 +1971,27 @@ public class Scanner implements IScanner, ITerminalSymbols {
                                                if ((currentCharacter != 'P') && (currentCharacter != 'p')) {
                                                        if (currentCharacter != '=') { // <?=
                                                                currentPosition--;
+                                                               phpShortTag = false;
                                                        } else {
-                                                               phpExpressionTag = true;
+                                                               phpShortTag = true;
                                                        }
                                                        // <?
                                                        if (ignorePHPOneLiner) { // for CodeFormatter
                                                                if (lookAheadLinePHPTag() == TokenNameINLINE_HTML) {
                                                                        phpMode = true;
+                                                                       if (phpShortTag) {
+                                                                               fFillerToken = TokenNameecho;
+                                                                       }
                                                                        return TokenNameINLINE_HTML;
                                                                }
                                                        } else {
                                                                phpMode = true;
+                                                               if (phpShortTag) {
+                                                                       fFillerToken = TokenNameecho;
+                                                               }
                                                                return TokenNameINLINE_HTML;
                                                        }
                                                } else {
-                                                       // boolean phpStart = (currentCharacter == 'P') ||
-                                                       // (currentCharacter == 'p');
-                                                       // if (phpStart) {
                                                        int test = getNextChar('H', 'h');
                                                        if (test >= 0) {
                                                                test = getNextChar('P', 'p');
@@ -2022,10 +2032,11 @@ public class Scanner implements IScanner, ITerminalSymbols {
        }
 
        /**
+        * check if the PHP is only in this line (for CodeFormatter)
+        *
         * @return
         */
        private int lookAheadLinePHPTag() {
-               // check if the PHP is only in this line (for CodeFormatter)
                int currentPositionInLine = currentPosition;
                char previousCharInLine = ' ';
                char currentCharInLine = ' ';