public function getFunctionName()
    {
       // function name is used as base for caching, so it must be unique for
       // every combination of settings that changes code in compiled template

       if (!$this->_functionName) {

            // just to make tempalte name recognizable
            $basename = preg_replace('/\.[a-z]{3,5}$/', '', basename($this->_source->getRealPath()));
            $basename = substr(trim(preg_replace('/[^a-zA-Z0-9]+/', '_', $basename), "_"), 0, 20);

            $hash = md5(PHPTAL_VERSION . PHP_VERSION
                    . $this->_source->getRealPath()
                    . $this->getEncoding()
                    . $this->getPrefiltersCacheId()
                    . $this->getOutputMode(),
                    true
                    );

            // uses base64 rather than hex to make filename shorter.
            // there is loss of some bits due to name constraints and case-insensivity,
            // but that's still over 110 bits in addition to basename and timestamp.
            $hash = strtr(rtrim(base64_encode($hash),"="),"+/=","_A_");

            $this->_functionName = $this->getFunctionNamePrefix($this->_source->getLastModifiedTime()) .
                                   $basename . '__' . $hash;
        }
        return $this->_functionName;
    }