docs: function(opts) {
  		var type     = opts.type,
  			id       = opts.id? 'elfinder-notify-'+opts.id : '',
  			msg      = this.i18n((typeof opts.msg !== 'undefined')? opts.msg : (this.messages['ntf'+type] ? 'ntf'+type : 'ntfsmth')),
  			ndialog  = this.ui.notify,
  			notify   = ndialog.children('.elfinder-notify-'+type+(id? ('.'+id) : '')),
  			button   = notify.children('div.elfinder-notify-cancel').children('button'),
  			ntpl     = '<div class="elfinder-notify elfinder-notify-{type}'+(id? (' '+id) : '')+'"><span class="elfinder-dialog-icon elfinder-dialog-icon-{type}"/><span class="elfinder-notify-msg">{msg}</span> <span class="elfinder-notify-cnt"/><div class="elfinder-notify-progressbar"><div class="elfinder-notify-progress"/></div><div class="elfinder-notify-cancel"/></div>',
  			delta    = opts.cnt,
  			size     = (typeof opts.size != 'undefined')? parseInt(opts.size) : null,
  			progress = (typeof opts.progress != 'undefined' && opts.progress >= 0) ? opts.progress : null,
  			cancel   = opts.cancel,
  			clhover  = 'ui-state-hover',
  			close    = function() {
  				notify._esc && $(document).off('keydown', notify._esc);
  				notify.remove();
  				!ndialog.children().length && ndialog.elfinderdialog('close');
  			},
  			cnt, total, prc;
  
  		if (!type) {
  			return this;
  		}
  		
  		if (!notify.length) {
  			notify = $(ntpl.replace(/\{type\}/g, type).replace(/\{msg\}/g, msg))
  				.appendTo(ndialog)
  				.data('cnt', 0);
  
  			if (progress != null) {
  				notify.data({progress : 0, total : 0});
  			}
  
  			if (cancel) {
  				button = $('<button type="button" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"><span class="ui-button-text">'+this.i18n('btnCancel')+'</span></button>')
  					.on('mouseenter mouseleave', function(e) { 
  						$(this).toggleClass(clhover, e.type === 'mouseenter');
  					});
  				notify.children('div.elfinder-notify-cancel').append(button);
  			}
  		} else if (typeof opts.msg !== 'undefined') {
  			notify.children('span.elfinder-notify-msg').html(msg);
  		}
  
  		cnt = delta + parseInt(notify.data('cnt'));
  		
  		if (cnt > 0) {
  			if (cancel && button.length) {
  				if ($.isFunction(cancel) || (typeof cancel === 'object' && cancel.promise)) {
  					notify._esc = function(e) {
  						if (e.type == 'keydown' && e.keyCode != $.ui.keyCode.ESCAPE) {
  							return;
  						}
  						e.preventDefault();
  						e.stopPropagation();
  						close();
  						if (cancel.promise) {
  							cancel.reject(0); // 0 is canceling flag
  						} else {
  							cancel(e);
  						}
  					};
  					button.on('click', function(e) {
  						notify._esc(e);
  					});
  					$(document).on('keydown.' + this.namespace, notify._esc);
  				}
  			}
  			
  			!opts.hideCnt && notify.children('.elfinder-notify-cnt').text('('+cnt+')');
  			ndialog.is(':hidden') && ndialog.elfinderdialog('open', this).height('auto');
  			notify.data('cnt', cnt);
  			
  			if ((progress != null)
  			&& (total = notify.data('total')) >= 0
  			&& (prc = notify.data('progress')) >= 0) {
  
  				total += size != null? size : delta;
  				prc   += progress;
  				(size == null && delta < 0) && (prc += delta * 100);
  				notify.data({progress : prc, total : total});
  				if (size != null) {
  					prc *= 100;
  					total = Math.max(1, total);
  				}
  				progress = parseInt(prc/total);
  				
  				notify.find('.elfinder-notify-progress')
  					.animate({
  						width : (progress < 100 ? progress : 100)+'%'
  					}, 20);
  			}
  			
  		} else {
  			close();
  		}
  		
  		return this;
  	}