docs: function(files, target, fm, isDir) {
  			var dfrd = $.Deferred(),
  				names, renames = [], hashes = {}, chkFiles = [],
  				cancel = function() {
  					var i = files.length;
  					while (--i > -1) {
  						files[i]._remove = true;
  					}
  				},
  				resolve = function() {
  					dfrd.resolve(renames, hashes);
  				},
  				check = function() {
  					var existed = [], exists = [], i, c,
  						pathStr = target !== fm.cwd().hash? fm.path(target, true) + fm.option('separator', target) : '',
  						confirm = function(ndx) {
  							var last = ndx == exists.length-1,
  								opts = {
  									cssClass : 'elfinder-confirm-upload',
  									title  : fm.i18n('cmdupload'),
  									text   : ['errExists', pathStr + exists[ndx].name, 'confirmRepl'], 
  									all    : !last,
  									accept : {
  										label    : 'btnYes',
  										callback : function(all) {
  											!last && !all
  												? confirm(++ndx)
  												: resolve();
  										}
  									},
  									reject : {
  										label    : 'btnNo',
  										callback : function(all) {
  											var i;
  			
  											if (all) {
  												i = exists.length;
  												while (ndx < i--) {
  													files[exists[i].i]._remove = true;
  												}
  											} else {
  												files[exists[ndx].i]._remove = true;
  											}
  			
  											!last && !all
  												? confirm(++ndx)
  												: resolve();
  										}
  									},
  									cancel : {
  										label    : 'btnCancel',
  										callback : function() {
  											cancel();
  											resolve();
  										}
  									},
  									buttons : [
  										{
  											label : 'btnBackup',
  											cssClass : 'elfinder-confirm-btn-backup',
  											callback : function(all) {
  												var i;
  												if (all) {
  													i = exists.length;
  													while (ndx < i--) {
  														renames.push(exists[i].name);
  													}
  												} else {
  													renames.push(exists[ndx].name);
  												}
  												!last && !all
  													? confirm(++ndx)
  													: resolve();
  											}
  										}
  									]
  								};
  							
  							if (!isDir) {
  								opts.buttons.push({
  									label : 'btnRename' + (last? '' : 'All'),
  									cssClass : 'elfinder-confirm-btn-rename',
  									callback : function() {
  										renames = null;
  										resolve();
  									}
  								});
  							}
  							if (fm.iframeCnt > 0) {
  								delete opts.reject;
  							}
  							fm.confirm(opts);
  						};
  					
  					if (! fm.file(target).read) {
  						// for dropbox type
  						resolve();
  						return;
  					}
  					
  					names = $.map(files, function(file, i) { return file.name && (!fm.UA.iOS || file.name !== 'image.jpg')? {i: i, name: file.name} : null ;});
  					
  					fm.request({
  						data : {cmd : 'ls', target : target, intersect : $.map(names, function(item) { return item.name;})},
  						notify : {type : 'preupload', cnt : 1, hideCnt : true},
  						preventDefault : true
  					})
  					.done(function(data) {
  						var existedArr, cwdItems;
  						if (data) {
  							if (data.error) {
  								cancel();
  							} else {
  								if (fm.options.overwriteUploadConfirm && fm.option('uploadOverwrite', target)) {
  									if (data.list) {
  										if (Array.isArray(data.list)) {
  											existed = data.list || [];
  										} else {
  											existedArr = [];
  											existed = $.map(data.list, function(n) {
  												if (typeof n === 'string') {
  													return n;
  												} else {
  													// support to >=2.1.11 plugin Normalizer, Sanitizer
  													existedArr = existedArr.concat(n);
  													return false;
  												}
  											});
  											if (existedArr.length) {
  												existed = existed.concat(existedArr);
  											}
  											hashes = data.list;
  										}
  										exists = $.grep(names, function(name){
  											return $.inArray(name.name, existed) !== -1 ? true : false ;
  										});
  										if (exists.length && existed.length && target == fm.cwd().hash) {
  											cwdItems = $.map(fm.files(target), function(file) { return file.name; } );
  											if ($.grep(existed, function(n) { 
  												return $.inArray(n, cwdItems) === -1? true : false;
  											}).length){
  												fm.sync();
  											}
  										}
  									}
  								}
  							}
  						}
  						if (exists.length > 0) {
  							confirm(0);
  						} else {
  							resolve();
  						}
  					})
  					.fail(function(error) {
  						cancel();
  						resolve();
  						error && fm.error(error);
  					});
  				};
  			if (fm.api >= 2.1 && typeof files[0] == 'object') {
  				check();
  			} else {
  				resolve();
  			}
  			return dfrd;
  		}