$.fn.extend({
	scrollbarPaper: function(opts) {
		
		return this.each(function(i) {
			
			var settings = {
				width:17
			}
			
			var $this = $(this);
			if ($this.data('settings') == null) {
				$.extend(settings,opts);
				$this.data('settings',settings);
			} else {
				settings = $this.data('settings');
			}
		
			var paper = $this.data('paper');
			
			if (paper == null) {
				
				//get browser default scrollbar width
				var barWidth = function() {
					var div = $('<div style="width:50px;height:50px;overflow:hidden;position:absolute;top:-200px;left:-200px;"><div style="height:100px;"></div></div>');
					$('body').append(div);
					var w1 = $('div', div).innerWidth();
					div.css('overflow-y', 'scroll');
					var w2 = $('div', div).innerWidth();
					div.remove();
					return Math.max(w1 - w2, settings.width);
				}.call();
		
				//append scrollbar paper before container
				$this.before('<div class="scrollbarpaper-container" style="width:' + barWidth + 'px"><div class="scrollbarpaper-track" ><div class="scrollbarpaper-drag"></div></div></div>');
				paper = $this.prev();
				var vBorder = parseInt(paper.find('.scrollbarpaper-track').css('borderLeftWidth')) + parseInt(paper.find('.scrollbarpaper-track').css('borderRightWidth'));
				paper.find('.scrollbarpaper-track, .scrollbarpaper-drag').css('width',barWidth-vBorder);
				$this.append('<div style="clear:both;"></div>');
				$this.data('barWidth', barWidth);
				$this.data('paper', paper);
				$this.data('track', $('.scrollbarpaper-track', paper));
				$this.data('drag', $('.scrollbarpaper-drag', paper));
				$this.data('content', $('> :first', $this));
				$this.data('clearer', $('> :last', $this));
				paper.hide();
			}
		
			var barWidth = $this.data('barWidth');
			var track = $this.data('track');
			var drag = $this.data('drag');
			var content = $this.data('content');
			var clearer =	$this.data('clearer');
		
			$this.data('content', content);
			$this.data('clearer', clearer);
			$this.data('height', $this.height());
			$this.data('contentHeight', clearer.position().top);
			$this.data('position', $this.position());
		
			$this.unbind();
			var ratio = $this.height() / clearer.position().top;
			if (ratio < 1) {
        		paper.show();
        		$this.css('overflow','auto');
        		paper.height($this.height());
        		var position = $this.position();
        		paper.css({'position':'absolute','left': position.left+$this.width()-paper.width(), 'top':position.top});
        		var dragHeight = Math.max(Math.round($this.height() * ratio)-(paper.find('.scrollbarpaper-track').outerHeight()- paper.find('.scrollbarpaper-track').height()), 20);
        		drag.height(dragHeight);
        		
        		var updateDragTop = function() {
   					drag.css('top', Math.min(Math.round($this.scrollTop() * ratio), $this.height() - dragHeight));
        		};
        		updateDragTop();
        		
        		$this.scroll(function(event) {updateDragTop();});
			
				var unbindMousemove = function() { $('html').unbind('mousemove.scrollbarpaper'); };
			
				drag.mousedown(function(event) {
					unbindMousemove();
					var offsetTop = event.pageY - drag.offset().top;
					$('html').bind('mousemove.scrollbarpaper', function(event) {
						$this.scrollTop((event.pageY - $this.offset().top - offsetTop) / ratio);
						return false;
					}).mouseup(unbindMousemove);
					return false;
				});
			} else {
				$this.unbind();
				paper.hide();
			}

			var timeout = function() {
				window.setTimeout(function() {
					if (($this.height() != $this.data('height')) || (clearer.position().top - content.position().top != $this.data('contentHeight'))) {
						$this.scrollbarPaper(); 
					} else {
						timeout();
					}
				}, 200);
			}
			timeout();
		});
	}
});

