diff --git a/apps/files_versions/ajax/expireAll.php b/apps/files_versions/ajax/expireAll.php
deleted file mode 100644
index 5c95885ffbdc15281bdb891967cbf0f04b34e32b..0000000000000000000000000000000000000000
--- a/apps/files_versions/ajax/expireAll.php
+++ /dev/null
@@ -1,44 +0,0 @@
-<?php
-
-/**
- * ownCloud - user_migrate
- *
- * @author Sam Tuke
- * @copyright 2012 Sam Tuke samtuke@owncloud.com
- *
- * 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/>.
- *
- */
-
-// TODO: Allow admins to expire versions of any user
-// TODO: Provide feedback as to how many versions were deleted
-
-// Check user and app status
-OCP\JSON::checkLoggedIn();
-OCP\App::checkAppEnabled('files_versions');
-OCP\JSON::callCheck();
-
-$versions = new OCA_Versions\Storage();
-
-if( $versions->expireAll() ) {
-
-	OCP\JSON::success();
-	die();
-
-} else {
-
-	OCP\JSON::error();
-	die();
-
-}
\ No newline at end of file
diff --git a/apps/files_versions/ajax/getVersions.php b/apps/files_versions/ajax/getVersions.php
index 8476e5e8a51c54312954e5e357d8ca7906defcb0..600e69cf798054bca6f9fe63a140c0e2c0cb0eca 100644
--- a/apps/files_versions/ajax/getVersions.php
+++ b/apps/files_versions/ajax/getVersions.php
@@ -4,10 +4,9 @@ OCP\JSON::checkAppEnabled('files_versions');
 $userDirectory = "/".OCP\USER::getUser()."/files";
 $source = $_GET['source'];
 
-if( OCA_Versions\Storage::isversioned( $source ) ) {
+$count = 5; //show the newest revisions
+if( ($versions = OCA_Versions\Storage::getVersions( $source, $count)) ) {
 
-	$count=5; //show the newest revisions
-	$versions = OCA_Versions\Storage::getVersions( $source, $count);
 	$versionsFormatted = array();
 
 	foreach ( $versions AS $version ) {
diff --git a/apps/files_versions/ajax/rollbackVersion.php b/apps/files_versions/ajax/rollbackVersion.php
index f1b02eb4b928647fbc567fa543890a9a521f5901..f2c211d9c1ec944247c0469c5d1ca654e8331f13 100644
--- a/apps/files_versions/ajax/rollbackVersion.php
+++ b/apps/files_versions/ajax/rollbackVersion.php
@@ -8,10 +8,9 @@ $userDirectory = "/".OCP\USER::getUser()."/files";
 $file = $_GET['file'];
 $revision=(int)$_GET['revision'];
 
-if( OCA_Versions\Storage::isversioned( $file ) ) {
-	if(OCA_Versions\Storage::rollback( $file, $revision )) {
-		OCP\JSON::success(array("data" => array( "revision" => $revision, "file" => $file )));
-	}else{
-		OCP\JSON::error(array("data" => array( "message" => "Could not revert:" . $file )));
-	}
+if(OCA_Versions\Storage::rollback( $file, $revision )) {
+	OCP\JSON::success(array("data" => array( "revision" => $revision, "file" => $file )));
+}else{
+	OCP\JSON::error(array("data" => array( "message" => "Could not revert:" . $file )));
 }
+
diff --git a/apps/files_versions/history.php b/apps/files_versions/history.php
index d4c278ebd85f0692b362c362bd820c0d484c76ab..6e27f43d576aebdcccf3c63e120176986a5ac868 100644
--- a/apps/files_versions/history.php
+++ b/apps/files_versions/history.php
@@ -52,10 +52,8 @@ if ( isset( $_GET['path'] ) ) {
 	}
 
 	// show the history only if there is something to show
-	if( OCA_Versions\Storage::isversioned( $path ) ) {
-
-		$count = 999; //show the newest revisions
-	        $versions = OCA_Versions\Storage::getVersions( $path, $count);
+	$count = 999; //show the newest revisions
+	if( ($versions = OCA_Versions\Storage::getVersions( $path, $count)) ) {
 
 		$tmpl->assign( 'versions', array_reverse( $versions ) );
 
diff --git a/apps/files_versions/js/settings-personal.js b/apps/files_versions/js/settings-personal.js
deleted file mode 100644
index 1e6b036fdab8136a0425ab6bceb2abd799c5d4ad..0000000000000000000000000000000000000000
--- a/apps/files_versions/js/settings-personal.js
+++ /dev/null
@@ -1,39 +0,0 @@
-// TODO: allow the button to be clicked only once
-
-$( document ).ready(function(){
-	//
-	$( '#expireAllBtn' ).click(
-
-		function( event ) {
-
-			// Prevent page from reloading
-			event.preventDefault();
-
-			// Show loading gif
-			$('.expireAllLoading').show();
-
-			$.getJSON(
-				OC.filePath('files_versions','ajax','expireAll.php'),
-				function(result){
-					if (result.status == 'success') {
-						$('.expireAllLoading').hide();
-						$('#expireAllBtn').html('Expiration successful');
-					} else {
-
-						// Cancel loading
-						$('#expireAllBtn').html('Expiration failed');
-
-						// Show Dialog
-						OC.dialogs.alert(
-							'Something went wrong, your files may not have been expired',
-							'An error has occurred',
-							function(){
-								$('#expireAllBtn').html(t('files_versions', 'Expire all versions')+'<img style="display: none;" class="loading" src="'+OC.filePath('core','img','loading.gif')+'" />');
-							}
-						);
-					}
-				}
-			);
-		}
-	);
-});
\ No newline at end of file
diff --git a/apps/files_versions/lib/hooks.php b/apps/files_versions/lib/hooks.php
index e897a81f7af4588de258115ca8f17003b46bdef5..5fb9dc3c3c550631fd669d7d9557782cde012394 100644
--- a/apps/files_versions/lib/hooks.php
+++ b/apps/files_versions/lib/hooks.php
@@ -39,15 +39,15 @@ class Hooks {
 	 * cleanup the versions directory if the actual file gets deleted
 	 */
 	public static function remove_hook($params) {
-		$versions_fileview = \OCP\Files::getStorage('files_versions');
-		$rel_path =  $params['path'];
-		$abs_path = \OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath('').$rel_path.'.v';
-		if(Storage::isversioned($rel_path)) {
-			$versions = Storage::getVersions($rel_path);
-			foreach ($versions as $v) {
-				unlink($abs_path . $v['version']);
-			}
-		}
+		if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
+		
+			$versions = new Storage( new \OC_FilesystemView('') );
+		
+			$path = $params[\OC_Filesystem::signal_param_path];
+		
+			if($path<>'') $versions->delete( $path );
+		
+		}
 	}
 
 	/**
@@ -58,18 +58,16 @@ class Hooks {
 	 * of the stored versions along the actual file
 	 */
 	public static function rename_hook($params) {
-		$versions_fileview = \OCP\Files::getStorage('files_versions');
-		$rel_oldpath =  $params['oldpath'];
-		$abs_oldpath = \OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath('').$rel_oldpath.'.v';
-		$abs_newpath = \OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath('').$params['newpath'].'.v';
-		if(Storage::isversioned($rel_oldpath)) {
-			$info=pathinfo($abs_newpath);
-			if(!file_exists($info['dirname'])) mkdir($info['dirname'], 0750, true);
-			$versions = Storage::getVersions($rel_oldpath);
-			foreach ($versions as $v) {
-				rename($abs_oldpath.$v['version'], $abs_newpath.$v['version']);
-			}
+		if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
+		
+			$versions = new Storage( new \OC_FilesystemView('') );
+		
+			$oldpath = $params['oldpath'];
+			$newpath = $params['newpath'];
+		
+			if($oldpath<>'' && $newpath<>'') $versions->rename( $oldpath, $newpath );
+		
 		}
 	}
-
+	
 }
diff --git a/apps/files_versions/lib/versions.php b/apps/files_versions/lib/versions.php
index 0ccaaf1095dd1079f8c991e089f94d14638bc601..f938a2dbe842331b2ba402973af3d7f60c2e833f 100644
--- a/apps/files_versions/lib/versions.php
+++ b/apps/files_versions/lib/versions.php
@@ -1,6 +1,7 @@
 <?php
 /**
  * Copyright (c) 2012 Frank Karlitschek <frank@owncloud.org>
+ *               2013 Bjoern Schiessle <schiessle@owncloud.com>
  * This file is licensed under the Affero General Public License version 3 or
  * later.
  * See the COPYING-README file.
@@ -16,24 +17,23 @@ namespace OCA_Versions;
 
 class Storage {
 
-
-	// config.php configuration:
-	//   - files_versions
-	//   - files_versionsfolder
-	//   - files_versionsblacklist
-	//   - files_versionsmaxfilesize
-	//   - files_versionsinterval
-	//   - files_versionmaxversions
-	//
-	// todo:
-	//   - finish porting to OC_FilesystemView to enable network transparency
-	//   - add transparent compression. first test if it´s worth it.
-
 	const DEFAULTENABLED=true;
-	const DEFAULTBLACKLIST='avi mp3 mpg mp4 ctmp';
-	const DEFAULTMAXFILESIZE=1048576; // 10MB
-	const DEFAULTMININTERVAL=60; // 1 min
-	const DEFAULTMAXVERSIONS=50;
+	const DEFAULTMAXSIZE=50; // unit: percentage; 50% of available disk space/quota
+	
+	private static $max_versions_per_interval = array(
+														1 => array('intervalEndsAfter' => 10,     //first 10sec, one version every 2sec
+																	'step' => 2),
+														2 => array('intervalEndsAfter' => 60,     //next minute, one version every 10sec
+																	'step' => 10),
+														3 => array('intervalEndsAfter' => 3600,     //next hour, one version every minute
+																	'step' => 60),
+														4 => array('intervalEndsAfter' => 86400,   //next 24h, one version every hour
+																	'step' => 3600),
+														5 => array('intervalEndsAfter' => 2592000,   //next 30days, one version per day
+																	'step' => 86400),
+														6 => array('intervalEndsAfter' => -1,      //until the end one version per week
+																	'step' => 604800),
+			);	
 
 	private static function getUidAndFilename($filename)
 	{
@@ -72,40 +72,11 @@ class Storage {
 				return false;
 			}
 
-			// check filetype blacklist
-			$blacklist=explode(' ', \OCP\Config::getSystemValue('files_versionsblacklist', Storage::DEFAULTBLACKLIST));
-			foreach($blacklist as $bl) {
-				$parts=explode('.', $filename);
-				$ext=end($parts);
-				if(strtolower($ext)==$bl) {
-					return false;
-				}
-			}
 			// we should have a source file to work with
 			if (!$files_view->file_exists($filename)) {
 				return false;
 			}
 
-			// check filesize
-			if($files_view->filesize($filename)>\OCP\Config::getSystemValue('files_versionsmaxfilesize', Storage::DEFAULTMAXFILESIZE)) {
-				return false;
-			}
-
-
-			// check mininterval if the file is being modified by the owner (all shared files should be versioned despite mininterval)
-			if ($uid == \OCP\User::getUser()) {
-				$versions_fileview = new \OC_FilesystemView('/'.$uid.'/files_versions');
-				$versionsName=\OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath($filename);
-				$versionsFolderName=\OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath('');
-				$matches=glob($versionsName.'.v*');
-				sort($matches);
-				$parts=explode('.v', end($matches));
-				if((end($parts)+Storage::DEFAULTMININTERVAL)>time()) {
-					return false;
-				}
-			}
-
-
 			// create all parent folders
 			$info=pathinfo($filename);
 			if(!file_exists($versionsFolderName.'/'.$info['dirname'])) {
@@ -113,14 +84,63 @@ class Storage {
 			}
 
 			// store a new version of a file
-			$users_view->copy('files'.$filename, 'files_versions'.$filename.'.v'.time());
-
+			$result = $users_view->copy('files'.$filename, 'files_versions'.$filename.'.v'.$users_view->filemtime('files'.$filename));
+			if (  ($versionsSize = \OCP\Config::getAppValue('files_versions', 'size')) === null ) {
+				$versionsSize = self::calculateSize($uid);
+			}
+			$versionsSize += $users_view->filesize('files'.$filename);
+			
 			// expire old revisions if necessary
-			Storage::expire($filename);
+			$newSize = self::expire($filename, $versionsSize);
+			
+			if ( $newSize != $versionsSize )  {
+				\OCP\Config::setAppValue('files_versions', 'size', $versionsSize);
+			}
 		}
 	}
 
 
+	/**
+	 * Delete versions of a file
+	 */
+	public static function delete($filename) {
+		list($uid, $filename) = self::getUidAndFilename($filename);
+		$versions_fileview = new \OC_FilesystemView('/'.$uid .'/files_versions');
+		
+		$abs_path = \OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath('').$filename.'.v';
+		if( ($versions = self::getVersions($filename)) ) {
+			if (  ($versionsSize = \OCP\Config::getAppValue('files_versions', 'size')) === null ) {
+				$versionsSize = self::calculateSize($uid);
+			}
+			foreach ($versions as $v) {
+				unlink($abs_path . $v['version']);
+				$versionsSize -= $v['size'];
+			}
+			\OCP\Config::setAppValue('files_versions', 'size', $versionsSize);
+		}
+	}
+	
+	/**
+	 * rename versions of a file
+	 */
+	public static function rename($oldpath, $newpath) {
+		list($uid, $oldpath) = self::getUidAndFilename($oldpath);
+		list($uidn, $newpath) = self::getUidAndFilename($newpath);
+		$versions_view = new \OC_FilesystemView('/'.$uid .'/files_versions');
+		$files_view = new \OC_FilesystemView('/'.$uid .'/files');
+		
+		if ( $files_view->is_dir($oldpath) && $versions_view->is_dir($oldpath) ) {
+			$versions_view->rename($oldpath, $newpath);
+		} else 	if ( ($versions = Storage::getVersions($oldpath)) ) {
+			$info=pathinfo($abs_newpath);
+			if(!file_exists($info['dirname'])) mkdir($info['dirname'], 0750, true);
+			$versions = Storage::getVersions($oldpath);
+			foreach ($versions as $v) {
+				$versions_view->rename($oldpath.'.v'.$v['version'], $newpath.'.v'.$v['version']);
+			}
+		}
+	}
+	
 	/**
 	 * rollback to an old version of a file.
 	 */
@@ -130,44 +150,27 @@ class Storage {
 			list($uid, $filename) = self::getUidAndFilename($filename);
 			$users_view = new \OC_FilesystemView('/'.$uid);
 
+			//first create a new version
+			$version = 'files_versions'.$filename.'.v'.$users_view->filemtime('files'.$filename);
+			if ( !$users_view->file_exists($version)) {
+				$users_view->copy('files'.$filename, 'files_versions'.$filename.'.v'.$users_view->filemtime('files'.$filename));
+				$versionCreated = true;
+			}
+			
 			// rollback
 			if( @$users_view->copy('files_versions'.$filename.'.v'.$revision, 'files'.$filename) ) {
-
+				$users_view->touch('files'.$filename, $revision);
+				Storage::expire($filename);
 				return true;
 
-			}else{
-
-				return false;
-
+			}else if ( $versionCreated ) {
+				$users_view->unlink($version);
 			}
-
 		}
+		return false;
 
 	}
 
-	/**
-	 * check if old versions of a file exist.
-	 */
-	public static function isversioned($filename) {
-		if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
-			list($uid, $filename) = self::getUidAndFilename($filename);
-			$versions_fileview = new \OC_FilesystemView('/'.$uid.'/files_versions');
-
-			$versionsName=\OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath($filename);
-
-			// check for old versions
-			$matches=glob($versionsName.'.v*');
-			if(count($matches)>0) {
-				return true;
-			}else{
-				return false;
-			}
-		}else{
-			return(false);
-		}
-	}
-
-
 
 	/**
 	 * @brief get a list of all available versions of a file in descending chronological order
@@ -187,92 +190,232 @@ class Storage {
 
 			sort( $matches );
 
-			$i = 0;
-
-			$files_view = new \OC_FilesystemView('/'.\OCP\User::getUser().'/files');
+			$files_view = new \OC_FilesystemView('/'.$uid.'/files');
 			$local_file = $files_view->getLocalFile($filename);
-			foreach( $matches as $ma ) {
 
-				$i++;
-				$versions[$i]['cur'] = 0;
+			foreach( $matches as $ma ) {
 				$parts = explode( '.v', $ma );
-				$versions[$i]['version'] = ( end( $parts ) );
+				$version = ( end( $parts ) );
+				$key = $version.'#'.$filename;
+				$versions[$key]['cur'] = 0;
+				$versions[$key]['version'] = $version;
+				$versions[$key]['path'] = $filename;
+				$versions[$key]['size'] = $versions_fileview->filesize($filename.'.v'.$version);
 
 				// if file with modified date exists, flag it in array as currently enabled version
-				( \md5_file( $ma ) == \md5_file( $local_file ) ? $versions[$i]['fileMatch'] = 1 : $versions[$i]['fileMatch'] = 0 );
+				( \md5_file( $ma ) == \md5_file( $local_file ) ? $versions[$key]['fileMatch'] = 1 : $versions[$key]['fileMatch'] = 0 );
 
 			}
 
 			$versions = array_reverse( $versions );
 
 			foreach( $versions as $key => $value ) {
-
 				// flag the first matched file in array (which will have latest modification date) as current version
 				if ( $value['fileMatch'] ) {
-
 					$value['cur'] = 1;
 					break;
-
 				}
-
 			}
 
 			$versions = array_reverse( $versions );
 
 			// only show the newest commits
 			if( $count != 0 and ( count( $versions )>$count ) ) {
-
 				$versions = array_slice( $versions, count( $versions ) - $count );
-
 			}
 
 			return( $versions );
 
-
 		} else {
-
 			// if versioning isn't enabled then return an empty array
 			return( array() );
-
 		}
 
 	}
 
+	/**
+	 * @brief get the size of all stored versions from a given user
+	 * @param $uid id from the user
+	 * @return size of vesions
+	 */
+	private static function calculateSize($uid) {
+		if( \OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true' ) {
+			$versions_fileview = new \OC_FilesystemView('/'.$uid.'/files_versions');
+			$versionsRoot = \OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath('');
+				
+			$iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($versionsRoot), \RecursiveIteratorIterator::CHILD_FIRST);
+				
+			$size = 0;
+							
+			foreach ($iterator as $path) {
+				if ( preg_match('/^.+\.v(\d+)$/', $path, $match) ) {
+					$relpath = substr($path, strlen($versionsRoot)-1);
+					$size += $versions_fileview->filesize($relpath);
+				}
+			}
+			
+			return $size;
+		}
+	}
+	
 	/**
-	 * @brief Erase a file's versions which exceed the set quota
+	 * @brief returns all stored file versions from a given user
+	 * @param $uid id to the user
+	 * @return array with contains two arrays 'all' which contains all versions sorted by age and 'by_file' which contains all versions sorted by filename
 	 */
-	public static function expire($filename) {
-		if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
-			list($uid, $filename) = self::getUidAndFilename($filename);
+	private static function getAllVersions($uid) {
+		if( \OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true' ) {
 			$versions_fileview = new \OC_FilesystemView('/'.$uid.'/files_versions');
-
-			$versionsName=\OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath($filename);
-
-			// check for old versions
-			$matches = glob( $versionsName.'.v*' );
-
-			if( count( $matches ) > \OCP\Config::getSystemValue( 'files_versionmaxversions', Storage::DEFAULTMAXVERSIONS ) ) {
-
-				$numberToDelete = count($matches) - \OCP\Config::getSystemValue( 'files_versionmaxversions', Storage::DEFAULTMAXVERSIONS );
-
-				// delete old versions of a file
-				$deleteItems = array_slice( $matches, 0, $numberToDelete );
-
-				foreach( $deleteItems as $de ) {
-
-					unlink( $versionsName.'.v'.$de );
-
+			$versionsRoot = \OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath('');
+			
+			$iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($versionsRoot), \RecursiveIteratorIterator::CHILD_FIRST);
+			
+			$versions = array();
+			
+			foreach ($iterator as $path) {
+				if ( preg_match('/^.+\.v(\d+)$/', $path, $match) ) {
+					$relpath = substr($path, strlen($versionsRoot)-1);
+					$versions[$match[1].'#'.$relpath] = array('path' => $relpath, 'timestamp' => $match[1]);
 				}
+			}
+			
+			ksort($versions);
+			
+			$i = 0;
+			
+			$result = array();
+			
+			foreach( $versions as $key => $value ) {
+				$i++;
+				$size = $versions_fileview->filesize($value['path']);
+				$filename = substr($value['path'], 0, -strlen($value['timestamp'])-2);
+
+				$result['all'][$key]['version'] = $value['timestamp'];
+				$result['all'][$key]['path'] = $filename;
+				$result['all'][$key]['size'] = $size;
+				
+				$filename = substr($value['path'], 0, -strlen($value['timestamp'])-2);
+				$result['by_file'][$filename][$key]['version'] = $value['timestamp'];
+				$result['by_file'][$filename][$key]['path'] = $filename;
+				$result['by_file'][$filename][$key]['size'] = $size;
+				
 			}
+			
+			return $result;
 		}
 	}
 
 	/**
-	 * @brief Erase all old versions of all user files
-	 * @return true/false
+	 * @brief Erase a file's versions which exceed the set quota
 	 */
-	public function expireAll() {
-		$view = \OCP\Files::getStorage('files_versions');
-		return $view->deleteAll('', true);
+	private static function expire($filename, $versionsSize = null) {
+		if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
+			list($uid, $filename) = self::getUidAndFilename($filename);			
+			$versions_fileview = new \OC_FilesystemView('/'.$uid.'/files_versions');
+			
+			// get available disk space for user
+			$quota = \OCP\Util::computerFileSize(\OC_Preferences::getValue($uid, 'files', 'quota'));
+			if ( $quota == null ) {
+				$quota = \OCP\Util::computerFileSize(\OC_Appconfig::getValue('files', 'default_quota'));
+			}
+			if ( $quota == null ) {
+				$quota = \OC_Filesystem::free_space('/');
+			}
+			
+			// make sure that we have the current size of the version history
+			if ( $versionsSize === null ) {
+				if (  ($versionsSize = \OCP\Config::getAppValue('files_versions', 'size')) === null ) {
+					$versionsSize = self::calculateSize($uid);
+				}
+			}
+
+			// calculate available space for version history
+			$rootInfo = \OC_FileCache::get('', '/'. $uid . '/files');
+			$free = $quota-$rootInfo['size']; // remaining free space for user
+			if ( $free > 0 ) {
+				$availableSpace = ($free * self::DEFAULTMAXSIZE / 100) - $versionsSize; // how much space can be used for versions
+			} else {
+				$availableSpace = $free-$versionsSize;
+			} 
+
+			// after every 1000s run reduce the number of all versions not only for the current file 
+			$random = rand(0, 1000);
+			if ($random == 0) {
+				$result = Storage::getAllVersions($uid);
+				$versions_by_file = $result['by_file'];
+				$all_versions = $result['all'];
+			} else {
+				$all_versions = Storage::getVersions($filename);
+				$versions_by_file[$filename] = $all_versions;
+			}
+			
+			$time = time();
+			
+			// it is possible to expire versions from more than one file
+			// iterate through all given files
+			foreach ($versions_by_file as $filename => $versions) {
+				$versions = array_reverse($versions);	// newest version first
+				
+				$interval = 1;
+				$step = Storage::$max_versions_per_interval[$interval]['step'];			
+				if (Storage::$max_versions_per_interval[$interval]['intervalEndsAfter'] == -1) {
+					$nextInterval = -1;
+				} else {
+					$nextInterval = $time - Storage::$max_versions_per_interval[$interval]['intervalEndsAfter'];
+				}
+				
+				$firstVersion = reset($versions);
+				$firstKey = key($versions);
+				$prevTimestamp = $firstVersion['version'];
+				$nextVersion = $firstVersion['version'] - $step;
+				$remaining_versions[$firstKey] = $firstVersion;
+				unset($versions[$firstKey]);
+				
+				foreach ($versions as $key => $version) {
+					$newInterval = true;
+					while ( $newInterval ) {
+						if ( $nextInterval == -1 || $version['version'] >= $nextInterval ) {
+							if ( $version['version'] > $nextVersion ) {
+								//distance between two version too small, delete version
+								$versions_fileview->unlink($version['path'].'.v'.$version['version']);
+								$availableSpace += $version['size'];
+								$versionsSize -= $version['size'];
+								unset($all_versions[$key]); // update array with all versions
+							} else {
+								$nextVersion = $version['version'] - $step;
+							}
+							$newInterval = false; // version checked so we can move to the next one
+						} else { // time to move on to the next interval
+							$interval++;
+							$step = Storage::$max_versions_per_interval[$interval]['step'];
+							$nextVersion = $prevTimestamp - $step;
+							if ( Storage::$max_versions_per_interval[$interval]['intervalEndsAfter'] == -1 ) {
+								$nextInterval = -1;
+							} else {
+								$nextInterval = $time - Storage::$max_versions_per_interval[$interval]['intervalEndsAfter'];
+							}
+							$newInterval = true; // we changed the interval -> check same version with new interval
+						}
+					}
+					$prevTimestamp = $version['version'];
+				}
+			}
+			
+			// check if enough space is available after versions are rearranged.
+			// if not we delete the oldest versions until we meet the size limit for versions
+			$numOfVersions = count($all_versions);
+			$i = 0; 
+			while ($availableSpace < 0) {
+				if ($i = $numOfVersions-2) break; // keep at least the last version
+				$versions_fileview->unlink($all_versions[$i]['path'].'.v'.$all_versions[$i]['version']);
+				$versionsSize -= $all_versions[$i]['size'];
+				$availableSpace += $all_versions[$i]['size'];
+				$i++;
+			}
+		
+			return $versionsSize; // finally return the new size of the version history
+		}
+		
+		return false;
 	}
 }
diff --git a/apps/files_versions/settings-personal.php b/apps/files_versions/settings-personal.php
deleted file mode 100644
index 6555bc99c3e193250255c47ab38d34688e89b399..0000000000000000000000000000000000000000
--- a/apps/files_versions/settings-personal.php
+++ /dev/null
@@ -1,7 +0,0 @@
-<?php
-
-$tmpl = new OCP\Template( 'files_versions', 'settings-personal');
-
-OCP\Util::addscript('files_versions', 'settings-personal');
-
-return $tmpl->fetchPage();
diff --git a/apps/files_versions/templates/settings-personal.php b/apps/files_versions/templates/settings-personal.php
deleted file mode 100644
index 2b313a07c8827d835f76d83ae14e559ba752ebfb..0000000000000000000000000000000000000000
--- a/apps/files_versions/templates/settings-personal.php
+++ /dev/null
@@ -1,12 +0,0 @@
-<form id="versions">
-	<fieldset class="personalblock">
-		<legend>
-			<strong><?php echo $l->t('Versions'); ?></strong>
-		</legend>
-		<button id="expireAllBtn">
-            <?php echo $l->t('Expire all versions'); ?>
-            <img style="display: none;" class="expireAllLoading" src="<?php echo OCP\Util::imagePath('core', 'loading.gif'); ?>" />
-            </button>
-            <br /><em><?php echo $l->t('This will delete all existing backup versions of your files'); ?></em>
-	</fieldset>
-</form>