/**
  * check if js or css files have changed and return all js/css as one big file or return "HTTP/1.0 304 Not Modified" if files don't have changed
  * 
  * @param string $_fileType
  * @param array $filesToWatch
  */
 protected function _deliverChangedFiles($_fileType, $filesToWatch = null)
 {
     // close session to allow other requests
     Tinebase_Session::writeClose(true);
     $config = Tinebase_Config::getInstance();
     $cacheId = null;
     $clientETag = null;
     $ifModifiedSince = null;
     if (isset($_SERVER['If_None_Match'])) {
         $clientETag = trim($_SERVER['If_None_Match'], '"');
         $ifModifiedSince = trim($_SERVER['If_Modified_Since'], '"');
     } elseif (isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
         $clientETag = trim($_SERVER['HTTP_IF_NONE_MATCH'], '"');
         $ifModifiedSince = trim($_SERVER['HTTP_IF_MODIFIED_SINCE'], '"');
     }
     $filesToWatch = $filesToWatch ? $filesToWatch : $this->_getFilesToWatch($_fileType);
     if ($_fileType == 'js' && TINE20_BUILDTYPE != 'DEVELOPMENT') {
         $customJSFiles = Tinebase_Config::getInstance()->get(Tinebase_Config::FAT_CLIENT_CUSTOM_JS);
         if (!empty($customJSFiles)) {
             $filesToWatch = array_merge($filesToWatch, (array) $customJSFiles);
         }
     }
     $lastModified = $this->_getLastModified($filesToWatch);
     // use last modified time also
     $serverETag = hash('sha1', implode('', $filesToWatch) . $lastModified);
     $cache = new Zend_Cache_Frontend_File(array('master_files' => $filesToWatch));
     $cache->setBackend(Tinebase_Core::get(Tinebase_Core::CACHE)->getBackend());
     if ($clientETag && $ifModifiedSince) {
         $cacheId = __CLASS__ . "_" . __FUNCTION__ . hash('sha1', $clientETag . $ifModifiedSince);
     }
     // cache for 60 seconds
     $maxAge = 60;
     header('Cache-Control: private, max-age=' . $maxAge);
     header("Expires: " . gmdate('D, d M Y H:i:s', Tinebase_DateTime::now()->addSecond($maxAge)->getTimestamp()) . " GMT");
     // overwrite Pragma header from session
     header("Pragma: cache");
     // if the cache id is still valid, the files don't have changed on disk
     if ($clientETag == $serverETag && $cache->test($cacheId)) {
         header("Last-Modified: " . $ifModifiedSince);
         header("HTTP/1.0 304 Not Modified");
         header('Content-Length: 0');
     } else {
         // get new cacheId
         $cacheId = __CLASS__ . "_" . __FUNCTION__ . hash('sha1', $serverETag . $lastModified);
         // do we need to update the cache? maybe the client did not send an etag
         if (!$cache->test($cacheId)) {
             $cache->save(TINE20_BUILDTYPE, $cacheId, array(), null);
         }
         header("Last-Modified: " . $lastModified);
         header('Content-Type: ' . ($_fileType == 'css' ? 'text/css' : 'application/javascript'));
         header('Etag: "' . $serverETag . '"');
         flush();
         // send files to client
         foreach ($filesToWatch as $file) {
             readfile($file);
         }
     }
 }