diff --git a/apps/files/ajax/upload.php b/apps/files/ajax/upload.php
index 8d183bd1f9c7d3ffd3a839cbe6bd51e9d6f14e37..619b5f6a04b756cb8f6c43369c9c1656b3e2a1f1 100644
--- a/apps/files/ajax/upload.php
+++ b/apps/files/ajax/upload.php
@@ -99,8 +99,8 @@ if (strpos($dir, '..') === false) {
 	$fileCount = count($files['name']);
 	for ($i = 0; $i < $fileCount; $i++) {
 		// $path needs to be normalized - this failed within drag'n'drop upload to a sub-folder
-		if (isset($_POST['new_name'])) {
-			$newName = $_POST['new_name'];
+		if (isset($_POST['newname'])) {
+			$newName = $_POST['newname'];
 		} else {
 			$newName = $files['name'][$i];
 		}
@@ -109,11 +109,12 @@ if (strpos($dir, '..') === false) {
 		} else {
 			$replace = false;
 		}
-		$target = \OC\Files\Filesystem::normalizePath(stripslashes($dir).$newName);
+		$target = \OC\Files\Filesystem::normalizePath(stripslashes($dir).'/'.$newName);
 		if ( ! $replace && \OC\Files\Filesystem::file_exists($target)) {
 			$meta = \OC\Files\Filesystem::getFileInfo($target);
 			$result[] = array('status' => 'existserror',
-				'mime' => $meta['mimetype'],
+				'type' => $meta['mimetype'],
+				'mtime' => $meta['mtime'],
 				'size' => $meta['size'],
 				'id' => $meta['fileid'],
 				'name' => basename($target),
diff --git a/apps/files/css/files.css b/apps/files/css/files.css
index acee8471aff3484a518246d16b1a2f9d646d1617..0ff25a24d76d74c4298884c196af44584a679e0c 100644
--- a/apps/files/css/files.css
+++ b/apps/files/css/files.css
@@ -190,6 +190,9 @@ table.dragshadow td.size {
 	margin-left: -200px;
 }
 
+.oc-dialog .fileexists table {
+	width: 100%;
+}
 .oc-dialog .fileexists .original .icon {
 	width: 64px;
 	height: 64px;
@@ -201,6 +204,7 @@ table.dragshadow td.size {
 
 .oc-dialog .fileexists .replacement {
 	margin-top: 20px;
+	margin-bottom: 20px;
 }
 
 .oc-dialog .fileexists .replacement .icon {
@@ -213,10 +217,23 @@ table.dragshadow td.size {
 	clear: both;
 }
 
-.oc-dialog .fileexists label[for="new-name"] {
-	margin-top: 20px;
-	display: block;
+.oc-dialog .fileexists .toggle {
+	background-image: url('%webroot%/core/img/actions/triangle-e.png');
+	width: 16px;
+	height: 16px;
+}
+.oc-dialog .fileexists #allfileslabel {
+	float:right;
 }
+.oc-dialog .fileexists #allfiles {
+	vertical-align: bottom;
+	position: relative;
+	top: -3px;
+}
+.oc-dialog .fileexists #allfiles + span{
+	vertical-align: bottom;
+}
+
 .oc-dialog .fileexists h3 {
 	font-weight: bold;
 }
diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js
index bd9757b5ffca58139c2f311013981d974f40ce0e..f8899cb07e685c45bd0c84dd0d3bae41abe581ca 100644
--- a/apps/files/js/file-upload.js
+++ b/apps/files/js/file-upload.js
@@ -1,4 +1,30 @@
 /**
+ * 1. tracking which file to upload next -> upload queue with data elements added whenever add is called
+ * 2. tracking progress for each folder individually -> track progress in a progress[dirname] object
+ *   - every new selection increases the total size and number of files for a directory
+ *   - add increases, successful done decreases, skip decreases, cancel decreases
+ * 3. track selections -> the general skip / overwrite decision is selection based and can change
+ *    - server might send already exists error -> show dialog & remember decision for selection again
+ *    - server sends error, how do we find collection?
+ * 4. track jqXHR object to prevent browser from navigationg away -> track in a uploads[dirname][filename] object [x]
+ * 
+ * selections can progress in parrallel but each selection progresses sequentially
+ * 
+ * -> store everything in context?
+ * context.folder
+ * context.element?
+ * context.progressui?
+ * context.jqXHR
+ * context.selection
+ * context.selection.onExistsAction?
+ * 
+ * context available in what events?
+ * build in drop() add dir
+ * latest in add() add file? add selection!
+ * progress? -> update progress?
+ * onsubmit -> context.jqXHR?
+ * fail() -> 
+ * done()
  * 
  * when versioning app is active -> always overwrite
  * 
@@ -22,24 +48,74 @@
  * dialoge:
  *	-> skip, replace, choose (or abort) ()
  *	-> choose left or right (with skip) (when only one file in list also show rename option and remember for all option)
+ *	
+ *	progress always based on filesize
+ *	number of files as text, bytes as bar
+ *	
  */
 
 
-OC.upload = {
+
+//TODO clean uploads when all progress has completed
+OC.Upload = {
+	/**
+	 * map to lookup the selections for a given directory.
+	 * @type Array
+	 */
+	_selections: {},
+	/*
+	 * queue which progress tracker to use for the next upload
+	 * @type Array
+	 */
+	_queue: [],
+	queueUpload:function(data) {
+		// add to queue
+		this._queue.push(data); //remember what to upload next
+		if ( ! this.isProcessing() ) {
+			this.startUpload();
+		}
+	},
+	getSelection:function(originalFiles) {
+		if (!originalFiles.selectionKey) {
+			originalFiles.selectionKey = 'selection-' + $.assocArraySize(this._selections);
+			this._selections[originalFiles.selectionKey] = {
+				selectionKey:originalFiles.selectionKey,
+				files:{},
+				totalBytes:0,
+				loadedBytes:0,
+				currentFile:0,
+				uploads:{},
+				checked:false
+			};
+		}
+		return this._selections[originalFiles.selectionKey];
+	},
+	cancelUpload:function(dir, filename) {
+		var deleted = false;
+		jQuery.each(this._selections, function(i, selection) {
+			if (selection.dir === dir && selection.uploads[filename]) {
+				delete selection.uploads[filename];
+				deleted = true;
+				return false; // end searching through selections
+			}
+		});
+		return deleted;
+	},
+	cancelUploads:function() {
+		jQuery.each(this._selections,function(i,selection){
+			jQuery.each(selection.uploads, function (j, jqXHR) {
+				delete jqXHR;
+			});
+		});
+		this._queue = [];
+		this._isProcessing = false;
+	},
 	_isProcessing:false,
 	isProcessing:function(){
 		return this._isProcessing;
 	},
-	_uploadQueue:[],
-	addUpload:function(data){
-		this._uploadQueue.push(data);
-
-		if ( ! OC.upload.isProcessing() ) {
-			OC.upload.startUpload();
-		}
-	},
 	startUpload:function(){
-		if (this._uploadQueue.length > 0) {
+		if (this._queue.length > 0) {
 			this._isProcessing = true;
 			this.nextUpload();
 			return true;
@@ -48,32 +124,50 @@ OC.upload = {
 		}
 	},
 	nextUpload:function(){
-		if (this._uploadQueue.length > 0) {
-			var data = this._uploadQueue.pop();
-			var jqXHR = data.submit();
-
-			// remember jqXHR to show warning to user when he navigates away but an upload is still in progress
-			if (typeof data.context !== 'undefined' && data.context.data('type') === 'dir') {
-				var dirName = data.context.data('file');
-				if(typeof uploadingFiles[dirName] === 'undefined') {
-					uploadingFiles[dirName] = {};
-				}
-				uploadingFiles[dirName][data.files[0].name] = jqXHR;
-			} else {
-				uploadingFiles[data.files[0].name] = jqXHR;
-			}
+		if (this._queue.length > 0) {
+			var data = this._queue.pop();
+			var selection = this.getSelection(data.originalFiles);
+			selection.uploads[data.files[0]] = data.submit();
+			
 		} else {
 			//queue is empty, we are done
 			this._isProcessing = false;
+			//TODO free data
 		}
+	},
+	progressBytes: function() {
+		var total = 0;
+		var loaded = 0;
+		jQuery.each(this._selections, function (i, selection) {
+			total += selection.totalBytes;
+			loaded += selection.loadedBytes;
+		});
+		return (loaded/total)*100;
+	},
+	loadedBytes: function() {
+		var loaded = 0;
+		jQuery.each(this._selections, function (i, selection) {
+			loaded += selection.loadedBytes;
+		});
+		return loaded;
+	},
+	totalBytes: function() {
+		var total = 0;
+		jQuery.each(this._selections, function (i, selection) {
+			total += selection.totalBytes;
+		});
+		return total;
+	},
+	handleExists:function(data) {
+
 	},
 	onCancel:function(data){
 		//TODO cancel all uploads
-		Files.cancelUploads();
-		this._uploadQueue = [];
-		this._isProcessing = false;
+		OC.Upload.cancelUploads();
 	},
 	onSkip:function(data){
+		var selection = this.getSelection(data.originalFiles);
+		selection.loadedBytes += data.loaded;
 		this.nextUpload();
 	},
 	onReplace:function(data){
@@ -83,8 +177,14 @@ OC.upload = {
 	},
 	onRename:function(data, newName){
 		//TODO rename file in filelist, stop spinner
-		data.data.append('new_name', newName);
+		data.data.append('newname', newName);
 		data.submit();
+	},
+	setAction:function(data, action) {
+		
+	},
+	setDefaultAction:function(action) {
+		
 	}
 };
 
@@ -92,15 +192,23 @@ $(document).ready(function() {
 
 	var file_upload_param = {
 		dropZone: $('#content'), // restrict dropZone to content div
+		
 		//singleFileUploads is on by default, so the data.files array will always have length 1
 		add: function(e, data) {
 			var that = $(this);
-
-			if (typeof data.originalFiles.checked === 'undefined') {
+			
+			// lookup selection for dir
+			var selection = OC.Upload.getSelection(data.originalFiles);
+			
+			if (!selection.dir) {
+				selection.dir = $('#dir').val();
+			}
+			
+			if ( ! selection.checked ) {
 				
-				var totalSize = 0;
+				selection.totalBytes = 0;
 				$.each(data.originalFiles, function(i, file) {
-					totalSize += file.size;
+					selection.totalBytes += file.size;
 
 					if (file.type === '' && file.size === 4096) {
 						data.textStatus = 'dirorzero';
@@ -111,11 +219,10 @@ $(document).ready(function() {
 					}
 				});
 
-				if (totalSize > $('#max_upload').val()) {
+				if (selection.totalBytes > $('#max_upload').val()) {
 					data.textStatus = 'notenoughspace';
 					data.errorThrown = t('files', 'Not enough space available');
 				}
-
 				if (data.errorThrown) {
 					//don't upload anything
 					var fu = that.data('blueimp-fileupload') || that.data('fileupload');
@@ -123,9 +230,22 @@ $(document).ready(function() {
 					return false;
 				}
 				
-				data.originalFiles.checked = true; // this will skip the checks on subsequent adds
+				//TODO refactor away:
+				//show cancel button
+				if($('html.lte9').length === 0 && data.dataType !== 'iframe') {
+					$('#uploadprogresswrapper input.stop').show();
+				}
 			}
 			
+			//all subsequent add calls for this selection can be ignored
+			//allow navigating to the selection from a context
+			//context.selection = data.originalFiles.selection;
+			
+			//allow navigating to contexts / files of a selection
+			selection.files[data.files[0].name] = data;
+			
+			OC.Upload.queueUpload(data);
+			
 			//TODO check filename already exists
 			/*
 			if ($('tr[data-file="'+data.files[0].name+'"][data-id]').length > 0) {
@@ -140,14 +260,6 @@ $(document).ready(function() {
 			}
 			*/
 
-			//add files to queue
-			OC.upload.addUpload(data);
-			
-			//TODO refactor away:
-			//show cancel button
-			if($('html.lte9').length === 0 && data.dataType !== 'iframe') {
-				$('#uploadprogresswrapper input.stop').show();
-			}
 			return true;
 		},
 		/**
@@ -176,7 +288,8 @@ $(document).ready(function() {
 					$('#notification').fadeOut();
 				}, 5000);
 			}
-			delete uploadingFiles[data.files[0].name];
+			var selection = OC.Upload.getSelection(data.originalFiles);
+			delete selection.uploads[data.files[0]];
 		},
 		progress: function(e, data) {
 			// TODO: show nice progress bar in file row
@@ -186,7 +299,8 @@ $(document).ready(function() {
 			if($('html.lte9').length > 0) {
 				return;
 			}
-			var progress = (data.loaded/data.total)*100;
+			//var progress = (data.loaded/data.total)*100;
+			var progress = OC.Upload.progressBytes();
 			$('#uploadprogressbar').progressbar('value', progress);
 		},
 		/**
@@ -204,27 +318,22 @@ $(document).ready(function() {
 				response = data.result[0].body.innerText;
 			}
 			var result=$.parseJSON(response);
+			var selection = OC.Upload.getSelection(data.originalFiles);
 
-			if(typeof result[0] !== 'undefined' && result[0].status === 'success') {
-				OC.upload.nextUpload();
+			if(typeof result[0] !== 'undefined'
+				&& result[0].status === 'success'
+			) {
+				selection.loadedBytes+=data.loaded;
+				OC.Upload.nextUpload();
 			} else {
 				if (result[0].status === 'existserror') {
-					//TODO open dialog and retry with other name?
-					// get jqXHR reference
-					if (typeof data.context !== 'undefined' && data.context.data('type') === 'dir') {
-						var dirName = data.context.data('file');
-						var jqXHR = uploadingFiles[dirName][filename];
-					} else {
-						var jqXHR = uploadingFiles[filename];
-					}
-					//filenames can only be changed on the server side
-					//TODO show "file already exists" dialog
-					//options: abort | skip | replace / rename
-							//TODO reset all-files flag? when done with selection?
+					//show "file already exists" dialog
 					var original = result[0];
 					var replacement = data.files[0];
-					OC.dialogs.fileexists(data, original, replacement, OC.upload);
+					var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload');
+					OC.dialogs.fileexists(data, original, replacement, OC.Upload, fu);
 				} else {
+					delete selection.uploads[data.files[0]];
 					data.textStatus = 'servererror';
 					data.errorThrown = t('files', result.data.message);
 					var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload');
@@ -232,19 +341,6 @@ $(document).ready(function() {
 				}
 			}
 
-			var filename = result[0].originalname;
-
-			// delete jqXHR reference
-			if (typeof data.context !== 'undefined' && data.context.data('type') === 'dir') {
-				var dirName = data.context.data('file');
-				delete uploadingFiles[dirName][filename];
-				if ($.assocArraySize(uploadingFiles[dirName]) === 0) {
-					delete uploadingFiles[dirName];
-				}
-			} else {
-				delete uploadingFiles[filename];
-			}
-
 		},
 		/**
 		 * called after last upload
@@ -252,17 +348,20 @@ $(document).ready(function() {
 		 * @param data
 		 */
 		stop: function(e, data) {
-			if(data.dataType !== 'iframe') {
-				$('#uploadprogresswrapper input.stop').hide();
-			}
+			if(OC.Upload.progressBytes()>=100) {
 
-			//IE < 10 does not fire the necessary events for the progress bar.
-			if($('html.lte9').length > 0) {
-				return;
-			}
+				if(data.dataType !== 'iframe') {
+					$('#uploadprogresswrapper input.stop').hide();
+				}
 
-			$('#uploadprogressbar').progressbar('value', 100);
-			$('#uploadprogressbar').fadeOut();
+				//IE < 10 does not fire the necessary events for the progress bar.
+				if($('html.lte9').length > 0) {
+					return;
+				}
+
+				$('#uploadprogressbar').progressbar('value', 100);
+				$('#uploadprogressbar').fadeOut();
+			}
 		}
 	};
 	
diff --git a/apps/files/js/fileactions.js b/apps/files/js/fileactions.js
index aa66a57a7b5e994eb0d04041761eb1a62c770306..277abcfdb15dbeb56d8602cd288a90f9c94b3b88 100644
--- a/apps/files/js/fileactions.js
+++ b/apps/files/js/fileactions.js
@@ -174,7 +174,7 @@ $(document).ready(function () {
 FileActions.register('all', 'Delete', OC.PERMISSION_DELETE, function () {
 	return OC.imagePath('core', 'actions/delete');
 }, function (filename) {
-	if (Files.cancelUpload(filename)) {
+	if (OC.Upload.cancelUpload($('#dir').val(), filename)) {
 		if (filename.substr) {
 			filename = [filename];
 		}
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index f4863837ce79d3c7e1b139a8d925b7c31074e623..335f81e04b91324b339087922f2eeda915b84b6e 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -407,151 +407,212 @@ $(document).ready(function(){
 
 	// handle upload events
 	var file_upload_start = $('#file_upload_start');
+	
 	file_upload_start.on('fileuploaddrop', function(e, data) {
-		// only handle drop to dir if fileList exists
-		if ($('#fileList').length > 0) {
-			var dropTarget = $(e.originalEvent.target).closest('tr');
-			if(dropTarget && dropTarget.data('type') === 'dir') { // drag&drop upload to folder
-				data.context = dropTarget;
-				var dirName = dropTarget.data('file');
-				// update folder in form
-				data.formData = function(form) {
-					var formArray = form.serializeArray();
-					// array index 0 contains the max files size
-					// array index 1 contains the request token
-					// array index 2 contains the directory
-					var parentDir = formArray[2]['value'];
-					if (parentDir === '/') {
-						formArray[2]['value'] += dirName;
-					} else {
-						formArray[2]['value'] += '/'+dirName;
-					}
-					return formArray;
-				};
+		console.log('fileuploaddrop ' +OC.Upload.loadedBytes()+' / '+OC.Upload.totalBytes());
+		
+		var dropTarget = $(e.originalEvent.target).closest('tr');
+		if(dropTarget && dropTarget.data('type') === 'dir') { // drag&drop upload to folder
+			
+			// lookup selection for dir
+			var selection = OC.Upload.getSelection(data.files);
+			
+			// remember drop target
+			selection.dropTarget = dropTarget;
+			
+			selection.dir = dropTarget.data('file');
+			if (selection.dir !== '/') {
+				if ($('#dir').val() === '/') {
+					selection.dir = '/' + selection.dir;
+				} else {
+					selection.dir = $('#dir').val() + '/' + selection.dir;
+				}
 			}
-		}
+			
+			// update folder in form
+			data.formData = function(form) {
+				var formArray = form.serializeArray();
+				// array index 0 contains the max files size
+				// array index 1 contains the request token
+				// array index 2 contains the directory
+				var parentDir = formArray[2]['value'];
+				if (parentDir === '/') {
+					formArray[2]['value'] += selection.dir;
+				} else {
+					formArray[2]['value'] += '/' + selection.dir;
+				}
+				
+				return formArray;
+			};
+		} 
+		
 	});
 	file_upload_start.on('fileuploadadd', function(e, data) {
-		// only add to fileList if it exists
-		if ($('#fileList').length > 0) {
+		console.log('fileuploadadd ' +OC.Upload.loadedBytes()+' / '+OC.Upload.totalBytes());
+
+		// lookup selection for dir
+		var selection = OC.Upload.getSelection(data.originalFiles);
+			
+		if(FileList.deleteFiles && FileList.deleteFiles.indexOf(data.files[0].name)!==-1){//finish delete if we are uploading a deleted file
+			FileList.finishDelete(null, true); //delete file before continuing
+		}
+		
+		// add ui visualization to existing folder
+		if(selection.dropTarget && selection.dropTarget.data('type') === 'dir') {
+			// add to existing folder
+			var dirName = selection.dropTarget.data('file');
+
+			// set dir context
+			data.context = $('tr').filterAttr('data-type', 'dir').filterAttr('data-file', dirName);
 
-			if(FileList.deleteFiles && FileList.deleteFiles.indexOf(data.files[0].name)!==-1){//finish delete if we are uploading a deleted file
-				FileList.finishDelete(null, true); //delete file before continuing
+			// update upload counter ui
+			var uploadtext = data.context.find('.uploadtext');
+			var currentUploads = parseInt(uploadtext.attr('currentUploads'));
+			currentUploads += 1;
+			uploadtext.attr('currentUploads', currentUploads);
+			
+			if(currentUploads === 1) {
+				var img = OC.imagePath('core', 'loading.gif');
+				data.context.find('td.filename').attr('style','background-image:url('+img+')');
+				uploadtext.text(t('files', '1 file uploading'));
+				uploadtext.show();
+			} else {
+				uploadtext.text(currentUploads + ' ' + t('files', 'files uploading'));
 			}
+		}
+		
+	});
+	file_upload_start.on('fileuploaddone', function(e, data) {
+		console.log('fileuploaddone ' +OC.Upload.loadedBytes()+' / '+OC.Upload.totalBytes());
+		
+		var response;
+		if (typeof data.result === 'string') {
+			response = data.result;
+		} else {
+			// fetch response from iframe
+			response = data.result[0].body.innerText;
+		}
+		var result=$.parseJSON(response);
 
-			// add ui visualization to existing folder
-			var dropTarget = $(e.originalEvent.target).closest('tr');
-			if(dropTarget && dropTarget.data('type') === 'dir') {
-				// add to existing folder
-				var dirName = dropTarget.data('file');
+		if(typeof result[0] !== 'undefined' && result[0].status === 'success') {
+			var file = result[0];
 
-				// set dir context
-				data.context = $('tr').filterAttr('data-type', 'dir').filterAttr('data-file', dirName);
+			if (data.context && data.context.data('type') === 'dir') {
 
 				// update upload counter ui
 				var uploadtext = data.context.find('.uploadtext');
 				var currentUploads = parseInt(uploadtext.attr('currentUploads'));
-				currentUploads += 1;
+				currentUploads -= 1;
 				uploadtext.attr('currentUploads', currentUploads);
-				if(currentUploads === 1) {
-					var img = OC.imagePath('core', 'loading.gif');
+				if(currentUploads === 0) {
+					var img = OC.imagePath('core', 'filetypes/folder.png');
 					data.context.find('td.filename').attr('style','background-image:url('+img+')');
-					uploadtext.text(t('files', '1 file uploading'));
-					uploadtext.show();
+					uploadtext.text('');
+					uploadtext.hide();
 				} else {
 					uploadtext.text(currentUploads + ' ' + t('files', 'files uploading'));
 				}
-			}
-		}
-	});
-	file_upload_start.on('fileuploaddone', function(e, data) {
-		// only update the fileList if it exists
-		if ($('#fileList').length > 0) {
-			var response;
-			if (typeof data.result === 'string') {
-				response = data.result;
+				
+				// update folder size
+				var size = parseInt(data.context.data('size'));
+				size += parseInt(file.size);
+				data.context.attr('data-size', size);
+				data.context.find('td.filesize').text(humanFileSize(size));
+				
 			} else {
-				// fetch response from iframe
-				response = data.result[0].body.innerText;
-			}
-			var result=$.parseJSON(response);
-
-			if(typeof result[0] !== 'undefined' && result[0].status === 'success') {
-				var file = result[0];
-
-				if (data.context && data.context.data('type') === 'dir') {
-					
-					// update upload counter ui
-					var uploadtext = data.context.find('.uploadtext');
-					var currentUploads = parseInt(uploadtext.attr('currentUploads'));
-					currentUploads -= 1;
-					uploadtext.attr('currentUploads', currentUploads);
-					if(currentUploads === 0) {
-						var img = OC.imagePath('core', 'filetypes/folder.png');
-						data.context.find('td.filename').attr('style','background-image:url('+img+')');
-						uploadtext.text('');
-						uploadtext.hide();
-					} else {
-						uploadtext.text(currentUploads + ' ' + t('files', 'files uploading'));
-					}
 
-					// update folder size
-					var size =  parseInt(data.context.data('size'));
-					size +=  parseInt(file.size)	;
-					data.context.attr('data-size', size);
-					data.context.find('td.filesize').text(humanFileSize(size));
+				// add as stand-alone row to filelist
+				var size=t('files','Pending');
+				if (data.files[0].size>=0){
+					size=data.files[0].size;
+				}
+				var date=new Date();
+				var param = {};
+				if ($('#publicUploadRequestToken').length) {
+					param.download_url = document.location.href + '&download&path=/' + $('#dir').val() + '/' + file.name;
+				}
+				//should the file exist in the list remove it
+				FileList.remove(file.name);
+				
+				// create new file context
+				data.context = FileList.addFile(file.name, file.size, date, false, false, param);
 
-				} else {
-					
-					// add as stand-alone row to filelist
-					var uniqueName = getUniqueName(data.files[0].name);
-					var size=t('files','Pending');
-					if (data.files[0].size>=0){
-						size=data.files[0].size;
-					}
-					var date=new Date();
-					var param = {};
-					if ($('#publicUploadRequestToken').length) {
-						param.download_url = document.location.href + '&download&path=/' + $('#dir').val() + '/' + uniqueName;
-					}
-					
-					//should the file exist in the list remove it
-					FileList.remove(file.name);
+				// update file data
+				data.context.attr('data-mime',file.mime).attr('data-id',file.id);
 
-					// create new file context
-					data.context = FileList.addFile(file.name, file.size, date, false, false, param);
-				
-					// update file data
-					data.context.attr('data-mime',file.mime).attr('data-id',file.id);
-					
-					getMimeIcon(file.mime, function(path){
-						data.context.find('td.filename').attr('style','background-image:url('+path+')');
-					});
-				}
+				getMimeIcon(file.mime, function(path){
+					data.context.find('td.filename').attr('style','background-image:url('+path+')');
+				});
 			}
 		}
 	});
+	
+	file_upload_start.on('fileuploadalways', function(e, data) {
+		console.log('fileuploadalways ' +OC.Upload.loadedBytes()+' / '+OC.Upload.totalBytes());
+	});
+	file_upload_start.on('fileuploadsend', function(e, data) {
+		console.log('fileuploadsend ' +OC.Upload.loadedBytes()+' / '+OC.Upload.totalBytes());
+		
+		// TODOD add vis
+		//data.context.element = 
+	});
+	file_upload_start.on('fileuploadprogress', function(e, data) {
+		console.log('fileuploadprogress ' +OC.Upload.loadedBytes()+' / '+OC.Upload.totalBytes());
+	});
+	file_upload_start.on('fileuploadprogressall', function(e, data) {
+		console.log('fileuploadprogressall ' +OC.Upload.loadedBytes()+' / '+OC.Upload.totalBytes());
+	});
+	file_upload_start.on('fileuploadstop', function(e, data) {
+		console.log('fileuploadstop ' +OC.Upload.loadedBytes()+' / '+OC.Upload.totalBytes());
+	});
+	file_upload_start.on('fileuploadfail', function(e, data) {
+		console.log('fileuploadfail ' +OC.Upload.loadedBytes()+' / '+OC.Upload.totalBytes());
+	});
+	/*
 	file_upload_start.on('fileuploadfail', function(e, data) {
-		// only update the fileList if it exists
+		console.log('fileuploadfail'+((data.files&&data.files.length>0)?' '+data.files[0].name:''));
+		
+		// if we are uploading to a subdirectory
+		if (data.context && data.context.data('type') === 'dir') {
+
+			// update upload counter ui
+			var uploadtext = data.context.find('.uploadtext');
+			var currentUploads = parseInt(uploadtext.attr('currentUploads'));
+			currentUploads -= 1;
+			uploadtext.attr('currentUploads', currentUploads);
+			if(currentUploads === 0) {
+				var img = OC.imagePath('core', 'filetypes/folder.png');
+				data.context.find('td.filename').attr('style','background-image:url('+img+')');
+				uploadtext.text('');
+				uploadtext.hide();
+			} else {
+				uploadtext.text(currentUploads + ' ' + t('files', 'files uploading'));
+			}
+
+		}
+		
 		// cleanup files, error notification has been shown by fileupload code
 		var tr = data.context;
 		if (typeof tr === 'undefined') {
 			tr = $('tr').filterAttr('data-file', data.files[0].name);
 		}
 		if (tr.attr('data-type') === 'dir') {
+			
 			//cleanup uploading to a dir
 			var uploadtext = tr.find('.uploadtext');
 			var img = OC.imagePath('core', 'filetypes/folder.png');
 			tr.find('td.filename').attr('style','background-image:url('+img+')');
 			uploadtext.text('');
 			uploadtext.hide(); //TODO really hide already
+			
 		} else {
+			//TODO add row when sending file
 			//remove file
 			tr.fadeOut();
 			tr.remove();
 		}
 	});
-
+*/
 	$('#notification').hide();
 	$('#notification').on('click', '.undo', function(){
 		if (FileList.deleteFiles) {
diff --git a/apps/files/js/files.js b/apps/files/js/files.js
index 3fad3fae7d39ed34b063541c43da59a92fea96ee..a907aeab1fc49485ee8f68f47e5a7e3f804ac473 100644
--- a/apps/files/js/files.js
+++ b/apps/files/js/files.js
@@ -1,31 +1,5 @@
 var uploadingFiles = {};
 Files={
-	cancelUpload:function(filename) {
-		if(uploadingFiles[filename]) {
-			uploadingFiles[filename].abort();
-			delete uploadingFiles[filename];
-			return true;
-		}
-		return false;
-	},
-	cancelUploads:function() {
-		$.each(uploadingFiles,function(index,file) {
-			if(typeof file['abort'] === 'function') {
-				file.abort();
-				var filename = $('tr').filterAttr('data-file',index);
-				filename.hide();
-				filename.find('input[type="checkbox"]').removeAttr('checked');
-				filename.removeClass('selected');
-			} else {
-				$.each(file,function(i,f) {
-					f.abort();
-					delete file[i];
-				});
-			}
-			delete uploadingFiles[index];
-		});
-		procesSelection();
-	},
 	updateMaxUploadFilesize:function(response) {
 		if(response == undefined) {
 			return;
@@ -117,7 +91,8 @@ $(document).ready(function() {
 
 	// Trigger cancelling of file upload
 	$('#uploadprogresswrapper .stop').on('click', function() {
-		Files.cancelUploads();
+		OC.Upload.cancelUploads();
+		procesSelection();
 	});
 
 	// Show trash bin
diff --git a/apps/files_sharing/js/public.js b/apps/files_sharing/js/public.js
index 294223aa094844640debf983731e83820dfae26f..a20b4ae636fa762ed60a8ed13f02f4ace0c8cbdb 100644
--- a/apps/files_sharing/js/public.js
+++ b/apps/files_sharing/js/public.js
@@ -62,7 +62,10 @@ $(document).ready(function() {
   // Add Uploadprogress Wrapper to controls bar
   $('#controls').append($('#additional_controls div#uploadprogresswrapper'));
 
-  // Cancel upload trigger
-  $('#cancel_upload_button').click(Files.cancelUploads);
+	// Cancel upload trigger
+	$('#cancel_upload_button').click(function() {
+		OC.Upload.cancelUploads();
+		procesSelection();
+	});
 
 });
diff --git a/core/js/oc-dialogs.js b/core/js/oc-dialogs.js
index 88a3f6628cb930af32f8c2816cdf32e210c2be2c..ea03ef214556b3906a5fcb14cff62654cc3ed399 100644
--- a/core/js/oc-dialogs.js
+++ b/core/js/oc-dialogs.js
@@ -207,105 +207,142 @@ var OCdialogs = {
 	 * @param {object} controller a controller with onCancel, onSkip, onReplace and onRename methods
 	*/
 	fileexists:function(data, original, replacement, controller) {
-		if (typeof controller !== 'object') {
-			controller = {};
-		}
-		var self = this;
-		$.when(this._getFileExistsTemplate()).then(function($tmpl) {
-			var dialog_name = 'oc-dialog-fileexists-' + OCdialogs.dialogs_counter + '-content';
-			var dialog_id = '#' + dialog_name;
-			var title = t('files','Replace »{filename}«?',{filename: original.name});
-			var $dlg = $tmpl.octemplate({
-				dialog_name: dialog_name,
-				title: title,
-				type: 'fileexists',
-				
-				why: t('files','Another file with the same name already exists in "{dir}".',{dir:'somedir'}),
-				what: t('files','Replacing it will overwrite it\'s contents.'),
-				original_heading: t('files','Original file'),
-				original_size: t('files','Size: {size}',{size: original.size}),
-				original_mtime: t('files','Last changed: {mtime}',{mtime: original.mtime}),
+		var selection = controller.getSelection(data.originalFiles);
+		if (selection.defaultAction) {
+			controller[selection.defaultAction](data);
+		} else {
+			$.when(this._getFileExistsTemplate()).then(function($tmpl) {
+				var dialog_name = 'oc-dialog-fileexists-' + OCdialogs.dialogs_counter + '-content';
+				var dialog_id = '#' + dialog_name;
+				var title = t('files','Replace »{filename}«?',{filename: original.name});
+				var original_size= t('files','Size: {size}',{size: original.size});
+				var original_mtime = t('files','Last changed: {mtime}',{mtime: original.mtime});
+				var replacement_size= t('files','Size: {size}',{size: replacement.size});
+				var replacement_mtime = t('files','Last changed: {mtime}',{mtime: replacement.mtime});
+				var $dlg = $tmpl.octemplate({
+					dialog_name: dialog_name,
+					title: title,
+					type: 'fileexists',
 
-				replacement_heading: t('files','Replace with'),
-				replacement_size: t('files','Size: {size}',{size: replacement.size}),
-				replacement_mtime: t('files','Last changed: {mtime}',{mtime: replacement.mtime}),
+					why: t('files','Another file with the same name already exists in "{dir}".',{dir:'somedir'}),
+					what: t('files','Replacing it will overwrite it\'s contents.'),
+					original_heading: t('files','Original file'),
+					original_size: original_size,
+					original_mtime: original_mtime,
 
-				new_name_label: t('files','Choose a new name for the target.'),
-				all_files_label: t('files','Use this action for all files.')
-			});
-			$('body').append($dlg);
-			
-			$(dialog_id + ' .original .icon').css('background-image','url('+OC.imagePath('core', 'filetypes/file.png')+')');
-			$(dialog_id + ' .replacement .icon').css('background-image','url('+OC.imagePath('core', 'filetypes/file.png')+')');
-			$(dialog_id + ' #new-name').val(original.name);
-			
-			
-			$(dialog_id + ' #new-name').on('keyup', function(e){
-				if ($(dialog_id + ' #new-name').val() === original.name) {
-					
-					$(dialog_id + ' + div .rename').removeClass('primary').hide();
-					$(dialog_id + ' + div .replace').addClass('primary').show();
-				} else {
-					$(dialog_id + ' + div .rename').addClass('primary').show();
-					$(dialog_id + ' + div .replace').removeClass('primary').hide();
-				}
-			});
+					replacement_heading: t('files','Replace with'),
+					replacement_size: replacement_size,
+					replacement_mtime: replacement_mtime,
 
-			buttonlist = [{
-					text: t('core', 'Cancel'),
-					classes: 'cancel',
-					click: function(){
-						if ( typeof controller.onCancel !== 'undefined') {
-							controller.onCancel(data);
-						}
-						$(dialog_id).ocdialog('close');
+					new_name_label: t('files','Choose a new name for the target.'),
+					all_files_label: t('files','Use this action for all files.')
+				});
+				$('body').append($dlg);
+
+				getMimeIcon(original.type,function(path){
+					$(dialog_id + ' .original .icon').css('background-image','url('+path+')');
+				});
+				getMimeIcon(replacement.type,function(path){
+					$(dialog_id + ' .replacement .icon').css('background-image','url('+path+')');
+				});
+				$(dialog_id + ' #newname').val(original.name);
+
+
+				$(dialog_id + ' #newname').on('keyup', function(e){
+					if ($(dialog_id + ' #newname').val() === original.name) {
+						$(dialog_id + ' + div .rename').removeClass('primary').hide();
+						$(dialog_id + ' + div .replace').addClass('primary').show();
+					} else {
+						$(dialog_id + ' + div .rename').addClass('primary').show();
+						$(dialog_id + ' + div .replace').removeClass('primary').hide();
 					}
-				},
-				{
-					text: t('core', 'Skip'),
-					classes: 'skip',
-					click: function(){
-						if ( typeof controller.onSkip !== 'undefined') {
-							controller.onSkip(data);
+				});
+
+				buttonlist = [{
+						text: t('core', 'Cancel'),
+						classes: 'cancel',
+						click: function(){
+							if ( typeof controller.onCancel !== 'undefined') {
+								controller.onCancel(data);
+							}
+							$(dialog_id).ocdialog('close');
 						}
-						$(dialog_id).ocdialog('close');
-					}
-				},
-				{
-					text: t('core', 'Replace'),
-					classes: 'replace',
-					click: function(){
-						if ( typeof controller.onReplace !== 'undefined') {
-							controller.onReplace(data);
+					},
+					{
+						text: t('core', 'Skip'),
+						classes: 'skip',
+						click: function(){
+							if ( typeof controller.onSkip !== 'undefined') {
+								if($(dialog_id + ' #allfiles').prop('checked')){
+									selection.defaultAction = 'onSkip';
+									/*selection.defaultAction = function(){
+										controller.onSkip(data);
+									};*/
+								}
+								controller.onSkip(data);
+							}
+							// trigger fileupload done with status skip
+							//data.result[0].status = 'skip';
+							//fileupload._trigger('done', data.e, data);
+							$(dialog_id).ocdialog('close');
 						}
-						$(dialog_id).ocdialog('close');
 					},
-					defaultButton: true
-				},
-				{
-					text: t('core', 'Rename'),
-					classes: 'rename',
-					click: function(){
-						if ( typeof controller.onRename !== 'undefined') {
-							controller.onRename(data, $(dialog_id + ' #new-name').val());
+					{
+						text: t('core', 'Replace'),
+						classes: 'replace',
+						click: function(){
+							if ( typeof controller.onReplace !== 'undefined') {
+								if($(dialog_id + ' #allfiles').prop('checked')){
+									selection.defaultAction = 'onReplace';
+									/*selection.defaultAction = function(){
+										controller.onReplace(data);
+									};*/
+								}
+								controller.onReplace(data);
+							}
+							$(dialog_id).ocdialog('close');
+						},
+						defaultButton: true
+					},
+					{
+						text: t('core', 'Rename'),
+						classes: 'rename',
+						click: function(){
+							if ( typeof controller.onRename !== 'undefined') {
+								//TODO use autorename when repeat is checked
+								controller.onRename(data, $(dialog_id + ' #newname').val());
+							}
+							$(dialog_id).ocdialog('close');
 						}
-						$(dialog_id).ocdialog('close');
-					}
-				}];
+					}];
 
-			$(dialog_id).ocdialog({
-				closeOnEscape: true,
-				modal: true,
-				buttons: buttonlist,
-				closeButton: null
+				$(dialog_id).ocdialog({
+					width: 500,
+					closeOnEscape: true,
+					modal: true,
+					buttons: buttonlist,
+					closeButton: null
+				});
+				OCdialogs.dialogs_counter++;
+
+				$(dialog_id + ' + div .rename').hide();
+				$(dialog_id + ' #newname').hide();
+				
+				$(dialog_id + ' #newnamecb').on('change', function(){
+					if ($(dialog_id + ' #newnamecb').prop('checked')) {
+						$(dialog_id + ' #newname').fadeIn();
+					} else {
+						$(dialog_id + ' #newname').fadeOut();
+						$(dialog_id + ' #newname').val(original.name);
+					}
+				});
+				
+				
+			})
+			.fail(function() {
+				alert(t('core', 'Error loading file exists template'));
 			});
-			OCdialogs.dialogs_counter++;
-			
-			$(dialog_id + ' + div .rename').hide();
-		})
-		.fail(function() {
-			alert(t('core', 'Error loading file exists template'));
-		});
+		}
 	},
 	_getFilePickerTemplate: function() {
 		var defer = $.Deferred();