diff --git a/AUTHORS b/AUTHORS
index b701c768d3efef1541908fbbe5d96a993175595a..2404174e3285d94560ddf62efadd33c928733956 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -17,6 +17,7 @@ ownCloud is written by:
 	Sam Tuke
 	Simon Birnbach
 	Lukas Reschke
+	Christian Reiner
 	…
 
 With help from many libraries and frameworks including:
diff --git a/apps/files/js/fileactions.js b/apps/files/js/fileactions.js
index ba80c3043b889ad784196920ab2f2acfcb331bd1..0cf4a05222585c4e69fc40bf5e35257e97e927e0 100644
--- a/apps/files/js/fileactions.js
+++ b/apps/files/js/fileactions.js
@@ -157,7 +157,7 @@ $(document).ready(function(){
 		var downloadScope = 'file';
 	}
 	FileActions.register(downloadScope,'Download', OC.PERMISSION_READ, function(){return OC.imagePath('core','actions/download');},function(filename){
-		window.location=OC.filePath('files', 'ajax', 'download.php') + encodeURIComponent('?files='+encodeURIComponent(filename)+'&dir='+encodeURIComponent($('#dir').val()));
+		window.location=OC.filePath('files', 'ajax', 'download.php') + '&files='+encodeURIComponent(filename)+'&dir='+encodeURIComponent($('#dir').val());
 	});
 });
 
diff --git a/core/ajax/requesttoken.php b/core/ajax/requesttoken.php
new file mode 100644
index 0000000000000000000000000000000000000000..96d5402e621d54b485119fd26e12f836d8f1bf1a
--- /dev/null
+++ b/core/ajax/requesttoken.php
@@ -0,0 +1,41 @@
+<?php
+/**
+* ownCloud
+* @author Christian Reiner
+* @copyright 2011-2012 Christian Reiner <foss@christian-reiner.info>
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the license, or any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+*
+* You should have received a copy of the GNU Affero General Public
+* License along with this library.
+* If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+
+/**
+ * @file core/ajax/requesttoken.php
+ * @brief Ajax method to retrieve a fresh request protection token for ajax calls
+ * @return json: success/error state indicator including a fresh request token
+ * @author Christian Reiner
+ */
+require_once '../../lib/base.php';
+
+// don't load apps or filesystem for this task
+$RUNTIME_NOAPPS    = TRUE;
+$RUNTIME_NOSETUPFS = TRUE;
+
+// Sanity checks
+// using OCP\JSON::callCheck() below protects the token refreshing itself.
+//OCP\JSON::callCheck ( );
+OCP\JSON::checkLoggedIn ( );
+// hand out a fresh token
+OCP\JSON::success ( array ( 'token'   => OCP\Util::callRegister() ) );
+?>
diff --git a/core/js/eventsource.js b/core/js/eventsource.js
index e3ad7e3a671fc54e2d67c41ab80d99631c2e77db..45c63715a7e85d2ff2912fac82cf3df089b5e5cd 100644
--- a/core/js/eventsource.js
+++ b/core/js/eventsource.js
@@ -40,7 +40,7 @@ OC.EventSource=function(src,data){
 			dataStr+=name+'='+encodeURIComponent(data[name])+'&';
 		}
 	}
-	dataStr+='requesttoken='+OC.EventSource.requesttoken;
+	dataStr+='requesttoken='+OC.Request.Token;
 	if(!this.useFallBack && typeof EventSource !='undefined'){
 		this.source=new EventSource(src+'?'+dataStr);
 		this.source.onmessage=function(e){
diff --git a/core/js/requesttoken.js b/core/js/requesttoken.js
new file mode 100644
index 0000000000000000000000000000000000000000..0d78cd7e93b808ee287e96532326699253b7ad08
--- /dev/null
+++ b/core/js/requesttoken.js
@@ -0,0 +1,55 @@
+/**
+ * ownCloud
+ *
+ * @file core/js/requesttoken.js
+ * @brief Routine to refresh the Request protection request token periodically
+ * @author Christian Reiner (arkascha)
+ * @copyright 2011-2012 Christian Reiner <foss@christian-reiner.info>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the license, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this library.
+ * If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+OC.Request = {
+	// the request token
+	Token: {},
+	// the lifespan span (in secs)
+	Lifespan: {},
+	// method to refresh the local request token periodically
+	Refresh: function(){
+		// just a client side console log to preserve efficiency
+		console.log("refreshing request token (lifebeat)");
+		var dfd=new $.Deferred();
+		$.ajax({
+			type:     'POST',
+			url:      OC.filePath('core','ajax','requesttoken.php'),
+			cache:    false,
+			data:     { },
+			dataType: 'json'
+		}).done(function(response){
+			// store refreshed token inside this class
+			OC.Request.Token=response.token;
+			dfd.resolve();
+		}).fail(dfd.reject);
+		return dfd;
+	}
+}
+// accept requesttoken and lifespan into the OC namespace
+OC.Request.Token = oc_requesttoken;
+OC.Request.Lifespan = oc_requestlifespan;
+// refresh the request token periodically shortly before it becomes invalid on the server side
+setInterval(OC.Request.Refresh,Math.floor(1000*OC.Request.Lifespan*0.93)), // 93% of lifespan value, close to when the token expires
+// early bind token as additional ajax argument for every single request
+$(document).bind('ajaxSend', function(elm, xhr, s){xhr.setRequestHeader('requesttoken', OC.Request.Token);});
diff --git a/core/templates/layout.user.php b/core/templates/layout.user.php
index 679be2657d43ae277b2c51907ace102404c62106..b6d8a7604a2320b9af482079fef9f55069872573 100644
--- a/core/templates/layout.user.php
+++ b/core/templates/layout.user.php
@@ -11,6 +11,8 @@
 			var oc_webroot = '<?php echo OC::$WEBROOT; ?>';
 			var oc_appswebroots = <?php echo $_['apps_paths'] ?>;
 			var oc_current_user = '<?php echo OC_User::getUser() ?>';
+			var oc_requesttoken = '<?php echo $_['requesttoken']; ?>';
+			var oc_requestlifespan = '<?php echo $_['requestlifespan']; ?>';
 		</script>
 		<?php foreach($_['jsfiles'] as $jsfile): ?>
 			<script type="text/javascript" src="<?php echo $jsfile; ?>"></script>
@@ -24,13 +26,6 @@
 				echo '/>';
 			?>
 		<?php endforeach; ?>
-		<script type="text/javascript">
-			requesttoken = '<?php echo $_['requesttoken']; ?>';
-			OC.EventSource.requesttoken=requesttoken;
-			$(document).bind('ajaxSend', function(elm, xhr, s) {
-				xhr.setRequestHeader('requesttoken', requesttoken);
-			});
-		</script>
 	</head>
 
 	<body id="<?php echo $_['bodyid'];?>">
diff --git a/lib/base.php b/lib/base.php
index fa777cb93430b199e9166eaaa694c6d88a4c3a0e..2d82d5a40fc0bc0bff624c7c4286a932e30f6419 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -247,6 +247,8 @@ class OC{
 		OC_Util::addScript( "jquery-tipsy" );
 		OC_Util::addScript( "oc-dialogs" );
 		OC_Util::addScript( "js" );
+		// request protection token MUST be defined after the jquery library but before any $('document').ready()
+		OC_Util::addScript( "requesttoken" );
 		OC_Util::addScript( "eventsource" );
 		OC_Util::addScript( "config" );
 		//OC_Util::addScript( "multiselect" );
diff --git a/lib/connector/sabre/node.php b/lib/connector/sabre/node.php
index 55fa0dfde66a9e9fe7b5cb321858bc43f8458395..bdedc030c8834fbaf1944e336a0ae2664f13684b 100644
--- a/lib/connector/sabre/node.php
+++ b/lib/connector/sabre/node.php
@@ -23,8 +23,7 @@
 
 abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IProperties {
 	const GETETAG_PROPERTYNAME = '{DAV:}getetag';
-	const LASTMODIFIED_PROPERTYNAME_DEPRECIATED = '{DAV:}lastmodified'; // FIXME: keept for the  transition period, can be removed for OC 4.5.1 if the sync client update too
-	const GETLASTMODIFIED_PROPERTYNAME = '{DAV:}getlastmodified';
+	const LASTMODIFIED_PROPERTYNAME = '{DAV:}lastmodified';
 	
 	/**
 	 * The path to the current node
@@ -151,9 +150,8 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
 					$query->execute( array( OC_User::getUser(), $this->path, $propertyName ));
 				}
 			}
-			else { //FIXME: first part of if statement can be removed together with the LASTMODIFIED_PROPERTYNAME_DEPRECIATED const for oc4.5.1 if the sync client was updated too
-				if( strcmp( $propertyName, self::LASTMODIFIED_PROPERTYNAME_DEPRECIATED) === 0 ||
-					strcmp( $propertyName, self::GETLASTMODIFIED_PROPERTYNAME) === 0	) {
+			else {
+				if( strcmp( $propertyName, self::LASTMODIFIED_PROPERTYNAME) === 0 ) {
 					$this->touch($propertyValue);
 				} else {
 					if(!array_key_exists( $propertyName, $existing )) {
diff --git a/lib/filesystem.php b/lib/filesystem.php
index f5c10923b32c9c9dae9245c59dde4d311fc2909b..c6da826a33942ff896ffbb93b50accfb519c3434 100644
--- a/lib/filesystem.php
+++ b/lib/filesystem.php
@@ -521,12 +521,19 @@ class OC_Filesystem{
 		return self::$defaultInstance->hasUpdated($path,$time);
 	}
 
-	static public function removeETagHook($params) {
+	static public function removeETagHook($params, $root = false) {
 		if (isset($params['path'])) {
 			$path=$params['path'];
 		} else {
 			$path=$params['oldpath'];
 		}
+
+		if ($root) { // reduce path to the required part of it (no 'username/files')
+			$fakeRootView = new OC_FilesystemView($root);
+			$count = 1;
+			$path=str_replace(OC_App::getStorage("files")->getAbsolutePath(), "", $fakeRootView->getAbsolutePath($path), $count);
+		}
+
 		$path = self::normalizePath($path);
 		OC_Connector_Sabre_Node::removeETagPropertyForPath($path);
 	}
diff --git a/lib/filesystemview.php b/lib/filesystemview.php
index 02a0b521053d0723d155ce7123b6a7e6b0429b4e..2950ced5f9e6836c4eb894ba27604af246a489a9 100644
--- a/lib/filesystemview.php
+++ b/lib/filesystemview.php
@@ -451,8 +451,9 @@ class OC_FilesystemView {
 						OC_Filesystem::signal_post_write,
 						array( OC_Filesystem::signal_param_path => $path2)
 					);
-				} else { // no real copy, file comes from somewhere else, e.g. version rollback -> just update the file cache without all the other post_write actions
+				} else { // no real copy, file comes from somewhere else, e.g. version rollback -> just update the file cache and the webdav properties without all the other post_write actions
 					OC_FileCache_Update::update($path2, $this->fakeRoot);
+					OC_Filesystem::removeETagHook(array("path" => $path2), $this->fakeRoot);
 				}
 				return $result;
 			}
diff --git a/lib/search/provider/file.php b/lib/search/provider/file.php
index 135e40667b141f16667572b789aac686746b0fa3..21fae0c1ce541ee7d5e6b62859a7d6b77fdf0d48 100644
--- a/lib/search/provider/file.php
+++ b/lib/search/provider/file.php
@@ -5,29 +5,36 @@ class OC_Search_Provider_File extends OC_Search_Provider{
 		$files=OC_FileCache::search($query,true);
 		$results=array();
 		foreach($files as $fileData) {
-			$file=$fileData['path'];
-			$mime=$fileData['mimetype'];
+			$path = $fileData['path'];
+			$mime = $fileData['mimetype'];
+
+			$name = basename($path);
+			$text = '';
+			$path = urlencode($path);
 			if($mime=='httpd/unix-directory') {
-				$results[]=new OC_Search_Result(basename($file),'',OC_Helper::linkTo( 'files', 'index.php', array('dir' => $file)),'Files');
+				$link = OC_Helper::linkTo( 'files', 'index.php', array('dir' => $path));
+				$type = 'Files';
 			}else{
-				$mimeBase=$fileData['mimepart'];
+				$link = OC_Helper::linkTo( 'files', 'download.php', array('file' => $path));
+				$mimeBase = $fileData['mimepart'];
 				switch($mimeBase) {
 					case 'audio':
 						break;
 					case 'text':
-						$results[]=new OC_Search_Result(basename($file),'',OC_Helper::linkTo( 'files', 'download.php', array('file' => $file) ),'Text');
+						$type = 'Text';
 						break;
 					case 'image':
-						$results[]=new OC_Search_Result(basename($file),'',OC_Helper::linkTo( 'files', 'download.php', array('file' => $file) ),'Images');
+						$type = 'Images';
 						break;
 					default:
 						if($mime=='application/xml') {
-							$results[]=new OC_Search_Result(basename($file),'',OC_Helper::linkTo( 'files', 'download.php', array('file' => $file) ),'Text');
+							$type = 'Text';
 						}else{
-							$results[]=new OC_Search_Result(basename($file),'',OC_Helper::linkTo( 'files', 'download.php', array('file' => $file) ),'Files');
+							$type = 'Files';
 						}
 				}
 			}
+			$results[] = new OC_Search_Result($name, $text, $link, $type);
 		}
 		return $results;
 	}
diff --git a/lib/template.php b/lib/template.php
index 0987d6f0d8885cec7ffdfa8edb50b75ad51edc23..681b3f0b1404f727debb1c5a766dc9e8326d896e 100644
--- a/lib/template.php
+++ b/lib/template.php
@@ -157,6 +157,7 @@ class OC_Template{
 		$this->vars = array();
 		if($renderas == 'user') {
 			$this->vars['requesttoken'] = OC_Util::callRegister();
+			$this->vars['requestlifespan'] = OC_Util::$callLifespan;
 		}
 		$parts = explode('/', $app); // fix translation when app is something like core/lostpassword
 		$this->l10n = OC_L10N::get($parts[0]);
@@ -374,6 +375,7 @@ class OC_Template{
 			$page = new OC_TemplateLayout($this->renderas);
 			if($this->renderas == 'user') {
 				$page->assign('requesttoken', $this->vars['requesttoken']);
+				$page->assign('requestlifespan', $this->vars['requestlifespan']);
 			}
 
 			// Add custom headers
diff --git a/lib/util.php b/lib/util.php
index c89c4d8c7c1bd450c5e39b553038907b1fce0964..777cb7a28fce84763c90343a10bfaf20a8acab87 100755
--- a/lib/util.php
+++ b/lib/util.php
@@ -416,14 +416,29 @@ class OC_Util {
 	}
 
 	/**
-	 * @brief Register an get/post call. This is important to prevent CSRF attacks
-	 * Todo: Write howto
+	 * @brief Static lifespan (in seconds) when a request token expires.
+	 * @see OC_Util::callRegister()
+	 * @see OC_Util::isCallRegistered()
+	 * @description
+	 * Also required for the client side to compute the piont in time when to
+	 * request a fresh token. The client will do so when nearly 97% of the
+	 * timespan coded here has expired. 
+	 */
+	public static $callLifespan = 3600; // 3600 secs = 1 hour
+
+	/**
+	 * @brief Register an get/post call. Important to prevent CSRF attacks.
+	 * @todo Write howto: CSRF protection guide
 	 * @return $token Generated token.
+	 * @description
+	 * Creates a 'request token' (random) and stores it inside the session.
+	 * Ever subsequent (ajax) request must use such a valid token to succeed,
+	 * otherwise the request will be denied as a protection against CSRF.
+	 * The tokens expire after a fixed lifespan.
+	 * @see OC_Util::$callLifespan
+	 * @see OC_Util::isCallRegistered()
 	 */
 	public static function callRegister() {
-		//mamimum time before token exires
-		$maxtime=(60*60);  // 1 hour
-
 		// generate a random token.
 		$token=mt_rand(1000,9000).mt_rand(1000,9000).mt_rand(1000,9000);
 
@@ -436,7 +451,8 @@ class OC_Util {
 			foreach($_SESSION as $key=>$value) {
 				// search all tokens in the session
 				if(substr($key,0,12)=='requesttoken') {
-					if($value+$maxtime<time()) {
+					// check if static lifespan has expired
+					if($value+self::$callLifespan<time()) {
 						// remove outdated tokens
 						unset($_SESSION[$key]);
 					}
@@ -447,14 +463,13 @@ class OC_Util {
 		return($token);
 	}
 
-
 	/**
 	 * @brief Check an ajax get/post call if the request token is valid.
 	 * @return boolean False if request token is not set or is invalid.
+	 * @see OC_Util::$callLifespan
+	 * @see OC_Util::calLRegister()
 	 */
 	public static function isCallRegistered() {
-		//mamimum time before token exires
-		$maxtime=(60*60);  // 1 hour
 		if(isset($_GET['requesttoken'])) {
 			$token=$_GET['requesttoken'];
 		}elseif(isset($_POST['requesttoken'])) {
@@ -467,7 +482,8 @@ class OC_Util {
 		}
 		if(isset($_SESSION['requesttoken-'.$token])) {
 			$timestamp=$_SESSION['requesttoken-'.$token];
-			if($timestamp+$maxtime<time()) {
+			// check if static lifespan has expired
+			if($timestamp+self::$callLifespan<time()) {
 				return false;
 			}else{
 				//token valid
diff --git a/search/js/result.js b/search/js/result.js
index aaecde08c6b95bfbdea41ef620a8f8b8b5227bc4..cadb0d0aabec4b6b7f6076d4a5c457dbe2442e17 100644
--- a/search/js/result.js
+++ b/search/js/result.js
@@ -25,6 +25,7 @@ OC.search.showResults=function(results){
 		parent.load(OC.filePath('search','templates','part.results.php'),function(){
 			OC.search.showResults.loaded=true;
 			$('#searchresults').click(function(event){
+				OC.search.hide();
 				event.stopPropagation();
 			});
 			$(window).click(function(event){