diff --git a/tenjin.py b/tenjin.py
new file mode 100644
index 0000000..db8cdde
--- /dev/null
+++ b/tenjin.py
@@ -0,0 +1,2118 @@
+##
+## $Release: 1.1.1 $
+## $Copyright: copyright(c) 2007-2012 kuwata-lab.com all rights reserved. $
+## $License: MIT License $
+##
+## Permission is hereby granted, free of charge, to any person obtaining
+## a copy of this software and associated documentation files (the
+## "Software"), to deal in the Software without restriction, including
+## without limitation the rights to use, copy, modify, merge, publish,
+## distribute, sublicense, and/or sell copies of the Software, and to
+## permit persons to whom the Software is furnished to do so, subject to
+## the following conditions:
+##
+## The above copyright notice and this permission notice shall be
+## included in all copies or substantial portions of the Software.
+##
+## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+## EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+## MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+## NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+## LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+## OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+## WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+##
+
+"""Very fast and light-weight template engine based embedded Python.
+   See User's Guide and examples for details.
+   http://www.kuwata-lab.com/tenjin/pytenjin-users-guide.html
+   http://www.kuwata-lab.com/tenjin/pytenjin-examples.html
+"""
+
+__version__  = "$Release: 1.1.1 $"[10:-2]
+__license__  = "$License: MIT License $"[10:-2]
+__all__      = ('Template', 'Engine', )
+
+
+import sys, os, re, time, marshal
+from time import time as _time
+from os.path import getmtime as _getmtime
+from os.path import isfile as _isfile
+random = pickle = unquote = None   # lazy import
+python3 = sys.version_info[0] == 3
+python2 = sys.version_info[0] == 2
+
+logger = None
+
+
+##
+## utilities
+##
+
+def _write_binary_file(filename, content):
+    global random
+    if random is None: from random import random
+    tmpfile = filename + str(random())[1:]
+    f = open(tmpfile, 'w+b')     # on windows, 'w+b' is preffered than 'wb'
+    try:
+        f.write(content)
+    finally:
+        f.close()
+    if os.path.exists(tmpfile):
+        try:
+            os.rename(tmpfile, filename)
+        except:
+            os.remove(filename)  # on windows, existing file should be removed before renaming
+            os.rename(tmpfile, filename)
+
+def _read_binary_file(filename):
+    f = open(filename, 'rb')
+    try:
+        return f.read()
+    finally:
+        f.close()
+
+codecs = None    # lazy import
+
+def _read_text_file(filename, encoding=None):
+    global codecs
+    if not codecs: import codecs
+    f = codecs.open(filename, encoding=(encoding or 'utf-8'))
+    try:
+        return f.read()
+    finally:
+        f.close()
+
+def _read_template_file(filename, encoding=None):
+    s = _read_binary_file(filename)          ## binary(=str)
+    if encoding: s = s.decode(encoding)      ## binary(=str) to unicode
+    return s
+
+_basestring = basestring
+_unicode    = unicode
+_bytes      = str
+
+def _ignore_not_found_error(f, default=None):
+    try:
+        return f()
+    except OSError, ex:
+        if ex.errno == 2:   # error: No such file or directory
+            return default
+        raise
+
+def create_module(module_name, dummy_func=None, **kwargs):
+    """ex. mod = create_module('tenjin.util')"""
+    try:
+        mod = type(sys)(module_name)
+    except:
+        # The module creation above does not work for Jython 2.5.2
+        import imp
+        mod = imp.new_module(module_name)
+
+    mod.__file__ = __file__
+    mod.__dict__.update(kwargs)
+    sys.modules[module_name] = mod
+    if dummy_func:
+        exec(dummy_func.func_code, mod.__dict__)
+    return mod
+
+def _raise(exception_class, *args):
+    raise exception_class(*args)
+
+
+##
+## helper method's module
+##
+
+def _dummy():
+    global unquote
+    unquote = None
+    global to_str, escape, echo, new_cycle, generate_tostrfunc
+    global start_capture, stop_capture, capture_as, captured_as, CaptureContext
+    global _p, _P, _decode_params
+
+    def generate_tostrfunc(encode=None, decode=None):
+        """Generate 'to_str' function with encode or decode encoding.
+           ex. generate to_str() function which encodes unicode into binary(=str).
+              to_str = tenjin.generate_tostrfunc(encode='utf-8')
+              repr(to_str(u'hoge'))  #=> 'hoge' (str)
+           ex. generate to_str() function which decodes binary(=str) into unicode.
+              to_str = tenjin.generate_tostrfunc(decode='utf-8')
+              repr(to_str('hoge'))   #=> u'hoge' (unicode)
+        """
+        if encode:
+            if decode:
+                raise ValueError("can't specify both encode and decode encoding.")
+            else:
+                def to_str(val,   _str=str, _unicode=unicode, _isa=isinstance, _encode=encode):
+                    """Convert val into string or return '' if None. Unicode will be encoded into binary(=str)."""
+                    if _isa(val, _str):     return val
+                    if val is None:         return ''
+                    #if _isa(val, _unicode): return val.encode(_encode)  # unicode to binary(=str)
+                    if _isa(val, _unicode):
+                        return val.encode(_encode)  # unicode to binary(=str)
+                    return _str(val)
+        else:
+            if decode:
+                def to_str(val,   _str=str, _unicode=unicode, _isa=isinstance, _decode=decode):
+                    """Convert val into string or return '' if None. Binary(=str) will be decoded into unicode."""
+                    #if _isa(val, _str):     return val.decode(_decode)  # binary(=str) to unicode
+                    if _isa(val, _str):
+                        return val.decode(_decode)
+                    if val is None:         return ''
+                    if _isa(val, _unicode): return val
+                    return _unicode(val)
+            else:
+                def to_str(val,   _str=str, _unicode=unicode, _isa=isinstance):
+                    """Convert val into string or return '' if None. Both binary(=str) and unicode will be retruned as-is."""
+                    if _isa(val, _str):     return val
+                    if val is None:         return ''
+                    if _isa(val, _unicode): return val
+                    return _str(val)
+        return to_str
+
+    to_str = generate_tostrfunc(encode='utf-8')  # or encode=None?
+
+    def echo(string):
+        """add string value into _buf. this is equivarent to '#{string}'."""
+        lvars = sys._getframe(1).f_locals   # local variables
+        lvars['_buf'].append(string)
+
+    def new_cycle(*values):
+        """Generate cycle object.
+           ex.
+             cycle = new_cycle('odd', 'even')
+             print(cycle())   #=> 'odd'
+             print(cycle())   #=> 'even'
+             print(cycle())   #=> 'odd'
+             print(cycle())   #=> 'even'
+        """
+        def gen(values):
+            i, n = 0, len(values)
+            while True:
+                yield values[i]
+                i = (i + 1) % n
+        return gen(values).next
+
+    class CaptureContext(object):
+
+        def __init__(self, name, store_to_context=True, lvars=None):
+            self.name  = name
+            self.store_to_context = store_to_context
+            self.lvars = lvars or sys._getframe(1).f_locals
+
+        def __enter__(self):
+            lvars = self.lvars
+            self._buf_orig = lvars['_buf']
+            lvars['_buf']    = _buf = []
+            lvars['_extend'] = _buf.extend
+            return self
+
+        def __exit__(self, *args):
+            lvars = self.lvars
+            _buf = lvars['_buf']
+            lvars['_buf']    = self._buf_orig
+            lvars['_extend'] = self._buf_orig.extend
+            lvars[self.name] = self.captured = ''.join(_buf)
+            if self.store_to_context and '_context' in lvars:
+                lvars['_context'][self.name] = self.captured
+
+        def __iter__(self):
+            self.__enter__()
+            yield self
+            self.__exit__()
+
+    def start_capture(varname=None, _depth=1):
+        """(obsolete) start capturing with name."""
+        lvars = sys._getframe(_depth).f_locals
+        capture_context = CaptureContext(varname, None, lvars)
+        lvars['_capture_context'] = capture_context
+        capture_context.__enter__()
+
+    def stop_capture(store_to_context=True, _depth=1):
+        """(obsolete) stop capturing and return the result of capturing.
+           if store_to_context is True then the result is stored into _context[varname].
+        """
+        lvars = sys._getframe(_depth).f_locals
+        capture_context = lvars.pop('_capture_context', None)
+        if not capture_context:
+            raise Exception('stop_capture(): start_capture() is not called before.')
+        capture_context.store_to_context = store_to_context
+        capture_context.__exit__()
+        return capture_context.captured
+
+    def capture_as(name, store_to_context=True):
+        """capture partial of template."""
+        return CaptureContext(name, store_to_context, sys._getframe(1).f_locals)
+
+    def captured_as(name, _depth=1):
+        """helper method for layout template.
+           if captured string is found then append it to _buf and return True,
+           else return False.
+        """
+        lvars = sys._getframe(_depth).f_locals   # local variables
+        if name in lvars:
+            _buf = lvars['_buf']
+            _buf.append(lvars[name])
+            return True
+        return False
+
+    def _p(arg):
+        """ex. '/show/'+_p("item['id']") => "/show/#{item['id']}" """
+        return '<`#%s#`>' % arg    # decoded into #{...} by preprocessor
+
+    def _P(arg):
+        """ex. '<b>%s</b>' % _P("item['id']") => "<b>${item['id']}</b>" """
+        return '<`$%s$`>' % arg    # decoded into ${...} by preprocessor
+
+    def _decode_params(s):
+        """decode <`#...#`> and <`$...$`> into #{...} and ${...}"""
+        global unquote
+        if unquote is None:
+            from urllib import unquote
+        dct = { 'lt':'<', 'gt':'>', 'amp':'&', 'quot':'"', '#039':"'", }
+        def unescape(s):
+            #return s.replace('&lt;', '<').replace('&gt;', '>').replace('&quot;', '"').replace('&#039;', "'").replace('&amp;',  '&')
+            return re.sub(r'&(lt|gt|quot|amp|#039);',  lambda m: dct[m.group(1)],  s)
+        s = to_str(s)
+        s = re.sub(r'%3C%60%23(.*?)%23%60%3E', lambda m: '#{%s}' % unquote(m.group(1)), s)
+        s = re.sub(r'%3C%60%24(.*?)%24%60%3E', lambda m: '${%s}' % unquote(m.group(1)), s)
+        s = re.sub(r'&lt;`#(.*?)#`&gt;',   lambda m: '#{%s}' % unescape(m.group(1)), s)
+        s = re.sub(r'&lt;`\$(.*?)\$`&gt;', lambda m: '${%s}' % unescape(m.group(1)), s)
+        s = re.sub(r'<`#(.*?)#`>', r'#{\1}', s)
+        s = re.sub(r'<`\$(.*?)\$`>', r'${\1}', s)
+        return s
+
+helpers = create_module('tenjin.helpers', _dummy, sys=sys, re=re)
+helpers.__all__ = ['to_str', 'escape', 'echo', 'new_cycle', 'generate_tostrfunc',
+                   'start_capture', 'stop_capture', 'capture_as', 'captured_as',
+                   'not_cached', 'echo_cached', 'cache_as',
+                   '_p', '_P', '_decode_params',
+                   ]
+generate_tostrfunc = helpers.generate_tostrfunc
+
+
+##
+## escaped module
+##
+def _dummy():
+    global is_escaped, as_escaped, to_escaped
+    global Escaped, EscapedStr, EscapedUnicode
+    global __all__
+    __all__ = ('is_escaped', 'as_escaped', 'to_escaped', ) #'Escaped', 'EscapedStr',
+
+    class Escaped(object):
+        """marking class that object is already escaped."""
+        pass
+
+    def is_escaped(value):
+        """return True if value is marked as escaped, else return False."""
+        return isinstance(value, Escaped)
+
+    class EscapedStr(str, Escaped):
+        """string class which is marked as escaped."""
+        pass
+
+    class EscapedUnicode(unicode, Escaped):
+        """unicode class which is marked as escaped."""
+        pass
+
+    def as_escaped(s):
+        """mark string as escaped, without escaping."""
+        if isinstance(s, str):     return EscapedStr(s)
+        if isinstance(s, unicode): return EscapedUnicode(s)
+        raise TypeError("as_escaped(%r): expected str or unicode." % (s, ))
+
+    def to_escaped(value):
+        """convert any value into string and escape it.
+           if value is already marked as escaped, don't escape it."""
+        if hasattr(value, '__html__'):
+            value = value.__html__()
+        if is_escaped(value):
+            #return value     # EscapedUnicode should be convered into EscapedStr
+            return as_escaped(_helpers.to_str(value))
+        #if isinstance(value, _basestring):
+        #    return as_escaped(_helpers.escape(value))
+        return as_escaped(_helpers.escape(_helpers.to_str(value)))
+
+escaped = create_module('tenjin.escaped', _dummy, _helpers=helpers)
+
+
+##
+## module for html
+##
+def _dummy():
+    global escape_html, escape_xml, escape, tagattr, tagattrs, _normalize_attrs
+    global checked, selected, disabled, nl2br, text2html, nv, js_link
+
+    #_escape_table = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }
+    #_escape_pattern = re.compile(r'[&<>"]')
+    ##_escape_callable = lambda m: _escape_table[m.group(0)]
+    ##_escape_callable = lambda m: _escape_table.__get__(m.group(0))
+    #_escape_get     = _escape_table.__getitem__
+    #_escape_callable = lambda m: _escape_get(m.group(0))
+    #_escape_sub     = _escape_pattern.sub
+
+    #def escape_html(s):
+    #    return s                                          # 3.02
+
+    #def escape_html(s):
+    #    return _escape_pattern.sub(_escape_callable, s)   # 6.31
+
+    #def escape_html(s):
+    #    return _escape_sub(_escape_callable, s)           # 6.01
+
+    #def escape_html(s, _p=_escape_pattern, _f=_escape_callable):
+    #    return _p.sub(_f, s)                              # 6.27
+
+    #def escape_html(s, _sub=_escape_pattern.sub, _callable=_escape_callable):
+    #    return _sub(_callable, s)                         # 6.04
+
+    #def escape_html(s):
+    #    s = s.replace('&', '&amp;')
+    #    s = s.replace('<', '&lt;')
+    #    s = s.replace('>', '&gt;')
+    #    s = s.replace('"', '&quot;')
+    #    return s                                          # 5.83
+
+    def escape_html(s):
+        """Escape '&', '<', '>', '"' into '&amp;', '&lt;', '&gt;', '&quot;'."""
+        return s.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;').replace('"', '&quot;').replace("'", '&#39;')   # 5.72
+
+    escape_xml = escape_html   # for backward compatibility
+
+    def tagattr(name, expr, value=None, escape=True):
+        """(experimental) Return ' name="value"' if expr is true value, else '' (empty string).
+           If value is not specified, expr is used as value instead."""
+        if not expr and expr != 0: return _escaped.as_escaped('')
+        if value is None: value = expr
+        if escape: value = _escaped.to_escaped(value)
+        return _escaped.as_escaped(' %s="%s"' % (name, value))
+
+    def tagattrs(**kwargs):
+        """(experimental) built html tag attribtes.
+           ex.
+           >>> tagattrs(klass='main', size=20)
+           ' class="main" size="20"'
+           >>> tagattrs(klass='', size=0)
+           ''
+        """
+        kwargs = _normalize_attrs(kwargs)
+        esc = _escaped.to_escaped
+        s = ''.join([ ' %s="%s"' % (k, esc(v)) for k, v in kwargs.iteritems() if v or v == 0 ])
+        return _escaped.as_escaped(s)
+
+    def _normalize_attrs(kwargs):
+        if 'klass'    in kwargs: kwargs['class']    = kwargs.pop('klass')
+        if 'checked'  in kwargs: kwargs['checked']  = kwargs.pop('checked')  and 'checked'  or None
+        if 'selected' in kwargs: kwargs['selected'] = kwargs.pop('selected') and 'selected' or None
+        if 'disabled' in kwargs: kwargs['disabled'] = kwargs.pop('disabled') and 'disabled' or None
+        return kwargs
+
+    def checked(expr):
+        """return ' checked="checked"' if expr is true."""
+        return _escaped.as_escaped(expr and ' checked="checked"' or '')
+
+    def selected(expr):
+        """return ' selected="selected"' if expr is true."""
+        return _escaped.as_escaped(expr and ' selected="selected"' or '')
+
+    def disabled(expr):
+        """return ' disabled="disabled"' if expr is true."""
+        return _escaped.as_escaped(expr and ' disabled="disabled"' or '')
+
+    def nl2br(text):
+        """replace "\n" to "<br />\n" and return it."""
+        if not text:
+            return _escaped.as_escaped('')
+        return _escaped.as_escaped(text.replace('\n', '<br />\n'))
+
+    def text2html(text, use_nbsp=True):
+        """(experimental) escape xml characters, replace "\n" to "<br />\n", and return it."""
+        if not text:
+            return _escaped.as_escaped('')
+        s = _escaped.to_escaped(text)
+        if use_nbsp: s = s.replace('  ', ' &nbsp;')
+        #return nl2br(s)
+        s = s.replace('\n', '<br />\n')
+        return _escaped.as_escaped(s)
+
+    def nv(name, value, sep=None, **kwargs):
+        """(experimental) Build name and value attributes.
+           ex.
+           >>> nv('rank', 'A')
+           'name="rank" value="A"'
+           >>> nv('rank', 'A', '.')
+           'name="rank" value="A" id="rank.A"'
+           >>> nv('rank', 'A', '.', checked=True)
+           'name="rank" value="A" id="rank.A" checked="checked"'
+           >>> nv('rank', 'A', '.', klass='error', style='color:red')
+           'name="rank" value="A" id="rank.A" class="error" style="color:red"'
+        """
+        name  = _escaped.to_escaped(name)
+        value = _escaped.to_escaped(value)
+        s = sep and 'name="%s" value="%s" id="%s"' % (name, value, name+sep+value) \
+                or  'name="%s" value="%s"'         % (name, value)
+        html = kwargs and s + tagattrs(**kwargs) or s
+        return _escaped.as_escaped(html)
+
+    def js_link(label, onclick, **kwargs):
+        s = kwargs and tagattrs(**kwargs) or ''
+        html = '<a href="javascript:undefined" onclick="%s;return false"%s>%s</a>' % \
+                  (_escaped.to_escaped(onclick), s, _escaped.to_escaped(label))
+        return _escaped.as_escaped(html)
+
+html = create_module('tenjin.html', _dummy, helpers=helpers, _escaped=escaped)
+helpers.escape = html.escape_html
+helpers.html = html   # for backward compatibility
+sys.modules['tenjin.helpers.html'] = html
+
+
+##
+## utility function to set default encoding of template files
+##
+_template_encoding = (None, 'utf-8')    # encodings for decode and encode
+
+def set_template_encoding(decode=None, encode=None):
+    """Set default encoding of template files.
+       This should be called before importing helper functions.
+       ex.
+          ## I like template files to be unicode-base like Django.
+          import tenjin
+          tenjin.set_template_encoding('utf-8')  # should be called before importing helpers
+          from tenjin.helpers import *
+    """
+    global _template_encoding
+    if _template_encoding == (decode, encode):
+        return
+    if decode and encode:
+        raise ValueError("set_template_encoding(): cannot specify both decode and encode.")
+    if not decode and not encode:
+        raise ValueError("set_template_encoding(): decode or encode should be specified.")
+    if decode:
+        Template.encoding = decode    # unicode base template
+        helpers.to_str = helpers.generate_tostrfunc(decode=decode)
+    else:
+        Template.encoding = None      # binary base template
+        helpers.to_str = helpers.generate_tostrfunc(encode=encode)
+    _template_encoding = (decode, encode)
+
+
+##
+## Template class
+##
+
+class TemplateSyntaxError(SyntaxError):
+
+    def build_error_message(self):
+        ex = self
+        if not ex.text:
+            return self.args[0]
+        return ''.join([
+            "%s:%s:%s: %s\n" % (ex.filename, ex.lineno, ex.offset, ex.msg, ),
+            "%4d: %s\n"      % (ex.lineno, ex.text.rstrip(), ),
+            "     %s^\n"     % (' ' * ex.offset, ),
+        ])
+
+
+class Template(object):
+    """Convert and evaluate embedded python string.
+       See User's Guide and examples for details.
+       http://www.kuwata-lab.com/tenjin/pytenjin-users-guide.html
+       http://www.kuwata-lab.com/tenjin/pytenjin-examples.html
+    """
+
+    ## default value of attributes
+    filename   = None
+    encoding   = None
+    escapefunc = 'escape'
+    tostrfunc  = 'to_str'
+    indent     = 4
+    preamble   = None    # "_buf = []; _expand = _buf.expand; _to_str = to_str; _escape = escape"
+    postamble  = None    # "print ''.join(_buf)"
+    smarttrim  = None
+    args       = None
+    timestamp  = None
+    trace      = False   # if True then '<!-- begin: file -->' and '<!-- end: file -->' are printed
+
+    def __init__(self, filename=None, encoding=None, input=None, escapefunc=None, tostrfunc=None,
+                       indent=None, preamble=None, postamble=None, smarttrim=None, trace=None):
+        """Initailizer of Template class.
+
+           filename:str (=None)
+             Filename to convert (optional). If None, no convert.
+           encoding:str (=None)
+             Encoding name. If specified, template string is converted into
+             unicode object internally.
+             Template.render() returns str object if encoding is None,
+             else returns unicode object if encoding name is specified.
+           input:str (=None)
+             Input string. In other words, content of template file.
+             Template file will not be read if this argument is specified.
+           escapefunc:str (='escape')
+             Escape function name.
+           tostrfunc:str (='to_str')
+             'to_str' function name.
+           indent:int (=4)
+             Indent width.
+           preamble:str or bool (=None)
+             Preamble string which is inserted into python code.
+             If true, '_buf = []; ' is used insated.
+           postamble:str or bool (=None)
+             Postamble string which is appended to python code.
+             If true, 'print("".join(_buf))' is used instead.
+           smarttrim:bool (=None)
+             If True then "<div>\\n#{_context}\\n</div>" is parsed as
+             "<div>\\n#{_context}</div>".
+        """
+        if encoding   is not None:  self.encoding   = encoding
+        if escapefunc is not None:  self.escapefunc = escapefunc
+        if tostrfunc  is not None:  self.tostrfunc  = tostrfunc
+        if indent     is not None:  self.indent     = indent
+        if preamble   is not None:  self.preamble   = preamble
+        if postamble  is not None:  self.postamble  = postamble
+        if smarttrim  is not None:  self.smarttrim  = smarttrim
+        if trace      is not None:  self.trace      = trace
+        #
+        if preamble  is True:  self.preamble  = "_buf = []"
+        if postamble is True:  self.postamble = "print(''.join(_buf))"
+        if input:
+            self.convert(input, filename)
+            self.timestamp = False      # False means 'file not exist' (= Engine should not check timestamp of file)
+        elif filename:
+            self.convert_file(filename)
+        else:
+            self._reset()
+
+    def _reset(self, input=None, filename=None):
+        self.script   = None
+        self.bytecode = None
+        self.input    = input
+        self.filename = filename
+        if input != None:
+            i = input.find("\n")
+            if i < 0:
+                self.newline = "\n"   # or None
+            elif len(input) >= 2 and input[i-1] == "\r":
+                self.newline = "\r\n"
+            else:
+                self.newline = "\n"
+        self._localvars_assignments_added = False
+
+    def _localvars_assignments(self):
+        return "_extend=_buf.extend;_to_str=%s;_escape=%s; " % (self.tostrfunc, self.escapefunc)
+
+    def before_convert(self, buf):
+        if self.preamble:
+            eol = self.input.startswith('<?py') and "\n" or "; "
+            buf.append(self.preamble + eol)
+
+    def after_convert(self, buf):
+        if self.postamble:
+            if buf and not buf[-1].endswith("\n"):
+                buf.append("\n")
+            buf.append(self.postamble + "\n")
+
+    def convert_file(self, filename):
+        """Convert file into python script and return it.
+           This is equivarent to convert(open(filename).read(), filename).
+        """
+        input = _read_template_file(filename)
+        return self.convert(input, filename)
+
+    def convert(self, input, filename=None):
+        """Convert string in which python code is embedded into python script and return it.
+
+           input:str
+             Input string to convert into python code.
+           filename:str (=None)
+             Filename of input. this is optional but recommended to report errors.
+        """
+        if self.encoding and isinstance(input, str):
+            input = input.decode(self.encoding)
+        self._reset(input, filename)
+        buf = []
+        self.before_convert(buf)
+        self.parse_stmts(buf, input)
+        self.after_convert(buf)
+        script = ''.join(buf)
+        self.script = script
+        return script
+
+    STMT_PATTERN = (r'<\?py( |\t|\r?\n)(.*?) ?\?>([ \t]*\r?\n)?', re.S)
+
+    def stmt_pattern(self):
+        pat = self.STMT_PATTERN
+        if isinstance(pat, tuple):
+            pat = self.__class__.STMT_PATTERN = re.compile(*pat)
+        return pat
+
+    def parse_stmts(self, buf, input):
+        if not input: return
+        rexp = self.stmt_pattern()
+        is_bol = True
+        index = 0
+        for m in rexp.finditer(input):
+            mspace, code, rspace = m.groups()
+            #mspace, close, rspace = m.groups()
+            #code = input[m.start()+4+len(mspace):m.end()-len(close)-(rspace and len(rspace) or 0)]
+            text = input[index:m.start()]
+            index = m.end()
+            ## detect spaces at beginning of line
+            lspace = None
+            if text == '':
+                if is_bol:
+                    lspace = ''
+            elif text[-1] == '\n':
+                lspace = ''
+            else:
+                rindex = text.rfind('\n')
+                if rindex < 0:
+                    if is_bol and text.isspace():
+                        lspace, text = text, ''
+                else:
+                    s = text[rindex+1:]
+                    if s.isspace():
+                        lspace, text = s, text[:rindex+1]
+            #is_bol = rspace is not None
+            ## add text, spaces, and statement
+            self.parse_exprs(buf, text, is_bol)
+            is_bol = rspace is not None
+            #if mspace == "\n":
+            if mspace and mspace.endswith("\n"):
+                code = "\n" + (code or "")
+            #if rspace == "\n":
+            if rspace and rspace.endswith("\n"):
+                code = (code or "") + "\n"
+            if code:
+                code = self.statement_hook(code)
+                m = self._match_to_args_declaration(code)
+                if m:
+                    self._add_args_declaration(buf, m)
+                else:
+                    self.add_stmt(buf, code)
+        rest = input[index:]
+        if rest:
+            self.parse_exprs(buf, rest)
+        self._arrange_indent(buf)
+
+    def statement_hook(self, stmt):
+        """expand macros and parse '#@ARGS' in a statement."""
+        return stmt.replace("\r\n", "\n")   # Python can't handle "\r\n" in code
+
+    def _match_to_args_declaration(self, stmt):
+        if self.args is not None:
+            return None
+        args_pattern = r'^ *#@ARGS(?:[ \t]+(.*?))?$'
+        return re.match(args_pattern, stmt)
+
+    def _add_args_declaration(self, buf, m):
+        arr = (m.group(1) or '').split(',')
+        args = [];  declares = []
+        for s in arr:
+            arg = s.strip()
+            if not s: continue
+            if not re.match('^[a-zA-Z_]\w*$', arg):
+                raise ValueError("%r: invalid template argument." % arg)
+            args.append(arg)
+            declares.append("%s = _context.get('%s'); " % (arg, arg))
+        self.args = args
+        #nl = stmt[m.end():]
+        #if nl: declares.append(nl)
+        buf.append(''.join(declares) + "\n")
+
+    s = '(?:\{.*?\}.*?)*'
+    EXPR_PATTERN = (r'#\{(.*?'+s+r')\}|\$\{(.*?'+s+r')\}|\{=(?:=(.*?)=|(.*?))=\}', re.S)
+    del s
+
+    def expr_pattern(self):
+        pat = self.EXPR_PATTERN
+        if isinstance(pat, tuple):
+            self.__class__.EXPR_PATTERN = pat = re.compile(*pat)
+        return pat
+
+    def get_expr_and_flags(self, match):
+        expr1, expr2, expr3, expr4 = match.groups()
+        if expr1 is not None: return expr1, (False, True)   # not escape,  call to_str
+        if expr2 is not None: return expr2, (True,  True)   # call escape, call to_str
+        if expr3 is not None: return expr3, (False, True)   # not escape,  call to_str
+        if expr4 is not None: return expr4, (True,  True)   # call escape, call to_str
+
+    def parse_exprs(self, buf, input, is_bol=False):
+        buf2 = []
+        self._parse_exprs(buf2, input, is_bol)
+        if buf2:
+            buf.append(''.join(buf2))
+
+    def _parse_exprs(self, buf, input, is_bol=False):
+        if not input: return
+        self.start_text_part(buf)
+        rexp = self.expr_pattern()
+        smarttrim = self.smarttrim
+        nl = self.newline
+        nl_len  = len(nl)
+        pos = 0
+        for m in rexp.finditer(input):
+            start = m.start()
+            text  = input[pos:start]
+            pos   = m.end()
+            expr, flags = self.get_expr_and_flags(m)
+            #
+            if text:
+                self.add_text(buf, text)
+            self.add_expr(buf, expr, *flags)
+            #
+            if smarttrim:
+                flag_bol = text.endswith(nl) or not text and (start > 0  or is_bol)
+                if flag_bol and not flags[0] and input[pos:pos+nl_len] == nl:
+                    pos += nl_len
+                    buf.append("\n")
+        if smarttrim:
+            if buf and buf[-1] == "\n":
+                buf.pop()
+        rest = input[pos:]
+        if rest:
+            self.add_text(buf, rest, True)
+        self.stop_text_part(buf)
+        if input[-1] == '\n':
+            buf.append("\n")
+
+    def start_text_part(self, buf):
+        self._add_localvars_assignments_to_text(buf)
+        #buf.append("_buf.extend((")
+        buf.append("_extend((")
+
+    def _add_localvars_assignments_to_text(self, buf):
+        if not self._localvars_assignments_added:
+            self._localvars_assignments_added = True
+            buf.append(self._localvars_assignments())
+
+    def stop_text_part(self, buf):
+        buf.append("));")
+
+    def _quote_text(self, text):
+        text = re.sub(r"(['\\\\])", r"\\\1", text)
+        text = text.replace("\r\n", "\\r\n")
+        return text
+
+    def add_text(self, buf, text, encode_newline=False):
+        if not text: return
+        use_unicode = self.encoding and python2
+        buf.append(use_unicode and "u'''" or "'''")
+        text = self._quote_text(text)
+        if   not encode_newline:    buf.extend((text,       "''', "))
+        elif text.endswith("\r\n"): buf.extend((text[0:-2], "\\r\\n''', "))
+        elif text.endswith("\n"):   buf.extend((text[0:-1], "\\n''', "))
+        else:                       buf.extend((text,       "''', "))
+
+    _add_text = add_text
+
+    def add_expr(self, buf, code, *flags):
+        if not code or code.isspace(): return
+        flag_escape, flag_tostr = flags
+        if not self.tostrfunc:  flag_tostr  = False
+        if not self.escapefunc: flag_escape = False
+        if flag_tostr and flag_escape: s1, s2 = "_escape(_to_str(", ")), "
+        elif flag_tostr:               s1, s2 = "_to_str(", "), "
+        elif flag_escape:              s1, s2 = "_escape(", "), "
+        else:                          s1, s2 = "(", "), "
+        buf.extend((s1, code, s2, ))
+
+    def add_stmt(self, buf, code):
+        if not code: return
+        lines = code.splitlines(True)   # keep "\n"
+        if lines[-1][-1] != "\n":
+            lines[-1] = lines[-1] + "\n"
+        buf.extend(lines)
+        self._add_localvars_assignments_to_stmts(buf)
+
+    def _add_localvars_assignments_to_stmts(self, buf):
+        if self._localvars_assignments_added:
+            return
+        for index, stmt in enumerate(buf):
+            if not re.match(r'^[ \t]*(?:\#|_buf ?= ?\[\]|from __future__)', stmt):
+                break
+        else:
+            return
+        self._localvars_assignments_added = True
+        if re.match(r'^[ \t]*(if|for|while|def|with|class)\b', stmt):
+            buf.insert(index, self._localvars_assignments() + "\n")
+        else:
+            buf[index] = self._localvars_assignments() + buf[index]
+
+
+    _START_WORDS = dict.fromkeys(('for', 'if', 'while', 'def', 'try:', 'with', 'class'), True)
+    _END_WORDS   = dict.fromkeys(('#end', '#endfor', '#endif', '#endwhile', '#enddef', '#endtry', '#endwith', '#endclass'), True)
+    _CONT_WORDS  = dict.fromkeys(('elif', 'else:', 'except', 'except:', 'finally:'), True)
+    _WORD_REXP   = re.compile(r'\S+')
+
+    depth = -1
+
+    ##
+    ## ex.
+    ##   input = r"""
+    ##   if items:
+    ##   _buf.extend(('<ul>\n', ))
+    ##   i = 0
+    ##   for item in items:
+    ##   i += 1
+    ##   _buf.extend(('<li>', to_str(item), '</li>\n', ))
+    ##   #endfor
+    ##   _buf.extend(('</ul>\n', ))
+    ##   #endif
+    ##   """[1:]
+    ##   lines = input.splitlines(True)
+    ##   block = self.parse_lines(lines)
+    ##      #=>  [ "if items:\n",
+    ##             [ "_buf.extend(('<ul>\n', ))\n",
+    ##               "i = 0\n",
+    ##               "for item in items:\n",
+    ##               [ "i += 1\n",
+    ##                 "_buf.extend(('<li>', to_str(item), '</li>\n', ))\n",
+    ##               ],
+    ##               "#endfor\n",
+    ##               "_buf.extend(('</ul>\n', ))\n",
+    ##             ],
+    ##             "#endif\n",
+    ##           ]
+    def parse_lines(self, lines):
+        block = []
+        try:
+            self._parse_lines(lines.__iter__(), False, block, 0)
+        except StopIteration:
+            if self.depth > 0:
+                fname, linenum, colnum, linetext = self.filename, len(lines), None, None
+                raise TemplateSyntaxError("unexpected EOF.", (fname, linenum, colnum, linetext))
+        else:
+            pass
+        return block
+
+    def _parse_lines(self, lines_iter, end_block, block, linenum):
+        if block is None: block = []
+        _START_WORDS = self._START_WORDS
+        _END_WORDS   = self._END_WORDS
+        _CONT_WORDS  = self._CONT_WORDS
+        _WORD_REXP   = self._WORD_REXP
+        get_line = lines_iter.next
+        while True:
+            line = get_line()
+            linenum += line.count("\n")
+            m = _WORD_REXP.search(line)
+            if not m:
+                block.append(line)
+                continue
+            word = m.group(0)
+            if word in _END_WORDS:
+                if word != end_block and word != '#end':
+                    if end_block is False:
+                        msg = "'%s' found but corresponding statement is missing." % (word, )
+                    else:
+                        msg = "'%s' expected but got '%s'." % (end_block, word)
+                    colnum = m.start() + 1
+                    raise TemplateSyntaxError(msg, (self.filename, linenum, colnum, line))
+                return block, line, None, linenum
+            elif line.endswith(':\n') or line.endswith(':\r\n'):
+                if word in _CONT_WORDS:
+                    return block, line, word, linenum
+                elif word in _START_WORDS:
+                    block.append(line)
+                    self.depth += 1
+                    cont_word = None
+                    try:
+                        child_block, line, cont_word, linenum = \
+                            self._parse_lines(lines_iter, '#end'+word, [], linenum)
+                        block.extend((child_block, line, ))
+                        while cont_word:   # 'elif' or 'else:'
+                            child_block, line, cont_word, linenum = \
+                                self._parse_lines(lines_iter, '#end'+word, [], linenum)
+                            block.extend((child_block, line, ))
+                    except StopIteration:
+                        msg = "'%s' is not closed." % (cont_word or word)
+                        colnum = m.start() + 1
+                        raise TemplateSyntaxError(msg, (self.filename, linenum, colnum, line))
+                    self.depth -= 1
+                else:
+                    block.append(line)
+            else:
+                block.append(line)
+        assert "unreachable"
+
+    def _join_block(self, block, buf, depth):
+        indent = ' ' * (self.indent * depth)
+        for line in block:
+            if isinstance(line, list):
+                self._join_block(line, buf, depth+1)
+            elif line.isspace():
+                buf.append(line)
+            else:
+                buf.append(indent + line.lstrip())
+
+    def _arrange_indent(self, buf):
+        """arrange indentation of statements in buf"""
+        block = self.parse_lines(buf)
+        buf[:] = []
+        self._join_block(block, buf, 0)
+
+
+    def render(self, context=None, globals=None, _buf=None):
+        """Evaluate python code with context dictionary.
+           If _buf is None then return the result of evaluation as str,
+           else return None.
+
+           context:dict (=None)
+             Context object to evaluate. If None then new dict is created.
+           globals:dict (=None)
+             Global object. If None then globals() is used.
+           _buf:list (=None)
+             If None then new list is created.
+        """
+        if context is None:
+            locals = context = {}
+        elif self.args is None:
+            locals = context.copy()
+        else:
+            locals = {}
+            if '_engine' in context:
+                context.get('_engine').hook_context(locals)
+        locals['_context'] = context
+        if globals is None:
+            globals = sys._getframe(1).f_globals
+        bufarg = _buf
+        if _buf is None:
+            _buf = []
+        locals['_buf'] = _buf
+        if not self.bytecode:
+            self.compile()
+        if self.trace:
+            _buf.append("<!-- ***** begin: %s ***** -->\n" % self.filename)
+            exec(self.bytecode, globals, locals)
+            _buf.append("<!-- ***** end: %s ***** -->\n" % self.filename)
+        else:
+            exec(self.bytecode, globals, locals)
+        if bufarg is not None:
+            return bufarg
+        elif not logger:
+            return ''.join(_buf)
+        else:
+            try:
+                return ''.join(_buf)
+            except UnicodeDecodeError, ex:
+                logger.error("[tenjin.Template] " + str(ex))
+                logger.error("[tenjin.Template] (_buf=%r)" % (_buf, ))
+                raise
+
+    def compile(self):
+        """compile self.script into self.bytecode"""
+        self.bytecode = compile(self.script, self.filename or '(tenjin)', 'exec')
+
+
+##
+## preprocessor class
+##
+
+class Preprocessor(Template):
+    """Template class for preprocessing."""
+
+    STMT_PATTERN = (r'<\?PY( |\t|\r?\n)(.*?) ?\?>([ \t]*\r?\n)?', re.S)
+
+    EXPR_PATTERN = (r'#\{\{(.*?)\}\}|\$\{\{(.*?)\}\}|\{#=(?:=(.*?)=|(.*?))=#\}', re.S)
+
+    def add_expr(self, buf, code, *flags):
+        if not code or code.isspace():
+            return
+        code = "_decode_params(%s)" % code
+        Template.add_expr(self, buf, code, *flags)
+
+
+class TemplatePreprocessor(object):
+    factory = Preprocessor
+
+    def __init__(self, factory=None):
+        if factory is not None: self.factory = factory
+        self.globals = sys._getframe(1).f_globals
+
+    def __call__(self, input, **kwargs):
+        filename = kwargs.get('filename')
+        context  = kwargs.get('context') or {}
+        globals  = kwargs.get('globals') or self.globals
+        template = self.factory()
+        template.convert(input, filename)
+        return template.render(context, globals=globals)
+
+
+class TrimPreprocessor(object):
+
+    _rexp     = re.compile(r'^[ \t]+<', re.M)
+    _rexp_all = re.compile(r'^[ \t]+',  re.M)
+
+    def __init__(self, all=False):
+        self.all = all
+
+    def __call__(self, input, **kwargs):
+        if self.all:
+            return self._rexp_all.sub('', input)
+        else:
+            return self._rexp.sub('<', input)
+
+
+class PrefixedLinePreprocessor(object):
+
+    def __init__(self, prefix='::(?=[ \t]|$)'):
+        self.prefix = prefix
+        self.regexp = re.compile(r'^([ \t]*)' + prefix + r'(.*)', re.M)
+
+    def convert_prefixed_lines(self, text):
+        fn = lambda m: "%s<?py%s ?>" % (m.group(1), m.group(2))
+        return self.regexp.sub(fn, text)
+
+    STMT_REXP = re.compile(r'<\?py\s.*?\?>', re.S)
+
+    def __call__(self, input, **kwargs):
+        buf = []; append = buf.append
+        pos = 0
+        for m in self.STMT_REXP.finditer(input):
+            text = input[pos:m.start()]
+            stmt = m.group(0)
+            pos = m.end()
+            if text: append(self.convert_prefixed_lines(text))
+            append(stmt)
+        rest = input[pos:]
+        if rest: append(self.convert_prefixed_lines(rest))
+        return "".join(buf)
+
+
+class ParseError(Exception):
+    pass
+
+
+class JavaScriptPreprocessor(object):
+
+    def __init__(self, **attrs):
+        self._attrs = attrs
+
+    def __call__(self, input, **kwargs):
+        return self.parse(input, kwargs.get('filename'))
+
+    def parse(self, input, filename=None):
+        buf = []
+        self._parse_chunks(input, buf, filename)
+        return ''.join(buf)
+
+    CHUNK_REXP = re.compile(r'(?:^( *)<|<)!-- *#(?:JS: (\$?\w+(?:\.\w+)*\(.*?\))|/JS:?) *-->([ \t]*\r?\n)?', re.M)
+
+    def _scan_chunks(self, input, filename):
+        rexp = self.CHUNK_REXP
+        pos = 0
+        curr_funcdecl = None
+        for m in rexp.finditer(input):
+            lspace, funcdecl, rspace = m.groups()
+            text = input[pos:m.start()]
+            pos = m.end()
+            if funcdecl:
+                if curr_funcdecl:
+                    raise ParseError("%s is nested in %s. (file: %s, line: %s)" % \
+                                         (funcdecl, curr_funcdecl, filename, _linenum(input, m.start()), ))
+                curr_funcdecl = funcdecl
+            else:
+                if not curr_funcdecl:
+                    raise ParseError("unexpected '<!-- #/JS -->'. (file: %s, line: %s)" % \
+                                         (filename, _linenum(input, m.start()), ))
+                curr_funcdecl = None
+            yield text, lspace, funcdecl, rspace, False
+        if curr_funcdecl:
+            raise ParseError("%s is not closed by '<!-- #/JS -->'. (file: %s, line: %s)" % \
+                                 (curr_funcdecl, filename, _linenum(input, m.start()), ))
+        rest = input[pos:]
+        yield rest, None, None, None, True
+
+    def _parse_chunks(self, input, buf, filename=None):
+        if not input: return
+        stag = '<script'
+        if self._attrs:
+            for k in self._attrs:
+                stag = "".join((stag, ' ', k, '="', self._attrs[k], '"'))
+        stag += '>'
+        etag = '</script>'
+        for text, lspace, funcdecl, rspace, end_p in self._scan_chunks(input, filename):
+            if end_p: break
+            if funcdecl:
+                buf.append(text)
+                if re.match(r'^\$?\w+\(', funcdecl):
+                    buf.extend((lspace or '', stag, 'function ', funcdecl, "{var _buf='';", rspace or ''))
+                else:
+                    m = re.match(r'(.+?)\((.*)\)', funcdecl)
+                    buf.extend((lspace or '', stag, m.group(1), '=function(', m.group(2), "){var _buf='';", rspace or ''))
+            else:
+                self._parse_stmts(text, buf)
+                buf.extend((lspace or '', "return _buf;};", etag, rspace or ''))
+            #
+        buf.append(text)
+
+    STMT_REXP = re.compile(r'(?:^( *)<|<)\?js(\s.*?) ?\?>([ \t]*\r?\n)?', re.M | re.S)
+
+    def _scan_stmts(self, input):
+        rexp = self.STMT_REXP
+        pos = 0
+        for m in rexp.finditer(input):
+            lspace, code, rspace = m.groups()
+            text = input[pos:m.start()]
+            pos = m.end()
+            yield text, lspace, code, rspace, False
+        rest = input[pos:]
+        yield rest, None, None, None, True
+
+    def _parse_stmts(self, input, buf):
+        if not input: return
+        for text, lspace, code, rspace, end_p in self._scan_stmts(input):
+            if end_p: break
+            if lspace is not None and rspace is not None:
+                self._parse_exprs(text, buf)
+                buf.extend((lspace, code, rspace))
+            else:
+                if lspace:
+                    text += lspace
+                self._parse_exprs(text, buf)
+                buf.append(code)
+                if rspace:
+                    self._parse_exprs(rspace, buf)
+        if text:
+            self._parse_exprs(text, buf)
+
+    s = r'(?:\{[^{}]*?\}[^{}]*?)*'
+    EXPR_REXP = re.compile(r'\{=(.*?)=\}|([$#])\{(.*?' + s + r')\}', re.S)
+    del s
+
+    def _get_expr(self, m):
+        code1, ch, code2 = m.groups()
+        if ch:
+            code = code2
+            escape_p = ch == '$'
+        elif code1[0] == code1[-1] == '=':
+            code = code1[1:-1]
+            escape_p = False
+        else:
+            code = code1
+            escape_p = True
+        return code, escape_p
+
+    def _scan_exprs(self, input):
+        rexp = self.EXPR_REXP
+        pos = 0
+        for m in rexp.finditer(input):
+            text = input[pos:m.start()]
+            pos = m.end()
+            code, escape_p = self._get_expr(m)
+            yield text, code, escape_p, False
+        rest = input[pos:]
+        yield rest, None, None, True
+
+    def _parse_exprs(self, input, buf):
+        if not input: return
+        buf.append("_buf+=")
+        extend = buf.extend
+        op = ''
+        for text, code, escape_p, end_p in self._scan_exprs(input):
+            if end_p:
+                break
+            if text:
+                extend((op, self._escape_text(text)))
+                op = '+'
+            if code:
+                extend((op, escape_p and '_E(' or '_S(', code, ')'))
+                op = '+'
+        rest = text
+        if rest:
+            extend((op, self._escape_text(rest)))
+        if input.endswith("\n"):
+            buf.append(";\n")
+        else:
+            buf.append(";")
+
+    def _escape_text(self, text):
+        lines = text.splitlines(True)
+        fn = self._escape_str
+        s = "\\\n".join( fn(line) for line in lines )
+        return "".join(("'", s, "'"))
+
+    def _escape_str(self, string):
+        return string.replace("\\", "\\\\").replace("'", "\\'").replace("\n", r"\n")
+
+
+def _linenum(input, pos):
+    return input[0:pos].count("\n") + 1
+
+
+JS_FUNC = r"""
+function _S(x){return x==null?'':x;}
+function _E(x){return x==null?'':typeof(x)!=='string'?x:x.replace(/[&<>"']/g,_EF);}
+var _ET={'&':"&amp;",'<':"&lt;",'>':"&gt;",'"':"&quot;","'":"&#039;"};
+function _EF(c){return _ET[c];};
+"""[1:-1]
+JS_FUNC = escaped.EscapedStr(JS_FUNC)
+
+
+
+##
+## cache storages
+##
+
+class CacheStorage(object):
+    """[abstract] Template object cache class (in memory and/or file)"""
+
+    def __init__(self):
+        self.items = {}    # key: full path, value: template object
+
+    def get(self, cachepath, create_template):
+        """get template object. if not found, load attributes from cache file and restore  template object."""
+        template = self.items.get(cachepath)
+        if not template:
+            dct = self._load(cachepath)
+            if dct:
+                template = create_template()
+                for k in dct:
+                    setattr(template, k, dct[k])
+                self.items[cachepath] = template
+        return template
+
+    def set(self, cachepath, template):
+        """set template object and save template attributes into cache file."""
+        self.items[cachepath] = template
+        dct = self._save_data_of(template)
+        return self._store(cachepath, dct)
+
+    def _save_data_of(self, template):
+        return { 'args'  : template.args,   'bytecode' : template.bytecode,
+                 'script': template.script, 'timestamp': template.timestamp }
+
+    def unset(self, cachepath):
+        """remove template object from dict and cache file."""
+        self.items.pop(cachepath, None)
+        return self._delete(cachepath)
+
+    def clear(self):
+        """remove all template objects and attributes from dict and cache file."""
+        d, self.items = self.items, {}
+        for k in d.iterkeys():
+            self._delete(k)
+        d.clear()
+
+    def _load(self, cachepath):
+        """(abstract) load dict object which represents template object attributes from cache file."""
+        raise NotImplementedError.new("%s#_load(): not implemented yet." % self.__class__.__name__)
+
+    def _store(self, cachepath, template):
+        """(abstract) load dict object which represents template object attributes from cache file."""
+        raise NotImplementedError.new("%s#_store(): not implemented yet." % self.__class__.__name__)
+
+    def _delete(self, cachepath):
+        """(abstract) remove template object from cache file."""
+        raise NotImplementedError.new("%s#_delete(): not implemented yet." % self.__class__.__name__)
+
+
+class MemoryCacheStorage(CacheStorage):
+
+    def _load(self, cachepath):
+        return None
+
+    def _store(self, cachepath, template):
+        pass
+
+    def _delete(self, cachepath):
+        pass
+
+
+class FileCacheStorage(CacheStorage):
+
+    def _load(self, cachepath):
+        if not _isfile(cachepath): return None
+        if logger: logger.info("[tenjin.%s] load cache (file=%r)" % (self.__class__.__name__, cachepath))
+        data = _read_binary_file(cachepath)
+        return self._restore(data)
+
+    def _store(self, cachepath, dct):
+        if logger: logger.info("[tenjin.%s] store cache (file=%r)" % (self.__class__.__name__, cachepath))
+        data = self._dump(dct)
+        _write_binary_file(cachepath, data)
+
+    def _restore(self, data):
+        raise NotImplementedError("%s._restore(): not implemented yet." % self.__class__.__name__)
+
+    def _dump(self, dct):
+        raise NotImplementedError("%s._dump(): not implemented yet." % self.__class__.__name__)
+
+    def _delete(self, cachepath):
+        _ignore_not_found_error(lambda: os.unlink(cachepath))
+
+
+class MarshalCacheStorage(FileCacheStorage):
+
+    def _restore(self, data):
+        return marshal.loads(data)
+
+    def _dump(self, dct):
+        return marshal.dumps(dct)
+
+
+class PickleCacheStorage(FileCacheStorage):
+
+    def __init__(self, *args, **kwargs):
+        global pickle
+        if pickle is None:
+            import cPickle as pickle
+        FileCacheStorage.__init__(self, *args, **kwargs)
+
+    def _restore(self, data):
+        return pickle.loads(data)
+
+    def _dump(self, dct):
+        dct.pop('bytecode', None)
+        return pickle.dumps(dct)
+
+
+class TextCacheStorage(FileCacheStorage):
+
+    def _restore(self, data):
+        header, script = data.split("\n\n", 1)
+        timestamp = encoding = args = None
+        for line in header.split("\n"):
+            key, val = line.split(": ", 1)
+            if   key == 'timestamp':  timestamp = float(val)
+            elif key == 'encoding':   encoding  = val
+            elif key == 'args':       args      = val.split(', ')
+        if encoding: script = script.decode(encoding)   ## binary(=str) to unicode
+        return {'args': args, 'script': script, 'timestamp': timestamp}
+
+    def _dump(self, dct):
+        s = dct['script']
+        if dct.get('encoding') and isinstance(s, unicode):
+            s = s.encode(dct['encoding'])           ## unicode to binary(=str)
+        sb = []
+        sb.append("timestamp: %s\n" % dct['timestamp'])
+        if dct.get('encoding'):
+            sb.append("encoding: %s\n" % dct['encoding'])
+        if dct.get('args') is not None:
+            sb.append("args: %s\n" % ', '.join(dct['args']))
+        sb.append("\n")
+        sb.append(s)
+        s = ''.join(sb)
+        if python3:
+            if isinstance(s, str):
+                s = s.encode(dct.get('encoding') or 'utf-8')   ## unicode(=str) to binary
+        return s
+
+    def _save_data_of(self, template):
+        dct = FileCacheStorage._save_data_of(self, template)
+        dct['encoding'] = template.encoding
+        return dct
+
+
+
+##
+## abstract class for data cache
+##
+class KeyValueStore(object):
+
+    def get(self, key, *options):
+        raise NotImplementedError("%s.get(): not implemented yet." % self.__class__.__name__)
+
+    def set(self, key, value, *options):
+        raise NotImplementedError("%s.set(): not implemented yet." % self.__class__.__name__)
+
+    def delete(self, key, *options):
+        raise NotImplementedError("%s.del(): not implemented yet." % self.__class__.__name__)
+
+    def has(self, key, *options):
+        raise NotImplementedError("%s.has(): not implemented yet." % self.__class__.__name__)
+
+
+##
+## memory base data cache
+##
+class MemoryBaseStore(KeyValueStore):
+
+    def __init__(self):
+        self.values = {}
+
+    def get(self, key, original_timestamp=None):
+        tupl = self.values.get(key)
+        if not tupl:
+            return None
+        value, created_at, expires_at = tupl
+        if original_timestamp is not None and created_at < original_timestamp:
+            self.delete(key)
+            return None
+        if expires_at < _time():
+            self.delete(key)
+            return None
+        return value
+
+    def set(self, key, value, lifetime=0):
+        created_at = _time()
+        expires_at = lifetime and created_at + lifetime or 0
+        self.values[key] = (value, created_at, expires_at)
+        return True
+
+    def delete(self, key):
+        try:
+            del self.values[key]
+            return True
+        except KeyError:
+            return False
+
+    def has(self, key):
+        pair = self.values.get(key)
+        if not pair:
+            return False
+        value, created_at, expires_at = pair
+        if expires_at and expires_at < _time():
+            self.delete(key)
+            return False
+        return True
+
+
+##
+## file base data cache
+##
+class FileBaseStore(KeyValueStore):
+
+    lifetime = 604800   # = 60*60*24*7
+
+    def __init__(self, root_path, encoding=None):
+        if not os.path.isdir(root_path):
+            raise ValueError("%r: directory not found." % (root_path, ))
+        self.root_path = root_path
+        if encoding is None and python3:
+            encoding = 'utf-8'
+        self.encoding = encoding
+
+    _pat = re.compile(r'[^-.\/\w]')
+
+    def filepath(self, key, _pat1=_pat):
+        return os.path.join(self.root_path, _pat1.sub('_', key))
+
+    def get(self, key, original_timestamp=None):
+        fpath = self.filepath(key)
+        #if not _isfile(fpath): return None
+        stat = _ignore_not_found_error(lambda: os.stat(fpath), None)
+        if stat is None:
+            return None
+        created_at = stat.st_ctime
+        expires_at = stat.st_mtime
+        if original_timestamp is not None and created_at < original_timestamp:
+            self.delete(key)
+            return None
+        if expires_at < _time():
+            self.delete(key)
+            return None
+        if self.encoding:
+            f = lambda: _read_text_file(fpath, self.encoding)
+        else:
+            f = lambda: _read_binary_file(fpath)
+        return _ignore_not_found_error(f, None)
+
+    def set(self, key, value, lifetime=0):
+        fpath = self.filepath(key)
+        dirname = os.path.dirname(fpath)
+        if not os.path.isdir(dirname):
+            os.makedirs(dirname)
+        now = _time()
+        if isinstance(value, _unicode):
+            value = value.encode(self.encoding or 'utf-8')
+        _write_binary_file(fpath, value)
+        expires_at = now + (lifetime or self.lifetime)  # timestamp
+        os.utime(fpath, (expires_at, expires_at))
+        return True
+
+    def delete(self, key):
+        fpath = self.filepath(key)
+        ret = _ignore_not_found_error(lambda: os.unlink(fpath), False)
+        return ret != False
+
+    def has(self, key):
+        fpath = self.filepath(key)
+        if not _isfile(fpath):
+            return False
+        if _getmtime(fpath) < _time():
+            self.delete(key)
+            return False
+        return True
+
+
+
+##
+## html fragment cache helper class
+##
+class FragmentCacheHelper(object):
+    """html fragment cache helper class."""
+
+    lifetime = 60   # 1 minute
+    prefix   = None
+
+    def __init__(self, store, lifetime=None, prefix=None):
+        self.store = store
+        if lifetime is not None:  self.lifetime = lifetime
+        if prefix   is not None:  self.prefix   = prefix
+
+    def not_cached(self, cache_key, lifetime=None):
+        """(obsolete. use cache_as() instead of this.)
+           html fragment cache helper. see document of FragmentCacheHelper class."""
+        context = sys._getframe(1).f_locals['_context']
+        context['_cache_key'] = cache_key
+        key = self.prefix and self.prefix + cache_key or cache_key
+        value = self.store.get(key)
+        if value:    ## cached
+            if logger: logger.debug('[tenjin.not_cached] %r: cached.' % (cache_key, ))
+            context[key] = value
+            return False
+        else:        ## not cached
+            if logger: logger.debug('[tenjin.not_cached]: %r: not cached.' % (cache_key, ))
+            if key in context: del context[key]
+            if lifetime is None:  lifetime = self.lifetime
+            context['_cache_lifetime'] = lifetime
+            helpers.start_capture(cache_key, _depth=2)
+            return True
+
+    def echo_cached(self):
+        """(obsolete. use cache_as() instead of this.)
+           html fragment cache helper. see document of FragmentCacheHelper class."""
+        f_locals = sys._getframe(1).f_locals
+        context = f_locals['_context']
+        cache_key = context.pop('_cache_key')
+        key = self.prefix and self.prefix + cache_key or cache_key
+        if key in context:    ## cached
+            value = context.pop(key)
+        else:                 ## not cached
+            value = helpers.stop_capture(False, _depth=2)
+            lifetime = context.pop('_cache_lifetime')
+            self.store.set(key, value, lifetime)
+        f_locals['_buf'].append(value)
+
+    def functions(self):
+        """(obsolete. use cache_as() instead of this.)"""
+        return (self.not_cached, self.echo_cached)
+
+    def cache_as(self, cache_key, lifetime=None):
+        key = self.prefix and self.prefix + cache_key or cache_key
+        _buf = sys._getframe(1).f_locals['_buf']
+        value = self.store.get(key)
+        if value:
+            if logger: logger.debug('[tenjin.cache_as] %r: cache found.' % (cache_key, ))
+            _buf.append(value)
+        else:
+            if logger: logger.debug('[tenjin.cache_as] %r: expired or not cached yet.' % (cache_key, ))
+            _buf_len = len(_buf)
+            yield None
+            value = ''.join(_buf[_buf_len:])
+            self.store.set(key, value, lifetime)
+
+## you can change default store by 'tenjin.helpers.fragment_cache.store = ...'
+helpers.fragment_cache = FragmentCacheHelper(MemoryBaseStore())
+helpers.not_cached  = helpers.fragment_cache.not_cached
+helpers.echo_cached = helpers.fragment_cache.echo_cached
+helpers.cache_as    = helpers.fragment_cache.cache_as
+helpers.__all__.extend(('not_cached', 'echo_cached', 'cache_as'))
+
+
+
+##
+## helper class to find and read template
+##
+class Loader(object):
+
+    def exists(self, filepath):
+        raise NotImplementedError("%s.exists(): not implemented yet." % self.__class__.__name__)
+
+    def find(self, filename, dirs=None):
+        #: if dirs provided then search template file from it.
+        if dirs:
+            for dirname in dirs:
+                filepath = os.path.join(dirname, filename)
+                if self.exists(filepath):
+                    return filepath
+        #: if dirs not provided then just return filename if file exists.
+        else:
+            if self.exists(filename):
+                return filename
+        #: if file not found then return None.
+        return None
+
+    def abspath(self, filename):
+        raise NotImplementedError("%s.abspath(): not implemented yet." % self.__class__.__name__)
+
+    def timestamp(self, filepath):
+        raise NotImplementedError("%s.timestamp(): not implemented yet." % self.__class__.__name__)
+
+    def load(self, filepath):
+        raise NotImplementedError("%s.timestamp(): not implemented yet." % self.__class__.__name__)
+
+
+
+##
+## helper class to find and read files
+##
+class FileSystemLoader(Loader):
+
+    def exists(self, filepath):
+        #: return True if filepath exists as a file.
+        return os.path.isfile(filepath)
+
+    def abspath(self, filepath):
+        #: return full-path of filepath
+        return os.path.abspath(filepath)
+
+    def timestamp(self, filepath):
+        #: return mtime of file
+        return _getmtime(filepath)
+
+    def load(self, filepath):
+        #: if file exists, return file content and mtime
+        def f():
+            mtime = _getmtime(filepath)
+            input = _read_template_file(filepath)
+            mtime2 = _getmtime(filepath)
+            if mtime != mtime2:
+                mtime = mtime2
+                input = _read_template_file(filepath)
+                mtime2 = _getmtime(filepath)
+                if mtime != mtime2:
+                    if logger:
+                        logger.warn("[tenjin] %s.load(): timestamp is changed while reading file." % self.__class__.__name__)
+            return input, mtime
+        #: if file not exist, return None
+        return _ignore_not_found_error(f)
+
+
+##
+##
+##
+class TemplateNotFoundError(Exception):
+    pass
+
+
+
+##
+## template engine class
+##
+
+class Engine(object):
+    """Template Engine class.
+       See User's Guide and examples for details.
+       http://www.kuwata-lab.com/tenjin/pytenjin-users-guide.html
+       http://www.kuwata-lab.com/tenjin/pytenjin-examples.html
+    """
+
+    ## default value of attributes
+    prefix     = ''
+    postfix    = ''
+    layout     = None
+    templateclass = Template
+    path       = None
+    cache      = TextCacheStorage()  # save converted Python code into text file
+    lang       = None
+    loader     = FileSystemLoader()
+    preprocess = False
+    preprocessorclass = Preprocessor
+    timestamp_interval = 1  # seconds
+
+    def __init__(self, prefix=None, postfix=None, layout=None, path=None, cache=True, preprocess=None, templateclass=None, preprocessorclass=None, lang=None, loader=None, pp=None, **kwargs):
+        """Initializer of Engine class.
+
+           prefix:str (='')
+             Prefix string used to convert template short name to template filename.
+           postfix:str (='')
+             Postfix string used to convert template short name to template filename.
+           layout:str (=None)
+             Default layout template name.
+           path:list of str(=None)
+             List of directory names which contain template files.
+           cache:bool or CacheStorage instance (=True)
+             Cache storage object to store converted python code.
+             If True, default cache storage (=Engine.cache) is used (if it is None
+             then create MarshalCacheStorage object for each engine object).
+             If False, no cache storage is used nor no cache files are created.
+           preprocess:bool(=False)
+             Activate preprocessing or not.
+           templateclass:class (=Template)
+             Template class which engine creates automatically.
+           lang:str (=None)
+             Language name such as 'en', 'fr', 'ja', and so on. If you specify
+             this, cache file path will be 'inex.html.en.cache' for example.
+           pp:list (=None)
+             List of preprocessor object which is callable and manipulates template content.
+           kwargs:dict
+             Options for Template class constructor.
+             See document of Template.__init__() for details.
+        """
+        if prefix:  self.prefix  = prefix
+        if postfix: self.postfix = postfix
+        if layout:  self.layout  = layout
+        if templateclass: self.templateclass = templateclass
+        if preprocessorclass: self.preprocessorclass = preprocessorclass
+        if path is not None:  self.path = path
+        if lang is not None:  self.lang = lang
+        if loader is not None: self.loader = loader
+        if preprocess is not None: self.preprocess = preprocess
+        if   pp is None:            pp = []
+        elif isinstance(pp, list):  pass
+        elif isinstance(pp, tuple): pp = list(pp)
+        else:
+            raise TypeError("'pp' expected to be a list but got %r." % (pp,))
+        self.pp = pp
+        if preprocess:
+            self.pp.append(TemplatePreprocessor(self.preprocessorclass))
+        self.kwargs = kwargs
+        self.encoding = kwargs.get('encoding')
+        self._filepaths = {}   # template_name => relative path and absolute path
+        self._added_templates = {}   # templates added by add_template()
+        #self.cache = cache
+        self._set_cache_storage(cache)
+
+    def _set_cache_storage(self, cache):
+        if cache is True:
+            if not self.cache:
+                self.cache = MarshalCacheStorage()
+        elif cache is None:
+            pass
+        elif cache is False:
+            self.cache = None
+        elif isinstance(cache, CacheStorage):
+            self.cache = cache
+        else:
+            raise ValueError("%r: invalid cache object." % (cache, ))
+
+    def cachename(self, filepath):
+        #: if lang is provided then add it to cache filename.
+        if self.lang:
+            return '%s.%s.cache' % (filepath, self.lang)
+        #: return cache file name.
+        else:
+            return filepath + '.cache'
+
+    def to_filename(self, template_name):
+        """Convert template short name into filename.
+           ex.
+             >>> engine = tenjin.Engine(prefix='user_', postfix='.pyhtml')
+             >>> engine.to_filename(':list')
+             'user_list.pyhtml'
+             >>> engine.to_filename('list')
+             'list'
+        """
+        #: if template_name starts with ':', add prefix and postfix to it.
+        if template_name[0] == ':' :
+            return self.prefix + template_name[1:] + self.postfix
+        #: if template_name doesn't start with ':', just return it.
+        return template_name
+
+    def _create_template(self, input=None, filepath=None, _context=None, _globals=None):
+        #: if input is not specified then just create empty template object.
+        template = self.templateclass(None, **self.kwargs)
+        #: if input is specified then create template object and return it.
+        if input:
+            template.convert(input, filepath)
+        return template
+
+    def _preprocess(self, input, filepath, _context, _globals):
+        #if _context is None: _context = {}
+        #if _globals is None: _globals = sys._getframe(3).f_globals
+        #: preprocess template and return result
+        #preprocessor = self.preprocessorclass(filepath, input=input)
+        #return preprocessor.render(_context, globals=_globals)
+        #: preprocesses input with _context and returns result.
+        if '_engine' not in _context:
+            self.hook_context(_context)
+        for pp in self.pp:
+            input = pp.__call__(input, filename=filepath, context=_context, globals=_globals)
+        return input
+
+    def add_template(self, template):
+        self._added_templates[template.filename] = template
+
+    def _get_template_from_cache(self, cachepath, filepath):
+        #: if template not found in cache, return None
+        template = self.cache.get(cachepath, self.templateclass)
+        if not template:
+            return None
+        assert template.timestamp is not None
+        #: if checked within a sec, skip timestamp check.
+        now = _time()
+        last_checked = getattr(template, '_last_checked_at', None)
+        if last_checked and now < last_checked + self.timestamp_interval:
+            #if logger: logger.trace('[tenjin.%s] timestamp check skipped (%f < %f + %f)' % \
+            #                        (self.__class__.__name__, now, template._last_checked_at, self.timestamp_interval))
+            return template
+        #: if timestamp of template objectis same as file, return it.
+        if template.timestamp == self.loader.timestamp(filepath):
+            template._last_checked_at = now
+            return template
+        #: if timestamp of template object is different from file, clear it
+        #cache._delete(cachepath)
+        if logger: logger.info("[tenjin.%s] cache expired (filepath=%r)" % \
+                                   (self.__class__.__name__, filepath))
+        return None
+
+    def get_template(self, template_name, _context=None, _globals=None):
+        """Return template object.
+           If template object has not registered, template engine creates
+           and registers template object automatically.
+        """
+        #: accept template_name such as ':index'.
+        filename = self.to_filename(template_name)
+        #: if template object is added by add_template(), return it.
+        if filename in self._added_templates:
+            return self._added_templates[filename]
+        #: get filepath and fullpath of template
+        pair = self._filepaths.get(filename)
+        if pair:
+            filepath, fullpath = pair
+        else:
+            #: if template file is not found then raise TemplateNotFoundError.
+            filepath = self.loader.find(filename, self.path)
+            if not filepath:
+                raise TemplateNotFoundError('%s: filename not found (path=%r).' % (filename, self.path))
+            #
+            fullpath = self.loader.abspath(filepath)
+            self._filepaths[filename] = (filepath, fullpath)
+        #: use full path as base of cache file path
+        cachepath = self.cachename(fullpath)
+        #: get template object from cache
+        cache = self.cache
+        template = cache and self._get_template_from_cache(cachepath, filepath) or None
+        #: if template object is not found in cache or is expired...
+        if not template:
+            ret = self.loader.load(filepath)
+            if not ret:
+                raise TemplateNotFoundError("%r: template not found." % filepath)
+            input, timestamp = ret
+            if self.pp:   ## required for preprocessing
+                if _context is None: _context = {}
+                if _globals is None: _globals = sys._getframe(1).f_globals
+                input = self._preprocess(input, filepath, _context, _globals)
+            #: create template object.
+            template = self._create_template(input, filepath, _context, _globals)
+            #: set timestamp and filename of template object.
+            template.timestamp = timestamp
+            template._last_checked_at = _time()
+            #: save template object into cache.
+            if cache:
+                if not template.bytecode:
+                    #: ignores syntax error when compiling.
+                    try: template.compile()
+                    except SyntaxError: pass
+                cache.set(cachepath, template)
+        #else:
+        #    template.compile()
+        #:
+        template.filename = filepath
+        return template
+
+    def include(self, template_name, append_to_buf=True, **kwargs):
+        """Evaluate template using current local variables as context.
+
+           template_name:str
+             Filename (ex. 'user_list.pyhtml') or short name (ex. ':list') of template.
+           append_to_buf:boolean (=True)
+             If True then append output into _buf and return None,
+             else return stirng output.
+
+           ex.
+             <?py include('file.pyhtml') ?>
+             #{include('file.pyhtml', False)}
+             <?py val = include('file.pyhtml', False) ?>
+        """
+        #: get local and global vars of caller.
+        frame = sys._getframe(1)
+        locals  = frame.f_locals
+        globals = frame.f_globals
+        #: get _context from caller's local vars.
+        assert '_context' in locals
+        context = locals['_context']
+        #: if kwargs specified then add them into context.
+        if kwargs:
+            context.update(kwargs)
+        #: get template object with context data and global vars.
+        ## (context and globals are passed to get_template() only for preprocessing.)
+        template = self.get_template(template_name, context, globals)
+        #: if append_to_buf is true then add output to _buf.
+        #: if append_to_buf is false then don't add output to _buf.
+        if append_to_buf:  _buf = locals['_buf']
+        else:              _buf = None
+        #: render template and return output.
+        s = template.render(context, globals, _buf=_buf)
+        #: kwargs are removed from context data.
+        if kwargs:
+            for k in kwargs:
+                del context[k]
+        return s
+
+    def render(self, template_name, context=None, globals=None, layout=True):
+        """Evaluate template with layout file and return result of evaluation.
+
+           template_name:str
+             Filename (ex. 'user_list.pyhtml') or short name (ex. ':list') of template.
+           context:dict (=None)
+             Context object to evaluate. If None then new dict is used.
+           globals:dict (=None)
+             Global context to evaluate. If None then globals() is used.
+           layout:str or Bool(=True)
+             If True, the default layout name specified in constructor is used.
+             If False, no layout template is used.
+             If str, it is regarded as layout template name.
+
+           If temlate object related with the 'template_name' argument is not exist,
+           engine generates a template object and register it automatically.
+        """
+        if context is None:
+            context = {}
+        if globals is None:
+            globals = sys._getframe(1).f_globals
+        self.hook_context(context)
+        while True:
+            ## context and globals are passed to get_template() only for preprocessing
+            template = self.get_template(template_name, context, globals)
+            content  = template.render(context, globals)
+            layout   = context.pop('_layout', layout)
+            if layout is True or layout is None:
+                layout = self.layout
+            if not layout:
+                break
+            template_name = layout
+            layout = False
+            context['_content'] = content
+        context.pop('_content', None)
+        return content
+
+    def hook_context(self, context):
+        #: add engine itself into context data.
+        context['_engine'] = self
+        #context['render'] = self.render
+        #: add include() method into context data.
+        context['include'] = self.include
+
+
+##
+## safe template and engine
+##
+
+class SafeTemplate(Template):
+    """Uses 'to_escaped()' instead of 'escape()'.
+       '#{...}' is not allowed with this class. Use '[==...==]' instead.
+    """
+
+    tostrfunc  = 'to_str'
+    escapefunc = 'to_escaped'
+
+    def get_expr_and_flags(self, match):
+        return _get_expr_and_flags(match, "#{%s}: '#{}' is not allowed with SafeTemplate.")
+
+
+class SafePreprocessor(Preprocessor):
+
+    tostrfunc  = 'to_str'
+    escapefunc = 'to_escaped'
+
+    def get_expr_and_flags(self, match):
+        return _get_expr_and_flags(match, "#{{%s}}: '#{{}}' is not allowed with SafePreprocessor.")
+
+
+def _get_expr_and_flags(match, errmsg):
+    expr1, expr2, expr3, expr4 = match.groups()
+    if expr1 is not None:
+        raise TemplateSyntaxError(errmsg % match.group(1))
+    if expr2 is not None: return expr2, (True, False)   # #{...}    : call escape, not to_str
+    if expr3 is not None: return expr3, (False, True)   # [==...==] : not escape, call to_str
+    if expr4 is not None: return expr4, (True, False)   # [=...=]   : call escape, not to_str
+
+
+class SafeEngine(Engine):
+
+    templateclass     = SafeTemplate
+    preprocessorclass = SafePreprocessor
+
+
+##
+## for Google App Engine
+## (should separate into individual file or module?)
+##
+
+def _dummy():
+    global memcache, _tenjin
+    memcache = _tenjin = None      # lazy import of google.appengine.api.memcache
+    global GaeMemcacheCacheStorage, GaeMemcacheStore, init
+
+    class GaeMemcacheCacheStorage(CacheStorage):
+
+        lifetime = 0     # 0 means unlimited
+
+        def __init__(self, lifetime=None, namespace=None):
+            CacheStorage.__init__(self)
+            if lifetime is not None:  self.lifetime = lifetime
+            self.namespace = namespace
+
+        def _load(self, cachepath):
+            key = cachepath
+            if _tenjin.logger: _tenjin.logger.info("[tenjin.gae.GaeMemcacheCacheStorage] load cache (key=%r)" % (key, ))
+            return memcache.get(key, namespace=self.namespace)
+
+        def _store(self, cachepath, dct):
+            dct.pop('bytecode', None)
+            key = cachepath
+            if _tenjin.logger: _tenjin.logger.info("[tenjin.gae.GaeMemcacheCacheStorage] store cache (key=%r)" % (key, ))
+            ret = memcache.set(key, dct, self.lifetime, namespace=self.namespace)
+            if not ret:
+                if _tenjin.logger: _tenjin.logger.info("[tenjin.gae.GaeMemcacheCacheStorage] failed to store cache (key=%r)" % (key, ))
+
+        def _delete(self, cachepath):
+            key = cachepath
+            memcache.delete(key, namespace=self.namespace)
+
+
+    class GaeMemcacheStore(KeyValueStore):
+
+        lifetime = 0
+
+        def __init__(self, lifetime=None, namespace=None):
+            if lifetime is not None:  self.lifetime = lifetime
+            self.namespace = namespace
+
+        def get(self, key):
+            return memcache.get(key, namespace=self.namespace)
+
+        def set(self, key, value, lifetime=None):
+            if lifetime is None:  lifetime = self.lifetime
+            if memcache.set(key, value, lifetime, namespace=self.namespace):
+                return True
+            else:
+                if _tenjin.logger: _tenjin.logger.info("[tenjin.gae.GaeMemcacheStore] failed to set (key=%r)" % (key, ))
+                return False
+
+        def delete(self, key):
+            return memcache.delete(key, namespace=self.namespace)
+
+        def has(self, key):
+            if memcache.add(key, 'dummy', namespace=self.namespace):
+                memcache.delete(key, namespace=self.namespace)
+                return False
+            else:
+                return True
+
+
+    def init():
+        global memcache, _tenjin
+        if not memcache:
+            from google.appengine.api import memcache
+        if not _tenjin: import tenjin as _tenjin
+        ## avoid cache confliction between versions
+        ver = os.environ.get('CURRENT_VERSION_ID', '1.1')#.split('.')[0]
+        Engine.cache = GaeMemcacheCacheStorage(namespace=ver)
+        ## set fragment cache store
+        helpers.fragment_cache.store    = GaeMemcacheStore(namespace=ver)
+        helpers.fragment_cache.lifetime = 60    #  1 minute
+        helpers.fragment_cache.prefix   = 'fragment.'
+
+
+gae = create_module('tenjin.gae', _dummy,
+                    os=os, helpers=helpers, Engine=Engine,
+                    CacheStorage=CacheStorage, KeyValueStore=KeyValueStore)
+
+
+del _dummy
