function iPadScroller(contentDivName,parentDivName) {
	var self = this;

	// Connect the content area and add the event listeners
	var contentDiv = document.getElementById(contentDivName);
	contentDiv.addEventListener('touchstart', function(e) { return self.onTouchStart(e) }, false);
	contentDiv.addEventListener('click', function(e) { return self.onClick(e) },true);
 
	contentDiv.addEventListener('touchmove', function(e) { return self.onTouchMove(e) }, false);
	contentDiv.addEventListener('touchend', function(e) { return self.onTouchEnd(e) }, false);

	this.contentDiv = contentDiv;
	

	// Set up some commonly-used variables
	
	this.momentumFunction=null;
	this.momentumStop=false;
	
	this.downStart=0;
	this.downEnd=0;
	
	var theParentDiv = document.getElementById(parentDivName);
	this.parentHeight =  parseInt(getStyle(theParentDiv, "height"));
	this.overshoot = (this.parentHeight/2);
	this.contentDifference = parseInt( getStyle(this.contentDiv, "height"))- this.parentHeight;
	this.currentTop=0;

	this.scrollerMomentum=0;
	this.scrollStartY=0;
	this.scrollBounce=false;


	// Now create and assign the scroller to the object
	// We create the scroller programmatically...
	var scrollerDiv = document.createElement('div');
	scrollerDiv.className = 'iOSTab';
	scrollerDiv.style.width='6px';
	scrollerDiv.style.top='0px';
	scrollerDiv.style.backgroundColor='#000';

	// Append it to theParentDiv
	theParentDiv.appendChild(scrollerDiv);
	this.scrollerDiv = scrollerDiv;
	
	// And make it the right height
	this.setTabHeight();

	return this;
}




iPadScroller.prototype = {

	setTabHeight: function () {
	// This function sets the height of the scroller tab
	this.tabHeight= ( this.parentHeight / parseInt(getStyle(this.contentDiv, "height"))) * this.parentHeight;
	this.scrollerDiv.style.height=this.tabHeight+"px";
	},
	
	
	updateSize: function () {
		this.contentDifference = parseInt( getStyle(this.contentDiv, "height"))- this.parentHeight;
	},

	onClick: function(e) {
	// This function intercepts the click messages so that we don't inadvertently follow a link when we're trying to scroll

		// Turn the highlight color back on
		this.contentDiv.style.webkitTapHighlightColor="rgba(0,0,0,.4)";

		if(Math.abs(this.downStart - this.downEnd) > 3 ) {

			e.stopPropagation();
			e.preventDefault();	
			this.momentumStop = false;
			e.returnValue = false;
		} 
		else {
			this.contentDiv.style.webkitTapHighlightColor="rgba(0,0,0,.4)";
			return true;
		}
	},


	onTouchStart: function(e) {
	// Start tracking when the first finger comes down in this element
		if (e.targetTouches.length != 1)
			return false;

//	     var dataDiv=document.getElementById('navNude');
//    dataDiv.innerHTML="Touched " + this.scrollerMomentum;

		// Hide the click highlight box (since we ignore clicks)
		this.contentDiv.style.webkitTapHighlightColor="rgba(0,0,0,0.0)";
		
		// Resize the tab in case the content height has changed
		this.setTabHeight();

		// Fade-in the scroll indicator
		this.scrollerDiv.style.opacity="0.50";
	
		// And save the initial touch position
		this.scrollStartY = e.targetTouches[0].clientY;
		this.downStart = this.scrollStartY;

		// Stop the momentum scroll if there is any
		this.momentumStop=false;
		if (Math.abs(this.scrollerMomentum) >.5) {
			this.scrollerMomentum=0;
			this.momentumStop=true;
		} else {
		this.downEnd = this.scrollStartY;
		}

		// Ultimately, we'd like to add these event listeners here, but removing them in the object didn't seem to work
		// var thisObj = this;
		// this.contentDiv.addEventListener('touchmove', function(e) { return thisObj.onTouchMove(e) }, false);
		// this.contentDiv.addEventListener('touchend', function(e) { return thisObj.onTouchEnd(e) }, false);

		return false;
	},



	onTouchMove: function(e) {
		// Prevent the browser from doing its default thing (scroll, zoom)
		e.preventDefault();
 
 
		// Don't track motion when multiple touches are down in this element (that's a gesture)
		if (e.targetTouches.length != 1)
			return false;

		// Set the amount we want to move the content (the same amount the inger moved)
		var topDelta = e.targetTouches[0].clientY - this.scrollStartY;
		this.scrollerMomentum = topDelta;

		//  *** This is to provide diagnostics **********************************************	
		//var dataDiv=document.getElementById('navNude');
		//dataDiv.innerHTML="Div top= " + topDelta;

		// Set the variable for the new top position of the content
		var newTop = (parseInt( getStyle(this.contentDiv, "top"))+topDelta);
		
		//  However, we want to emulate the stretchy rubber band thing where you pull past the limit
		// So if we're past the top, we actually only want to have it move a fraction of the amount you drag
		if (newTop > 0) {
			// That fraction will be the ratio of how much past the top vs, until one half past the top.
			var deltaScaled = topDelta * ((this.overshoot-parseInt( getStyle(this.contentDiv, "top")))/ this.overshoot);
			newTop = (parseInt( getStyle(this.contentDiv, "top"))+deltaScaled);
			this.doScrollTab(newTop);

			// Prevent the content from moving past the overshoot limit
			if (newTop > this.overshoot) newTop= this.overshoot;
		}
		
		//  And the same stretchy rubber band thing for the bottom
		else if (newTop < -this.contentDifference ){
			var deltaScaled = topDelta * ((this.overshoot+(parseInt( getStyle(this.contentDiv, "top"))+this.contentDifference))/ this.overshoot);
			newTop = (parseInt( getStyle(this.contentDiv, "top")) + deltaScaled);
			this.doScrollTab(newTop);

			// Prevent the content from moving past the overshoot limit
			if (newTop < -(this.contentDifference+this.overshoot)) newTop= -(this.contentDifference+this.overshoot);

			// A diagnostic
			//dataDiv.innerHTML=  this.contentDifference+" top "+getStyle(this.contentDiv, "top");
		} else {
			var scrollTabTop= ( 0-(newTop / (((parseInt(getStyle(this.contentDiv, "height")))- this.parentHeight )/( this.parentHeight -this.tabHeight))));
			this.scrollerDiv.style.top= scrollTabTop+"px";
		}

		// Set the content div to its new top position 
		this.contentDiv.style.top = newTop+"px";

		// and set the scroll tap to the matching position 
//		this.doScrollTab(newTop);

		// Save the touch position for next time
		this.scrollStartY = e.targetTouches[0].clientY;
		this.downEnd= this.scrollStartY;
		
		// And we're done
		return false;
	},


	onTouchEnd: function(e){
		// Prevent the browser from doing its default thing (scroll, zoom)
		e.preventDefault();

		// Stop tracking when the last finger is removed from this element
		if (e.targetTouches.length > 0)
			return false;

		//  *** This is to provide diagnostics **********************************************	
		// var dataDiv=document.getElementById('navNude');
		// dataDiv.innerHTML=  this.scrollerMomentum+' done '+ this.scrollStartY;

		//  Remove the event listeners for better performance
		// var thisObj = this;
		//	this.contentDiv.removeEventListener('touchmove', function(e) { return thisObj.onTouchMove(e) }, false);
		//	this.contentDiv.removeEventListener('touchmove', function(e) { return thisObj.onTouchMove(e) }, false);
	
		// Turn the cllck highlight box back on 
		this.contentDiv.style.webkitTapHighlightColor="rgba(0,0,0,.4)";
		this.momentumStop = false;

		// And do the momentum function
		this.momentumScrollStart();

		return false;
	},


	momentumScrollStart: function() {
	// This initializes the momentum function
	
		var newTop = (parseInt( getStyle(this.contentDiv, "top")));
		this.currentTop= newTop;

		// Thes are diagnostics
		// var dataDiv=document.getElementById('navNude');
		//dataDiv.innerHTML=  " Momentum";

		var thisObj = this;
		var doMomentum = false;

		// So there are two cases where we want to keep moving
		
		//    1.-- If the user released the scroll area while moving at a significant speed
		// Or 2.-- if the touch ends and the content area is past its limits
		
		// Are we past the top?
		if  (newTop > 0) {
			// Then set the momentum value and set our momentum flag to true
			this.scrollerMomentum = -38 * ((parseInt( getStyle(this.contentDiv, "top")))/ this.overshoot);
			doMomentum = true;
		}

		// Are we past the bottom?
		else if  (newTop < -this.contentDifference ) {
			// Then set the momentum value and set our momentum flag to true
			this.scrollerMomentum = 38 * (( Math.abs(parseInt( getStyle(this.contentDiv, "top")))- this.contentDifference)/ this.overshoot);
			//this.momentumFunction= setTimeout(function() { thisObj.momentumScroll(); }, 30);
			doMomentum = true;
		}

		// Otherwise, if the user moved the scroll area more than five pixels, start our momentum function
		if ( Math.abs(this.scrollerMomentum) > 5 || doMomentum == true ) {
			this.momentumFunction= setTimeout(function() { thisObj.momentumScroll(); }, 30);
	
			//  *** This is to provide diagnostics **********************************************	
			//	var dataDiv=document.getElementById('navNude');
			//	dataDiv.innerHTML=  "started Momentum";
		} else {
			// If not, fade out the scroll tab
			this.scrollerDiv.style.opacity="0.0";
		}
	},


	momentumScroll: function() {
		// This function does the updating of position after the finger is lifted when there is momentum


		if (this.momentumStop)
			return ;

		var newTop = this.currentTop + this.scrollerMomentum;


		this.scrollerDiv.style.opacity="0.5";


		// Prevent going past our overshoot distance for the bottom edge
//		if (newTop < -(this.contentDifference+this.overshoot)) {
//			newTop= -(this.contentDifference+this.overshoot);
//			this.scrollerMomentum = 38;
//		}
	
		// And for the top edge
//		if (newTop > this.overshoot) {
//			newTop= this.overshoot;
//			this.scrollerMomentum = -38;
//		}
		
		// If we're past the top edge, slow the scroller momentum
		if (newTop > 0) {
			var oldScrollMomentum = this.scrollerMomentum;
			if (oldScrollMomentum < 5) oldScrollMomentum = 0;
			this.scrollerMomentum = oldScrollMomentum -(((newTop)/3)+.075);
			this.doScrollTab(newTop);
			
			// And prevent us from going past the overshoot limit
			if (newTop > this.overshoot) {
				newTop= this.overshoot;
				this.scrollerMomentum = -38;
			}
		}

		// Similarly, if we're past bottom top edge, slow the scroller momentum
		else if (newTop < -this.contentDifference) {
			var oldScrollMomentum = this.scrollerMomentum;
			if (oldScrollMomentum > -5) oldScrollMomentum = 0;
			this.scrollerMomentum = oldScrollMomentum -(((newTop+this.contentDifference)/3)-.075);
			this.doScrollTab(newTop);

			// And prevent going past our overshoot distance for the bottom edge
			if (newTop < -(this.contentDifference+this.overshoot)) {
				newTop= -(this.contentDifference+this.overshoot);
				this.scrollerMomentum = 38;
			}
		} else {
			var scrollTabTop= ( 0-(newTop / (((parseInt(getStyle(this.contentDiv, "height")))- this.parentHeight )/( this.parentHeight -this.tabHeight))));
			this.scrollerDiv.style.top= scrollTabTop+"px";
		}

	
//  *** This is to provide diagnostics **********************************************	
//	var dataDiv=document.getElementById('navNude');
//	dataDiv.innerHTML=  "MomentumScroll "+ newTop;

		// Set the scroll content to the new position
		this.contentDiv.style.top = newTop+"px";
		this.currentTop = newTop;

		// Set the scroll tab position to match
//		this.doScrollTab(newTop);
//		var scrollTabTop= ( 0-(newTop / (((parseInt(getStyle(this.contentDiv, "height")))- this.parentHeight )/( this.parentHeight -this.tabHeight))));
//		this.scrollerDiv.style.top= scrollTabTop+"px";


		// Decrease the momentum (friction)
		this.scrollerMomentum = this.scrollerMomentum * .85;
	
		// And if the momentum is greater than or equal to 1, call this function again in a frame
		if ( Math.abs(this.scrollerMomentum) >= .25) {
			var thisObj = this;
			this.momentumFunction= setTimeout(function() { thisObj.momentumScroll(); }, 30);

		} else {
			// If not, fade out the scroll tab
			this.scrollerDiv.style.opacity="0.0";
		}
		
		
	},


	doScrollTab: function(newTop) {
	// This moves the scroll tab to the newTop position and resizes the tab when the content overshoots its bounds
	
		var scrollTabTop= ( 0-(newTop / (((parseInt(getStyle(this.contentDiv, "height")))- this.parentHeight )/( this.parentHeight -this.tabHeight))));
		if (scrollTabTop < 0) {
			this.scrollerDiv.style.height=(this.tabHeight+scrollTabTop)+"px";
			scrollTabTop = 0;
			this.scrollBounce=true;
		} 
		else if  (scrollTabTop > this.parentHeight - this.tabHeight ) {
			this.scrollerDiv.style.height=(this.tabHeight-(scrollTabTop-(this.parentHeight - this.tabHeight)))+"px";
			this.scrollBounce=true;
		} 
		else if ( this.scrollBounce ) {
			this.scrollerDiv.style.height=this.tabHeight+"px";
			this.scrollBounce=false;
		}
		
		this.scrollerDiv.style.top= scrollTabTop+"px";

	},

}
