
BSDStringUtils = {
	DEPENDENCIES: new Array(),
	VERSION: 1.1,
	
	toCamelCaseRegex: /-([a-z])/,
	
	toCamelCase: function(value) {
		var regex = BSDStringUtils.toCamelCaseRegex;
		for(; regex.test(value); value = value.replace(regex, RegExp.$1.toUpperCase()) );
		return value;
	},
	
	trimRegex: /^\s+|\s+$/g,
	
	trim: function(value) {
		var regex = BSDStringUtils.trimRegex;
		value = value.replace(regex, '');
		return value;
	},
	
	equalsTrimmed: function(value1, value2) {
		if(!value1 && !value2) {
			return true;
		}
		if(!value1) {
			return false;
		}
		if(!value2) {
			return false;
		}
		value1 = BSDStringUtils.trim(value1);
		value2 = BSDStringUtils.trim(value2);
		return value1 == value2;
	},
	
	equalsIgnoreCase: function(value1, value2) {
		if(!value1 && !value2) {
			return true;
		}
		if(!value1) {
			return false;
		}
		if(!value2) {
			return false;
		}
		return value1.toLowerCase() == value2.toLowerCase();
	},

	startsWith: function(value, starting) {
		if(!value) {
			return false;
		}
		var regex = new RegExp("^" + starting, "g");
		if(regex.exec(value)) {
			return true;
		}
		return false;
	},
		
	endsWith: function(value, ending) {
		if(!value) {
			return false;
		}
		var regex = new RegExp(ending + "$", "g");
		if(regex.exec(value)) {
			return true;
		}
		return false;
	},
	
	stripWhitespace: function(value) {
		return value.replace(/\s/g, '');
	},
	
	stripHtml: function(value) {
		return value.replace(/<[^\s0-9\.\$\=>][^>]*>/g, '');
	},
	
	truncate: function(value, length) {
		if(value.length > length) {
			value = value.substring(0, length);
		}
		return value;
	},
	
	brToLB: function(value) {
		if(!value) {
			return value;
		}
		value = value.replace("<br/>", "\n");
		value = value.replace("<br>", "\n");
		return value;
	},
	
	lbToBR: function(value) {
		if(!value) {
			return value;
		}
		value = value.replace("\r\n", "<br/>");
		value = value.replace("\r", "<br/>");
		value = value.replace("\n", "<br/>");
		return value;
	}
	
	
}

BSDTypeUtils = {
	DEPENDENCIES: new Array(),
	
	isArray: function(value) {
	    return BSDTypeUtils.isObject(value) && value.constructor == Array;		
	},
	
	isBoolean: function(value) {	
		return typeof value == 'boolean';
	},
		
	isEmpty: function(value) {
	    var i, v;
	    if (isObject(value)) {
	        for (i in value) {
	            v = value[i];
	            if (BSDTypeUtils.isUndefined(v) && BSDTypeUtils.isFunction(v)) {
	                return false;
	            }
	        }
	    }
	    return true;
	}, 
	
	isFunction: function(value) {
	    return typeof value == 'function';	
	},
	
	isNull: function(value) {
		return value == nulll;
	},
	
	isNumber: function(value) {
		return typeof value == 'number'; // && BSDTypeUtils.isFinite(value);
	},
	
	isObject: function(value) {
		return (value && typeof value == 'object');
	},

	isString: function(value) {
		return typeof value == 'string';
	},
	
	isUndefined: function(value) {
		return typeof value == 'undefined';
	}
	
}

BSDBrowserUtils = {
	DEPENDENCIES: new Array(),

	getIsSafari: function() {
		if(!navigator.userAgent) {
			return false;
		}
		return navigator.userAgent.indexOf('Safari/') > -1;
	},
	
	getIsSafari3: function() {
		if(!navigator.userAgent) {
			return false;
		}
		return navigator.userAgent.indexOf('Safari/5') > -1;
	},
	
	getIsWebkit: function() {
		if(!navigator.userAgent) {
			return false;
		}
		return navigator.userAgent.indexOf('WebKit') > -1;
	},
	
	getIsMSIE: function() {
		if(!navigator.userAgent) {
			return false;
		}
		return navigator.userAgent.indexOf('MSIE') > -1;	
	},
	
	getIsMSIE8: function() {
		return BSDBrowserUtils.getIsMSIE() && document.documentMode;
	},
	
	getIsOpera: function() {
		return window.opera;
	},
	
	setCookie: function(name, value, days) {
		var expires;
		if(days) {
			var date = new Date();
			date.setTime(date.getTime()+(days*24*60*60*1000));
			expires = "; expires="+date.toGMTString();
		} else  {
			var expires = "";
		}
		document.cookie = name + "=" + value+expires + "; path=/";
	},

	getCookieValue: function(name) {
		var nameEQ = name + "=";
		var ca = document.cookie.split(';');
		for(var i = 0; i < ca.length; i++) {
			var c = ca[i];
			while(c.charAt(0) == ' ') {
				c = c.substring(1, c.length);
			}
			if(c.indexOf(nameEQ) == 0)  {
				return c.substring(nameEQ.length, c.length);
			}
		}
		return null;
	},

	eraseCookie: function(name) {
		createCookie(name, "", -1);
	}
	
			
	
	
}	
var bsdObjectsByClassHash;

BSDDOMUtils = {
	DEPENDENCIES: new Array("BSDStringUtils", "BSDTypeUtils", "util/BSDBrowserUtils"),
	VERSION: 1.2,

	setElementValue: function(element, value) {
		if(element.innerHTML) {
			element.innerHTML = value;
		} else if(element.nodeName && element.nodeName == 'input') {
			element.value = value;
		} else if(element.nodeType == 1) {
			var children = element.childNodes;
			for(i = 0; children && i < children.length; i++) {
				var currentChild = children[i];
				element.removeChild(currentChild);
			}
			var newTextNode = document.createTextNode(value);
			element.appendChild(newTextNode);
		} else {
			alert("Couldn't set value for node type " + element.nodeType);
		}
	},

	getAttributeValue: function(element, attributeName) {

		if(!element) {
			return;
		}
		if(element.getAttribute) {
			var currentAttribute = element.getAttribute(attributeName);
			if(currentAttribute) {
				return currentAttribute;
			}
		} else if(element.attributes) {
			var currentAttr = element.attributes[attributeName];
			if(currentAttr) {
				return currentAttr.value;
			}
		} else {

		}	



		
	},
	
	setAttributeValue: function(element, attributeName, attributeValue) {
		element.setAttribute(attributeName, attributeValue);
	},

	removeAttribute: function(element, attributeName) {
		element.removeAttribute(attributeName);
	},

	getObjectById: function(id, doc) {
		if(!doc) {
			doc = document;
		}
		
	    if(doc.getElementById) {
	        return doc.getElementById(id);
	    } else if(doc.all) {
	        return doc.all[id];
	    } else if(doc.layers) {
	        return doc.layers[id];
	    }	
	},
	
	getParentObjectByClass: function(element, className) {
		if(BSDDOMUtils.containsClass(element, className)) {
			return element;
		} else if(element.parentNode) {
			return this.getParentObjectByClass(element.parentNode, className);
		} else {

		}		
	},

	getParentObjectById: function(element, objectId) {
		if(element.id == objectId) {
			return element;
		} else if(element.parentNode) {
			return this.getParentObjectById(element.parentNode, objectId);
		} else {

		}		
	},

	getParentObjectByNodeName: function(element, nodeName, includeCurrent) {
		if(includeCurrent && element.nodeName && element.nodeName.toLowerCase() == nodeName.toLowerCase()) {

			return element;
		}
		if(element.parentNode == element || !element.parentNode || !element.parentNode.nodeName) {

			return null;
		}
		if(element.parentNode.nodeName.toLowerCase() == nodeName.toLowerCase()) {

			return element.parentNode;
		} else {

			return BSDDOMUtils.getParentObjectByNodeName(element.parentNode, nodeName);
		}
	},
	
	getObjectByNodeNameFromParent: function(parent, nodeName, includeCurrent) {
		if(includeCurrent && parent.nodeName && parent.nodeName.toLowerCase() == nodeName) {
			return parent;
		}
		for(var i = 0; i < parent.childNodes.length; i++) {
			var currentChild = parent.childNodes[i];
			if(currentChild.nodeName && currentChild.nodeName.toLowerCase() == nodeName) {
				return currentChild;
			}
		}
		for(var i = 0; i < parent.childNodes.length; i++) {
			var result = BSDDOMUtils.getObjectByNodeNameFromParent(parent.childNodes[i], nodeName, true);
			if(result) {
				return result;
			}
		}
		
	},

	getObjectByIdFromParent: function(parent, id, elementClassToIgnore) {
		if(!parent) {
			return;
		}
		var children = parent.childNodes;
		if(!children) {
			return null;
		}
		if(arguments.length > 3) {
			elementClassToIgnore = new Array();
			for(var i = 2; i < arguments.length; i++) {
				BSDArrayUtils.append(elementClassToIgnore, arguments[i]);
			}
		}
		
		for(var i = 0; i < children.length; i++) {
			var currentChild = children[i];
			if(currentChild.id == id && (!elementClassToIgnore || !BSDDOMUtils.containsClass(currentChild, elementClassToIgnore))) {
				return currentChild;
			}
		}
		for(var i = 0; i < children.length; i++) {
			var currentChild = children[i];
			if(!elementClassToIgnore || !BSDDOMUtils.containsClass(currentChild, elementClassToIgnore)) {
				var childValue = BSDDOMUtils.getObjectByIdFromParent(currentChild, id, elementClassToIgnore);
				if(childValue != null) {
					return childValue;
				}
			}
		}
	    return null;
	}, 

	getObjectByIdPrefixFromParent: function(parent, idPrefix, elementClassToIgnore) {
		var children = parent.childNodes;
		if(!children) {
			return null;
		}
		
		if(arguments.length > 3) {
			elementClassToIgnore = new Array();
			for(var i = 2; i < arguments.length; i++) {
				BSDArrayUtils.append(elementClassToIgnore, arguments[i]);
			}
		}
		
		for(var i = 0; i < children.length; i++) {
			var currentChild = children[i];
			if(currentChild.id && currentChild.id.indexOf(idPrefix) == 0 && (!elementClassToIgnore || !BSDDOMUtils.containsClass(currentChild, elementClassToIgnore))) {
				return currentChild;
			}
		}
		for(var i = 0; i < children.length; i++) {
			var currentChild = children[i];
			if(!elementClassToIgnore || !BSDDOMUtils.containsClass(currentChild, elementClassToIgnore)) {
				var childValue = BSDDOMUtils.getObjectByIdPrefixFromParent(currentChild, idPrefix, elementClassToIgnore);
				if(childValue != null) {
					return childValue;
				}
			}
		}
	    return null;
	}, 

	getObjectsByClass: function(className, parentElement, elementArray, elementClassToIgnore) {
		if(parentElement || elementArray || elementClassToIgnore) {
			return BSDDOMUtils.getObjectsByClassInternal(className, parentElement, elementArray, elementClassToIgnore);
		}
		if(document.getElementsByClassName) {
			return document.getElementsByClassName(className);
		}
		if(!bsdObjectsByClassHash) {
			BSDDOMUtils.buildObjectsByClassHash();
		} 
		
		var elementArray = bsdObjectsByClassHash[className];
		if(!elementArray) {

			elementArray = new Array();
		} 
		
		return elementArray;		
	},

	buildObjectsByClassHash: function() {
		bsdObjectsByClassHash = new Array();
		BSDDOMUtils.buildObjectsByClassHashByElement(document, true);
	},

	buildObjectsByClassHashByElement: function(parentElement) {
		if(!parentElement) {
			BSDLogUtils.error("Got null parentElement for buildObjectsByClassHashByElement");
			return;
		}
		if(parentElement.className) {
	        var split = parentElement.className.split(/\s+/);
	        for(var j = 0; j < split.length; j++) {
	        	var currentClassName = split[j];
	        	if(currentClassName.length < 1) {
	        		continue;
	        	}
				var classElements = bsdObjectsByClassHash[currentClassName];
				if(!classElements) {
					classElements = new Array();
					bsdObjectsByClassHash[currentClassName] = classElements;
				}
				classElements[classElements.length] = parentElement;				
			}			
		}
		
		
		var childNodes = parentElement.childNodes;
		for(var i = 0; childNodes && i < childNodes.length; i++) {
			var currentChild = childNodes[i];
			BSDDOMUtils.buildObjectsByClassHashByElement(currentChild);
		} 
		
	},
	
	getObjectsByClassInternal: function(className, parentElement, elementArray, elementClassToIgnore) {
		if(!elementArray) {
			elementArray = new Array();
		}
		if(!className) {
			return elementArray;
		}
		if(!parentElement) {
			parentElement = document;
		}
	    var children = parentElement.childNodes;
	    if(!children) {
	   		return elementArray;
	    }
	    for(var i = 0; i < children.length; i++) {
	        var currentChild = children[i];
		    if(currentChild.nodeType != 1) {
			    continue;
	        }	
	        
	        var split = currentChild.className.split(/\s+/);
	        for(var j = 0; j < split.length; j++) {
	        	var currentClassName = split[j];
	        	if(!currentClassName || currentClassName.length < 1) {
	        		continue;
	        	}

			    if(currentClassName == className) {
			        var index = elementArray.length;
			        elementArray[index] = currentChild;
		        } else if(elementClassToIgnore && currentClassName == elementClassToIgnore) {

		        	continue;
		        }
		    }	        
	        
		    BSDDOMUtils.getObjectsByClass(className, currentChild, 
							elementArray, elementClassToIgnore);
	    }
	    return elementArray;
	},
	
	getObjectsById: function(id, parentElement, elementArray) {
		if(!elementArray) {
			elementArray = new Array();
		}
		if(!id) {
			return elementArray;
		}
		if(!parentElement) {
			parentElement = document;
		}
	    var children = parentElement.childNodes;
	    if(!children) {
	   		return elementArray;
	    }
	    for(var i = 0; i < children.length; i++) {
	        var currentChild = children[i];
		    if(currentChild.nodeType != 1) {
			    continue;
	        }	
		    if(currentChild.id == id) {
		        var index = elementArray.length;
		        elementArray[index] = currentChild;
	        }
		    BSDDOMUtils.getObjectsById(id, currentChild, 
							elementArray);
	    }
	    return elementArray;
	},

	getObjectsByNodeName: function(parentElement, nodeName, elementArray) {
		if(!elementArray) {
			elementArray = new Array();
		}
		if(!nodeName) {
			return elementArray;
		}
		if(!parentElement) {
			BSDLogUtils.error("ERROR: Got null parentElement for getObjectsByNodeName()");
			return;
		}
	    var children = parentElement.childNodes;
	    if(!children) {
	   		return null;
	    }
	    for(var i = 0; i < children.length; i++) {
	        var currentChild = children[i];
		    if(currentChild.nodeType != 1) {
			    continue;
	        }	
		    if(currentChild.nodeName == nodeName) {
		        var index = elementArray.length;
		        elementArray[index] = currentChild;
	        }
		    BSDDOMUtils.getObjectsByNodeName(currentChild, nodeName, 
							elementArray);
	    }
	    return elementArray;
	},

	getRootElement: function() {
		if(document.documentElement) {
			return document.documentElement;
		}
		return null;
	},
	
	getNextElementSibling: function(element) {
		var sibling = element.nextSibling;
		while(sibling && sibling.nodeType != 1) {
			sibling = sibling.nextSibling;
		}
		return sibling;
	},

	getPreviousElementSibling: function(element) {
		var sibling = element.previousSibling;
		while(sibling && sibling.nodeType != 1) {
			sibling = sibling.previousSibling;
		}
		return sibling;
	},
	
	getElementStyle: function(element, styleName) {
		if(!element.style) {

			return;
		}
		var ieStyleName = BSDStringUtils.toCamelCase(styleName);
		var styleValue = element.style[ieStyleName];
	    if(!styleValue) {
			if(document.defaultView && document.defaultView.getComputedStyle) {
	        	var cssStyleValue = document.defaultView.getComputedStyle(element, "");
	        	if(!cssStyleValue) {
	        		return null;
	        	}
	        	styleValue = cssStyleValue.getPropertyValue(styleName);

	      	} else if(element.currentStyle) {
	        	styleValue = element.currentStyle[ieStyleName];
	      	}
	  	}

		if(styleValue == 'auto') {
			return null;
		}
	  	return styleValue;
	},
	
 
	elementContainsStyle: function(element, stylePropertyName, stylePropertyValue) {
	    stylePropertyValue = stylePropertyValue.toLowerCase();
	    if(element.style && element.style[stylePropertyName] &&
						element.style[stylePropertyName].toLowerCase() == stylePropertyValue) {
			return true;
	    }
	    return false;
	},

	setElementStyle: function(element, stylePropertyName, stylePropertyValue) {
		BSDDOMUtils.changeElementStyle(element, stylePropertyName, stylePropertyValue);
	},
		
	changeElementStyle: function(element, stylePropertyName, stylePropertyValue) {
		if(!element) {
			return;
		}
	    var elementStyle = element.style;
	    if(elementStyle) {
	    	try {
			    elementStyle[stylePropertyName] = stylePropertyValue;
			} catch (err) {  


			}
		}
		if(stylePropertyName == 'background-color') {
			element.style.backgroundColor = stylePropertyValue;
		} else if(stylePropertyName == 'font-family') {
			element.style.fontFamily = stylePropertyValue;
		} else if(stylePropertyName == 'text-align') {
			element.style.textAlign = stylePropertyValue;
		}
	},
	
	cloneElementStyle: function(source, target, stylePropertyName) {
		if(stylePropertyName) {
			var value = BSDDOMUtils.getElementStyle(source, stylePropertyName);
			if(value) {

				BSDDOMUtils.changeElementStyle(target, stylePropertyName, value);
			}
			return value;
		}
	},
	
	cloneAllElementStyles: function(source, target) {
		for(var styleName in source.style) {
			if(styleName) {
				BSDDOMUtils.cloneElementStyle(source, target, styleName);
			}
		}
	
	},
	
	getElementMargin: function(source, tryChildren) {
		var margin = BSDDOMUtils.getElementStyle(source, 'margin');
		var iTop = 0;
		var iRight = 0;
		var iLeft = 0;
		var iBottom = 0;
		if(margin) {
			var split = margin.split(/\s*px\s*/i);
			if(split.length < 1 && margin.length > 0) {
				iTop = parseInt(margin);
			}
			if(split.length > 0) {
				iTop = parseInt(split[0]);
			}
			if(split.length > 1) {
				iRight = parseInt(split[1]);
			}
			if(split.length > 2) {
				iBottom = parseInt(split[2]);
			}
			if(split.length > 3) {
				iLeft = parseInt(split[3]);
			}			
		}
		
		var marginTop = BSDDOMUtils.getElementStyle(source, 'margin-top');
		if(marginTop && marginTop.length > 2) {
			iTop = marginTop.replace(/\s*px\s*/i, '');
		}
		var marginRight = BSDDOMUtils.getElementStyle(source, 'margin-right');
		if(marginRight && marginRight.length > 2) {
			iRight = marginRight.replace(/\s*px\s*/i, '');
		}
		var marginBottom = BSDDOMUtils.getElementStyle(source, 'margin-bottom');
		if(marginBottom && marginBottom.length > 2) {
			iBottom = marginBottom.replace(/\s*px\s*/i, '');
		}
		var marginLeft = BSDDOMUtils.getElementStyle(source, 'margin-left');
		if(marginLeft && marginLeft.length > 2) {
			iLeft = marginLeft.replace(/\s*px\s*/i, '');
		}

		if(tryChildren && iTop == 0 && iRight == 0 && iBottom == 0 && iLeft == 0) {

			var marginChild = null;
			for(var i = 0; i < source.childNodes.length; i++) {
				var currentChild = source.childNodes[i];
				if(currentChild.nodeType == 1 && !BSDVisibilityUtils.isObjectHidden(currentChild)) {
					if(!marginChild) {
						marginChild = currentChild;
					} else {
						marginChild = null;
						break;
					}
				}
				if(marginChild) { 
					return BSDDOMUtils.getElementMargin(marginChild, false);
				}
			}		
		}
		
		var margin = new Object();
		
		margin.margin = iTop + 'px ' + iRight + 'px ' + iBottom + 'px ' + iLeft + 'px';
		margin.top = iTop;
		margin.right = iRight;
		margin.bottom = iBottom;
		margin.left = iLeft;


		return margin;
	},

	
	getElementWidth: function(element) {
		var iWidth = element.offsetWidth;
		if(iWidth && iWidth > 0) {
			return iWidth;
		}
		var width = BSDDOMUtils.getElementStyle(element, 'width');
		if(width && width.length > 0) {
			width = width.replace(/\s*px\s*/i, '');
			return parseInt(width);
		}
		
		width = BSDDOMUtils.getAttributeValue(element, 'width');		
		if(width && width.length > 0) {
			return parseInt(width);
		}
		return 0;
	},
	
	setElementWidth: function(element, newWidth) {
		BSDDOMUtils.changeElementStyle(element, 'width', newWidth + 'px');
	},
	
	getElementHeight: function(element) {
		var iHeight = element.offsetHeight;
		if(iHeight && iHeight > 0) {
			return iHeight;
		}
		var height = BSDDOMUtils.getElementStyle(element, 'height');
		if(height && height.length > 0) {
			height = height.replace(/\s*px\s*/i, '');
			return parseInt(height);
		}
		height = BSDDOMUtils.getAttributeValue(element, 'height');
		if(height && height.length > 0) {
			return parseInt(height);
		}
		return 0;
	},
	
	setElementHeight: function(element, newHeight) {
		BSDDOMUtils.changeElementStyle(element, 'height', newHeight + 'px');
	},
	
	getDocumentWidth: function(doc) {
		if(!doc) {
			doc = document;
		}
		if(doc.body) {
			return doc.body.clientWidth;
		} else if(doc.documentElement) {
			return doc.documentElement.clientWidth;
		}
	},
	
	getDocumentHeight: function(doc) {
		if(!doc) {
			doc = document;
		}
		if(doc.body) {
			return doc.body.clientHeight;
		} else if(doc.documentElement) {
			return doc.documentElement.clientHeight;
		}
	},
	
	cloneElement: function(sourceElement, doShallowClone) {
		var deep = true;
		if(doShallowClone) {
			deep = false;
		}
		return sourceElement.cloneNode(deep);
	},    

	cloneElementDimensions: function(source, target, deltaWidth, deltaHeight) {
	    var newWidth = source.offsetWidth;
	    var newHeight = source.offsetHeight;
	    if(deltaWidth) {
			newWidth += deltaWidth;
	    }
	    if(deltaHeight) {
			newHeight += deltaHeight;
	    }
	    BSDDOMUtils.changeElementStyle(target, 'width', newWidth);
	    BSDDOMUtils.changeElementStyle(target, 'height', newHeight);
	},

	cloneDimensions: function(sourceDimensions, target) { 
	    BSDDOMUtils.changeElementStyle(target, 'width', sourceDimensions.width);
	    BSDDOMUtils.changeElementStyle(target, 'height', sourceDimensions.height);	
	},
	
	cloneElementMargins: function(source, target, tryChildren) {
		var margin = BSDDOMUtils.getElementMargin(source, tryChildren);
		BSDDOMUtils.changeElementStyle(target, 'margin', margin.margin);

		return margin.margin != '0px 0px 0px 0px';		

	},

	createElement: function(nodeName, parent, id, className) {
		return BSDDOMUtils.createElementByDoc(document, nodeName, parent, id, className);
	},

	createElementByDoc: function(doc, nodeName, parent, id, className) {

		var element = doc.createElement(nodeName);	
		if(parent) {
			parent.appendChild(element);
		}
		if(id) {
			element.id = id;
		}
		if(className) {
			element.className = className;
		}
		return element;
	},
	
	removeElement: function(element) {
		var parent = element.parentNode;
		if(!parent) {
			return;
		}
		if(element.nodeName == 'TR') {
			while(parent && parent.nodeName != 'TABLE') {
				parent = parent.parentNode;
			}
			if(parent) {
				parent.deleteRow(element.rowIndex);
			} else {
				BSDLogUtils.error("ERROR: Couldn't find table parent for row to remove");
			}
		} else {
			parent.removeChild(element);
		}
	},
	
	getPreviousSiblingElement: function(element) {
		var sibling = element.previousSibling;
		while(sibling && sibling.nodeType != 1) {
			sibling = sibling.previousSibling;
		}
		return sibling;
	},
	
	getNextSiblingElement: function(element) {
		var sibling = element.nextSibling;
		while(sibling && sibling.nodeType != 1) {
			sibling = sibling.nextSibling;
		}
		return sibling;
	},
	
	setCursor: function(element, cursorName) {
		BSDDOMUtils.changeElementStyle(element, 'cursor', cursorName);
	},

	setMoveCursor: function(element) {
		BSDDOMUtils.setCursor(element, 'move');
	},
	
	setDefaultCursor: function(element) {
		BSDDOMUtils.setCursor(element, 'default');
	},
	
	setClass: function(element, className) {
		element.className = className;
	},
	
	addClass: function(element, className, prepend) {
		if(element.className) {
			if(prepend) {
				element.className = className + " " + element.className;
			} else {
				element.className += " " + className;
			}
		} else {
			element.className = className;
		}
	},
	
	removeClass: function(element, className) {
		if(!element.className || element.className.length < 1) {
			return;
		}
		var newClassName = "";
		var split = element.className.split(/\s+/);
	    for(var i = 0; i < split.length; i++) {
	        var currentClassName = split[i];
	        if(!currentClassName || currentClassName.length < 1) {
	        	continue;
	        }

			if(currentClassName != className) {
				newClassName += currentClassName;
				if(i < split.length -1) {
					newClassName += " ";
				}
			}
		}
		element.className = newClassName;
	},
	
	containsClass: function(element, className) {
		if(!element.className || !className) {
			return false;
		}
		var multipleClasses = BSDTypeUtils.isArray(className);
        var split = element.className.split(/\s+/);
        for(var j = 0; j < split.length; j++) {
        	var currentClassName = split[j];
        	if(!currentClassName || currentClassName.length < 1) {
        		continue;
        	}

        	if(multipleClasses && BSDArrayUtils.contains(className, currentClassName)) {
        		return true;
		    } else if(currentClassName == className) {
		    	return true;
	        } 
	    }		
	    return false;
	},
	
	addChild: function(element, child) {
		element.appendChild(child);
	},
	
	moveElement: function(element, newParent) {
		BSDDOMUtils.removeElement(element);
		BSDDOMUtils.addChild(newParent, element);
	},
	
	replaceElement: function(oldElement, newElement) {
		if(oldElement && oldElement.parentNode) {
			oldElement.parentNode.replaceChild(newElement, oldElement);
		}
	},
	
	replaceElementByIdAndHtml: function(oldElementId, newElementHtml) {
		var oldElement = BSDDOMUtils.getObjectById(oldElementId);
		if(!oldElement) {
			BSDLogUtils.warning("Couldn't find element to replace with id: " + oldElementId);
			return;
		}
		newElementHtml = newElementHtml.replace(/scripx/g, 'script');

		oldElement.innerHTML = newElementHtml;
		var newNode;
		if(oldElement.childNodes && oldElement.childNodes.length && oldElement.childNodes.length == 1) {
			newNode = oldElement.childNodes[0];
			BSDDOMUtils.replaceElement(oldElement, newNode);
		}
		return newNode;
	},
	
	replaceElementByParentId: function(parentElementId) {
		var parentElement = BSDDOMUtils.getObjectById(parentElementId);
		if(!parentElement) {
			BSDLogUtils.warning("Couldn't find parent element to replace with id: " + parentElementId);
			return;
		}

		var elementsToMove = new Array();
		for(var i = 0; i < parentElement.childNodes.length; i++) {

			var currentElement = parentElement.childNodes[i];

			if(currentElement.nodeType != 1) {
				continue;
			}
			var targetId = BSDDOMUtils.getAttributeValue(currentElement, 'rid');
			if(!targetId) {
				BSDLogUtils.warning("Couldn't find target id for element to replace: " + currentElement.id);
				continue;
			}
			var target = BSDDOMUtils.getObjectById(targetId);
			if(!target) {
				BSDLogUtils.warning("Couldn't find target element to replace: " + targetId);
				continue;
			}
			
			var currentHolder = new Object();
			currentHolder.source = currentElement;
			currentHolder.target = target;
			elementsToMove[elementsToMove.length] = currentHolder;
		}
		for(var i = 0; i < elementsToMove.length; i++) {
			var currentHolder = elementsToMove[i];
			BSDDOMUtils.replaceElement(currentHolder.target, currentHolder.source);

		}
	

	},
	
	addText: function(element, text) {
		var textNode = document.createTextNode(text);
		element.appendChild(textNode);
	},
	
	setText: function(element, text) {
		if(!element || !element.childNodes) {
			BSDLogUtils.error("Cannot set text on null element");
			return;
		}
		if(element.nodeName && element.nodeName.toLowerCase() == 'input') {
			element.value = text;
		} else if(element.nodeName && element.nodeName.toLowerCase() == 'select') {
			if(!text || text.length < 1) {
				if(element.options && element.options.length > 0) {
					element.options[0].selected = true;
					return;
				}
			}
			for(var i = 0; i < element.childNodes.length; i++) {
				var currentChild = element.childNodes[i];
				var value = currentChild.value;
				if(value && value == text) {
					currentChild.selected = true;
					break;
				} else if(!value && BSDDOMUtils.getText(element) == text) {
					currentChild.selected = true;
					break;
				}
			}
		} else if(element.nodeType == 3) {
			element.nodeValue = text;
		} else {			
			for(var i = 0; i < element.childNodes.length; i++) {
				if(element.childNodes[i].nodeType == 3) {
					element.removeChild(element.childNodes[i]);
					i--;
				} 
			}
			BSDDOMUtils.addText(element, text);
		}
		
	},
	
	setTextById: function(elementId, text, parentElement) {
		var element;
		if(parentElement) {
			element = BSDDOMUtils.getObjectByIdFromParent(parentElement, elementId);
		} else {
			element = BSDDOMUtils.getObjectById(elementId);
		}
		if(!element) {
			return;
		}
		BSDDOMUtils.setText(element, text);
		return element;
	},
	
	setTextByClass: function(elementClass, text, parentElement) {
		var objects = BSDDOMUtils.getObjectsByClass(elementClass, parentElement);
		for(var i = 0; i < objects.length; i++) {
			BSDDOMUtils.setText(objects[i], text);
		}
		return objects;
	},
	
	getText: function(element) {
		var text = "";
		if(!element) {
			return text;
		}
		if(element.nodeName && element.nodeName.toLowerCase() == 'input') {
			return element.value;
		}
		
		if(element.nodeType == 3) {
			return element.nodeValue;
		} else if(!element.childNodes) {
			return text;
		}
		for(var i = 0; i < element.childNodes.length; i++) {
			if(element.childNodes[i].nodeType == 3) {
				text += element.childNodes[i].nodeValue;
			}		
		}
		return text;
	},
	
	getTextById: function(elementId, parentNode) {
		var element;
		if(parentNode) {
			element = BSDDOMUtils.getObjectByIdFromParent(parentNode, elementId);
		} else {
			element = BSDDOMUtils.getObjectById(elementId);
		}
		if(!element) {
			return;
		}
		return BSDDOMUtils.getText(element);	
	},
	
	appendElementToRoot: function(element) {
		if(document.body) {
			document.body.appendChild(element);
		} else {
			for(var i = 0; i < document.childNodes.length; i++) {
				document.childNodes[i].appendChild(element);
			}
		}
	},
	
	clear: function(element) {
		if(element.nodeName.toLowerCase() == 'table' && element.tBodies && element.tBodies.length > 0) {
			for(var i = 0; i < element.tBodies.length; i++) {

				BSDDOMUtils.clear(element.tBodies[i]);
			}
		} else {
		    while(element.childNodes.length > 0) {

				element.removeChild(element.childNodes[0]);
			}
		}	
	},
	
	getContainsChildElements: function(element, exceptionClass) {
		if(!element || !element.childNodes) {
			return false;
		}
		for(var i = 0; i < element.childNodes.length; i++) {
			var currentChild = element.childNodes[i];
			if(exceptionClass && BSDDOMUtils.containsClass(currentChild, exceptionClass)) {
				continue;
			}
			if(currentChild.nodeType == 1) {
				return true;
			}
		}
		return false;
	},
	
	insertAfter: function(existingElement, newElement) {
		var parentNode = existingElement.parentNode;
		if(!parentNode) {
			return false;
		}
		if(existingElement.nextSibling) {
			parentNode.insertBefore(newElement, existingElement.nextSibling);
		} else {
			parentNode.appendChild(newElement);
		}
		
		return true;
	},
	
	insertBefore: function(existingElement, newElement) {
		var parentNode = existingElement.parentNode;
		if(!parentNode) {
			return false;
		}

		if(existingElement.nodeName.toUpperCase() == 'TR' && !newElement.nodeName.toUpperCase() == 'TR') {
			var row = document.createElement('tr');
			if(!newElement.nodeName.toUpperCase() == 'TD') {
				var column = document.createElement('td');
				column.appendChild(newElement);
				row.appendChild(column);
			} else {
				row.appendChild(newElement);
			}
			newElement = row;
		} 

		parentNode.insertBefore(newElement, existingElement);
		
		return true;
	},
	
	insertChild: function(parentElement, newElement, index) {
		if(!parentElement) {
			BSDLogUtils.error("Got null parentElement for insertChild");
			return;
		}
		var childNodes = parentElement.childNodes;
		if(index >= 0 && childNodes.length > index) {
			BSDDOMUtils.insertBefore(childNodes[index], newElement);
		} else {
			BSDDOMUtils.addChild(parentElement, newElement);
		}
	},
	
	getElementParentIndex: function(element) {
		var parentNode = element.parentNode;
		for(var i = 0; i < parentNode.childNodes.length; i++){
			if(parentNode.childNodes[i] == element) {
				return i;
			}
		}
	},
	
	appendAsRow: function(table, rowContents) {
		var row = document.createElement('tr');
		var column = document.createElement('td');
		
		column.innerHTML = rowContents;
		table.tBodies[0].appendChild(row);
		row.appendChild(column);
	},
	
	setInnerHTML: function(element, content) {
  		if(element.nodeName.toUpperCase() == 'TABLE') {
  			BSDDOMUtils.clear(element);
  			if(BSDStringUtils.startsWith(content, '<tr') && element.tBodies && element.tBodies.length > 0) {
  				element.tBodies[0].innerHTML = content;
  			} else {
				BSDDOMUtils.appendAsRow(element, content);
			}
  		} else {
	  		element.innerHTML = content;
	  	}
	
	},
	
	getFrameDocument: function(frame) {
		if(frame.contentDocument) {
			return frame.contentDocument;
		} else if(frame.contentWindow && frame.contentWindow.document) {
			return frame.contentWindow.document;
		} else {
			return frame.document; //ie
		}
	},
	
	getRangeObject: function(selectionObject, doc) {
		if(selectionObject.getRng && selectionObject.getRng()) {
			return selectionObject.getRng();
		} else if(selectionObject.getRangeAt) {
			return selectionObject.getRangeAt(0);
		} else { // Safari!
			if(!doc) {
				doc = document;
			}
			var range = doc.createRange();
			if(selectionObject.anchorNode) {
				range.setStart(selectionObject.anchorNode,selectionObject.anchorOffset);
			}
			if(selectionObject.focusNode) {
				range.setEnd(selectionObject.focusNode,selectionObject.focusOffset);
			}
			return range;
		}
	},
	
	copyTable: function(source, target, removeExisting) {

		var tbody = null;
		for(var i = 0; i < target.childNodes.length; i++) {
			var currentChild = target.childNodes[i];
			if(currentChild.nodeName == 'TBODY') {
				tbody = currentChild;
			} else if(removeExisting) {
				BSDDOMUtils.removeElement(currentChild);
			}
		}

		if(tbody && removeExisting) {

			for(var i = 0; i < tbody.childNodes.length; i++) {
				BSDDOMUtils.removeElement(tbody.childNodes[i]);
			}	
		} else if(!tbody) {
			tbody = target;
		}
		for(var i = 0; i < source.childNodes.length; i++) {
			var currentChild = source.childNodes[i];
			if(currentChild.nodeName == 'TBODY') {
				for(var j = 0; j < currentChild.childNodes.length; j++) {
					tbody.appendChild(currentChild.childNodes[j]);

				}	
			} else {
				tbody.appendChild(currentChild);
			}
		}

	},
	
	wrapSelectionByElement: function(selectionObject, doc, newElement) {
		var range = BSDDOMUtils.getRangeObject(selectionObject, doc);
		if(!range || !range.startContainer || range.collapsed) {

			return null;
		}

		if(range.startContainer.nodeType == 3) { //text
			var text = BSDDOMUtils.getText(range.startContainer);
			if(text.length == range.startOffset - range.endOffset) { //the whole element is selected - return it
				return range.startContainer;
			}
			var startText; 
			var endText;
			var selectText;
			if(range.startOffset > 0) {
				startText = text.substring(0, range.startOffset);
			}
			if(range.endContainer == range.startContainer) {
				selectText = text.substring(range.startOffset, range.endOffset);
				endText = text.substring(range.endOffset);
			} else {
				selectText = text.substring(range.startOffset);
			}

			var startNode;
			if(startText && startText.length > 0) {
				startNode = doc.createTextNode(startText);
			}
			if(range.endContainer == range.startContainer) {
				var endNode;
				if(endText && endText.length > 0) {
					endNode = doc.createTextNode(endText);
				}
				BSDDOMUtils.setText(newElement, selectText);
				if(endNode) {
					BSDDOMUtils.insertAfter(range.startContainer, endNode);			
				}
				if(startNode) {
					BSDDOMUtils.insertAfter(range.startContainer, startNode);
				}
				BSDDOMUtils.insertAfter(range.startContainer, newElement);
			} else {
				if(startNode) {
					BSDDOMUtils.insertBefore(range.startContainer, startNode);
				}
				if(selectText) {
					var selectTextNode = doc.createTextNode(selectText);
					BSDDOMUtils.addChild(newElement, selectTextNode);
				}
				var nextSibling = range.startContainer.nextSibling;
				while(nextSibling) {


					if(nextSibling == range.endContainer && nextSibling.nodeType == 3) {
						var curText = BSDDOMUtils.getText(nextSibling);
						var endText1 = curText.substring(0, range.endOffset);
						var endNode1 = doc.createTextNode(endText1);
						BSDDOMUtils.addChild(newElement, endNode1);
						if(range.endOffset > curText.length) {
							var endText2 = curText.substring(range.endOffset);
							var endNode2 = doc.createTextNode(endText2);
							BSDDOMUtils.insertAfter(range.startContainer, endNode2);
						}
						BSDDOMUtils.removeElement(range.endContainer);						
						nextSibling = null;
					} else {
						var nextNextSibling = nextSibling.nextSibling;
						BSDDOMUtils.addChild(newElement, nextSibling);						
						if(nextSibling != range.endContainer) {
							nextSibling = nextNextSibling;
						} else {
							nextSibling = null;
						}
					}

				}
				BSDDOMUtils.insertBefore(range.startContainer, newElement);
			}
			

			BSDDOMUtils.removeElement(range.startContainer);

		} else if(range.startContainer && range.startContainer.nodeType == 1) {
			var hasInserted = false;
			if(!hasInserted) {
				BSDDOMUtils.insertChild(range.startContainer, newElement, range.startOffset);
			}
			if(range.startContainer.nodeList) {
				for(var i = range.startOffset; i < range.endOffset && i < range.startContainer.nodeList.length; i++) {
					var currentChild = range.startContainer.nodeList[i];
					BSDDOMUtils.removeElement(currentChild);
					newElement.appendChild(currentChild);
				}
			}
		}
		
		return newElement;
	},
	
	clearStyles: function(parent, removeEmptySpans) {
		if(parent.style) {

			parent.style.cssText = '';
		}
		var childNodes = parent.childNodes;
		for(var i = 0; i < childNodes.length; i++) {
			var currentChild = childNodes[i];
			if(currentChild.nodeType == 1) {
				BSDDOMUtils.clearStyles(currentChild, removeEmptySpans);
			}
		}
		if(removeEmptySpans && parent.nodeName == 'SPAN' && !parent.id && !parent.className) {
			for(var i = 0; i < childNodes.length; i++) {
				BSDDOMUtils.insertBefore(parent, childNodes[i]);			
			}
			BSDDOMUtils.removeElement(parent);
		}
	},
	
	convertDoubleBrToP: function(parent, doc, currentParent, depth) {




		if(!doc) {
			doc = parent.ownerDocument;
		}
		if(!depth) {
			depth = 0;
		}
		var prevBr;
		if(!currentParent) {
			currentParent = parent;
		}
		var childNodes = currentParent.childNodes;
		var moveArray = new Array();
		var moveParentArray = new Array();
		var deleteArray = new Array();
		var prevElement = parent;



		for(var i = 0; i < childNodes.length; i++) {
			var currentChild = childNodes[i];
			var isBr = currentChild.nodeName == 'BR';

			/*if(isBr) {
				alert("Got br");
			} else {
				alert("Got other: " + currentChild.nodeName + " " + currentChild.id + " " + currentChild.nodeValue);
			}*/

			if(isBr && prevBr) {
				BSDArrayUtils.append(deleteArray, currentChild);
				prevBr = null;
				continue; //skip this one, as we must have already created a p for the previous br
			} else if(isBr) {
				prevBr = currentChild;
				var newP = BSDDOMUtils.createElementByDoc(doc, "p");
				currentParent = newP;
				newP.bsdIndex = i;
				BSDArrayUtils.append(deleteArray, currentChild);

			} else if(currentChild.nodeName == 'DIV' && currentChild.id == '_mcePaste') {
				var hadParent = false;
				BSDArrayUtils.append(deleteArray, currentChild);
				/* as of 1/23/2010, webkit browsers send both divs like this and plain text nodes. ignore the divs and the plain text will get put into p nodes automatically
				continue;
				if(true) {
					continue;
				}
				if(currentChild.innerHTML == '<br style="">') {
					continue;
				}
				if(currentParent) {

					hadParent = true;
				}

				currentParent = BSDDOMUtils.createElementByDoc(doc, "p");				
				currentParent.innerHTML = currentChild.innerHTML;
				currentParent.id = i;


				BSDArrayUtils.append(moveArray, currentChild);
				BSDArrayUtils.append(moveParentArray, currentParent);

				prevElement = currentParent;
				if(hadParent) {
					currentParent = BSDDOMUtils.createElementByDoc(doc, "p");
				}
				*/
			} else if(currentChild.nodeType == 1) {

				prevElement = currentChild;
			}
			if(currentChild.nodeType == 3 && !isBr && currentParent && currentParent != parent && currentChild.nodeValue && BSDStringUtils.trim(currentChild.nodeValue).length > 0) { //move text nodes
				currentParent.innerHTML = currentChild.nodeValue;
				/*if(parent.parentNode) {
					BSDDOMUtils.insertAfter(prevElement, currentParent);					
				}*/
				/*if(!isBr && prevBr) {
					BSDArrayUtils.append(moveArray, prevBr);
					BSDArrayUtils.append(moveParentArray, currentParent);
				}*/

				BSDArrayUtils.append(moveArray, currentChild);
				BSDArrayUtils.append(moveParentArray, currentParent);
				prevElement = currentParent;
			}
			if(!isBr) {
				prevBr = null;				
			}

			
		}	

		for(var i = 0; i < moveArray.length; i++) {
			var currentChild = moveArray[i];
			var currentParent = moveParentArray[i];
			/*if(!currentChild.nodeValue && currentChild.childNodes.length < 1) {
				continue;
			}*/


			BSDDOMUtils.replaceElement(currentChild, currentParent);


			if(!currentParent.parentNode && !BSDBrowserUtils.getIsWebkit()) {
				parent.appendChild(currentParent); //ff doesn't have a parent for the pasted node
			}
		}	
		for(var i = 0; i < deleteArray.length; i++) {
			var currentChild = deleteArray[i];
			BSDDOMUtils.removeElement(currentChild);
		}

	},
	
	isBlockElement: function(currentChild) {
		return currentChild.nodeName == 'P' || currentChild.nodeName == 'DIV' || currentChild.nodeName == 'UL' 
				|| currentChild.nodeName == 'BLOCKQUOTE' || currentChild.nodeName == 'DL' || currentChild.nodeName == 'FORM'
				|| currentChild.nodeName == 'HR' || currentChild.nodeName == 'OL' || currentChild.nodeName == 'TABLE';
	}

}
var BSDClass = {
	create: function() {
    	return function() {
    		if(this.initialize) {
	      		this.initialize.apply(this, arguments);
	      	} else if(this.className) {
				BSDLogUtils.error("Couldn't find initialize function for class " + this.className);		      	
			} else {
				BSDLogUtils.error("Couldn't find initialize function for class " + arguments);		      	
	      	}
    	}
  	}
}
BSDDebugUtils = {
	DEPENDENCIES: new Array(),
	
	debugDOM: function(element) {  
		if(!element) {
			return;
		}
		var message = BSDDebugUtils.getElementMessage(element);		
		alert(message);		
	},
	
	getElementMessage: function(element, indentLevel) {
		if(!indentLevel) {
			indentLevel = 0;
		}
		var message = "\n";
		message += BSDDebugUtils.getIndentSpaces(indentLevel);
		message += "[";
		message += element.nodeName;
		message += "][";
		message += element.id
		message += "][";
		message += element.className
		message += "]";
		
		for(var i = 0; element && element.childNodes && element.childNodes.length > i; i++) {
			message += BSDDebugUtils.getElementMessage(element.childNodes[i], indentLevel + 1);
		}
		return message;
	},
	
	getIndentSpaces: function(indentLevel) {
		var indent = "";
		for(var i = 0; i < indentLevel; i++) {
			indent += "   ";
		}
		return indent;
	},
	
	dumpObject: function(objectToDump) {
		if(!objectToDump) {
			return "";
		} 
		var content;
		for(propertyName in objectToDump) {
			var propertyValue = objectToDump[propertyName];
			if(!content) {
				content = "";
			} else {
				content += "\n";
			}
			content += "[" + propertyName + "=" + propertyValue + "]";	
		}
		if(!content) {
			return "";
		}
		return content;

	}

}	
BSDArrayUtils = {
	DEPENDENCIES: new Array("BSDTypeUtils"),
	
	insert: function(array, value, index) {
		if(array.splice && BSDTypeUtils.isArray(value)) {
			for(var i = 0; i < value.length; i++) {
				array.splice(index + i, 0, value[i]);
			}		
		} else if(array.splice) {
			array.splice(index, 0, value);
		} else if(BSDTypeUtils.isArray(value)) {
			for(var i = array.length - 1 + value.length; i > index; i--) {
				array[i] = array[i-1];			
			}
			for(var i = 0; i < value.length; i++) {
				array[index + i] = value[i];
			}		
		} else {
			for(var i = array.length; i > index; i--) {
				array[i] = array[i-1];			
			}
			array[index] = value;
		}
	},
	
	append: function(array, value) {
		if(array.push && !BSDTypeUtils.isArray(value)) {
			array.push(value);
		} else if(BSDTypeUtils.isArray(value)) {
			var j = 0;
			var newLength = array.length + value.length;
			for(var i = array.length; i < newLength; i++) {
				array[i] = value[j];
				j++
			}
		} else {	
			array[array.length] = value;
		}
	},
	
	deleteElement: function(array, index, count) {
		if(!count) {
			count = 1;
		}
		if(array.splice) {
			array.splice(index, count);
			return array;
		} else {
			var newArray = new Array();
			for(var i = 0; i < array.length; i++) {
				if(i < index && i >= index + count) {
					BSDArrayUtils.append(newArray, array[i]);
				}
			}
			return newArray;
		}
	}, 
	
	replace: function(array, index, value) {
		array[index] = value;
	},
	
	copy: function(sourceArray, targetArray) {
		var j = targetArray.length;
		for(var i = 0; i < sourceArray.length; i++) {
			targetArray[j + i] = sourceArray[i];
		}
	},
	
	toCommaDelimitedString: function(sourceArray) {
		var value = "";
		for(var i = 0; i < sourceArray.length; i++) {
			value += sourceArray[i];
			if(i < sourceArray.length - 1) {
				value += ",";
			}
		}	
		return value;
	},
	
	insertUnique: function(array, value, index) {
		for(var i = 0; i < array.length; i++) {
			if(array[i] == value) {
				BSDArrayUtils.deleteElement(array, i);
				break;
			}
		}
		BSDArrayUtils.insert(array, value, index);
	},
	
	contains: function(array, value) {
		for(var i = 0; i < array.length; i++) {
			if(array[i] == value) {
				return true;
			}
		}
		return false;
	}
}

BSDTimeoutUtils = {
	DEPENDENCIES: new Array("BSDArrayUtils"),

	setTimeout: function(functionName, timeInMillis) {
		var argsString = BSDTimeoutUtils.getArgumentsString(2, arguments);
		window.setTimeout(functionName + argsString, timeInMillis);
	},

	setManagedTimeout: function(timeInMillis) {
		var argsString = BSDTimeoutUtils.getArgumentsString(1, arguments);
		window.setTimeout("BSDTimeoutUtils.handleTimeout" + argsString, timeInMillis);
	},
		
	timeoutManagers: new Object(),
	
	addTimeoutManager: function(newManager) {
		BSDTimeoutUtils.timeoutManagers[newManager.key] = newManager;
	},
	
	handleTimeout: function(managerKey, timeoutRequestId) {

		var manager = BSDTimeoutUtils.timeoutManagers[managerKey];
		if(!manager) {
			BSDLogUtils.error("Couldn't find timeout manager with key: " + managerKey);
			return;
		}
		manager.handleTimeout(timeoutRequestId);
	},
	
	getArgumentsString: function(beginningIndex, argsArray) {
		var argsString = "(";
		for(var i = beginningIndex; i < argsArray.length; i++) {
			if(i > 1 && argsString != "(") {
				argsString += ", ";
			}
			var isString = typeof(argsArray[i]) == 'string';
			if(isString) {
				argsString += "'";
			}
			argsString += argsArray[i];
			if(isString) {
				argsString += "'";
			}
		}	
		argsString += ")";
		return argsString;
	}
	
	
}

BSDLogUtils = {
	DEPENDENCIES: new Array("BSDDOMUtils", "BSDClass"),
	VERSION: 1.1,

	isLogWindowEnabled: false,
	
	debugEnabled: true,
	warningEnabled: true,
	errorEnabled: true,
	
	logStatements: new Array(),

	showLogWindow: function() {
		var logElement = BSDLogUtils.logElement;
		if(!logElement) {
			logElement = BSDDOMUtils.getObjectById("BSDLogWindow");
		}

		if(!logElement) {
			logElement = BSDDOMUtils.createElement("div");
			logElement.id = "BSDLogWindow";
			BSDDOMUtils.changeElementStyle(logElement, 'position', 'absolute');			
			BSDDOMUtils.changeElementStyle(logElement, 'text-align', 'left');	
			BSDLogUtils.logElement = logElement;
			document.body.appendChild(logElement);

			BSDLogUtils.showLogStatements();
		}
		BSDDOMUtils.changeElementStyle(logElement, "top", 0); // + currentScrollPosition.y);
		BSDDOMUtils.changeElementStyle(logElement, "left", 450); // + currentScrollPosition.x);
				
	},

	showLogStatements: function() {
		var logElement = BSDLogUtils.logElement;
		for(var i = 0; i < BSDLogUtils.logStatements.length; i++) {
			var currentStatement = BSDLogUtils.logStatements[i];
			if(currentStatement.isError && !BSDLogUtils.errorEnabled) {
				continue;
			} else if(currentStatement.isWarning && !BSDLogUtils.warningEnabled) {
				continue;
			} else if(currentStatement.isDebug && !BSDLogUtils.debugEnabled) {
				continue;
			}
			
			BSDLogUtils.displayLogStatement(currentStatement);
		}
	},
	
	displayLogStatement: function(statement) {
		var logElement = BSDLogUtils.logElement;

		var statementElement = BSDDOMUtils.createElement("div", logElement, null, "BSDLogStatement");			
		statementElement.statementId = statement.id;

		var statementDateElement = BSDDOMUtils.createElement("span", statementElement, null, "BSDLogStatementDate");
		statementDateElement.innerHTML = statement.date.getHours() + ":" + statement.date.getMinutes() + ":" + statement.date.getSeconds();

		var statementTypeElement = BSDDOMUtils.createElement("span", statementElement, null, "BSDLogStatementType");
		statementTypeElement.innerHTML = statement.type;
		
		var statementMsgElement = BSDDOMUtils.createElement("span", statementElement, null, "BSDLogStatementMessage");
		statementMsgElement.innerHTML = statement.message;

	},		
	
	error: function(message) {
		var newStatement = new BSDLogStatement(BSDLogUtils.logStatements.length, "ERROR", message);
		BSDArrayUtils.append(BSDLogUtils.logStatements, newStatement);
		if(BSDLogUtils.errorEnabled) {
			BSDLogUtils.displayLogStatement(newStatement);		
		}
	},
	
	warning: function(message) {
		var newStatement = new BSDLogStatement(BSDLogUtils.logStatements.length, "WARNING", message);
		BSDArrayUtils.append(BSDLogUtils.logStatements, newStatement);
		if(BSDLogUtils.warningEnabled) {
			BSDLogUtils.displayLogStatement(newStatement);		
		}
	},
	
	debug: function(message) {
		var newStatement = new BSDLogStatement(BSDLogUtils.logStatements.length, "DEBUG", message);
		BSDArrayUtils.append(BSDLogUtils.logStatements, newStatement);
		if(BSDLogUtils.debugEnabled) {
			BSDLogUtils.displayLogStatement(newStatement);		
		}
	},
	
	registerEvent: function(element, type, func) {
	    if(element.addEventListener) {
			element.addEventListener(type, func, true);
	    } else if(element.attachEvent) {
			element.attachEvent('on' + type, func);
	    } else {
	    	alert("ERROR: Couldn't register event: " + type + " " + func);
	    }

	},
	
	recordImageTime: function(src) {
		var image = new Image();
		image.src = src;
		var breakBlock = BSDDOMUtils.getObjectById('kcmBreakBlock');
		if(!breakBlock) {
			breakBlock = document.body;
		}
		BSDDOMUtils.insertChild(breakBlock, image, 0);

	}
	
}

if(BSDLogUtils.isLogWindowEnabled) {
	BSDLogUtils.registerEvent(window, "load", BSDLogUtils.showLogWindow);
}


BSDLogStatement = BSDClass.create();
BSDLogStatement.prototype = {

	className: "BSDLogStatement",
	initialize: function(id, type, message) {
		this.id = id;
	    this.type = type;
		this.message = message;
		this.date = new Date();
	},
	
	isError: function() {
		if(this.type == 'ERROR') {
			return true;
		}
		return false;
	},

	isWarning: function() {
		if(this.type == 'WARNING') {
			return true;
		}
		return false;
	},

	isDebug: function() {
		if(this.type == 'DEBUG') {
			return true;
		}
		return false;
	}

}


BSDEventUtils = {
	DEPENDENCIES: new Array("BSDLogUtils"),

	registerEvent: function(element, type, func) {
	    if(element.addEventListener) {
			element.addEventListener(type, func, true);			
	    } else if(element.attachEvent) {
			element.attachEvent('on' + type, func);
	    } else {
	    	BSDLogUtils.error("ERROR: Couldn't register event: " + type + " " + func);
	    	return false;
	    }
		return true;
	},
	
	stopPropagation: function(event) {	    
	    if(event.stopPropagation) {
	    	event.stopPropagation(); 
		} else {
	    	event.cancelBubble = true; 
	  	}

	  	if(event.preventDefault) {
	      	event.preventDefault(); 
	  	} else {
	      	event.returnValue = false; 
		}
	},
	
	removeEvent: function(element, type, func) {
		if(element.removeEventListener) {
			element.removeEventListener(type, func, true);
		} else if(element.detachEvent) { //was: && element['on' + type]) {
			element.detachEvent('on' + type, func);
		} else {
			BSDLogUtils.error("Couldn't removeEvent: " + element.detachEvent + " " + element[type]);
			return false;
		}	
		return true;
	},
	
	
	fixEventTarget: function(event) {
	    if(!event) {
			event = window.event;
	    }
	
	    if(event.target) {
			if(event.target.nodeType == 3) {
			    event.target = event.target.parentNode;
			}
		} else if(event.srcElement) {
			event.target = event.srcElement
	    }
	    return event.target;
	},

	getKeyPressed: function(event) {
	    var nbr;
	    if(window.event) {
			nbr = event.which;
	    } else { 
			nbr = event.keyCode;
	    }
	    var keyChar = String.fromCharCode(nbr);
		return keyChar;	
	},

	handleKeyPress: function(event, targetKeyCode) {
	    var nbr;
	    if(window.event) {
			nbr = event.which;
	    } else { 
			nbr = event.keyCode;
	    }

		
		for(var i = 1; i < arguments.length; i++) {
			var currentCode = arguments[i];

			if(nbr == currentCode) {
				return true;
			}
		}
		
		return false;
	},
	
	getIsLeftClick: function(event) {
		var nbr;
		if(event.which) {
			nbr = event.which;			
		} else {
			nbr = event.button;					
		}

		if(nbr == 1) {
			return true;
		}
		return false;
	},
	
	getIsRightClick: function(event) {
		var nbr;
		if(event.which) {
			nbr = event.which;			
		} else {
			nbr = event.button;					
		}
		if(nbr == 3) {
			return true;
		}
		return false;
	
	},
	
	registerDOMLoadEvent: function(newEvent) {
		if(!document.bsdDOMLoadInitialized) {
			BSDEventUtils.initializeDOMLoadEvents();
		}
		document.bsdDOMLoadEvents[document.bsdDOMLoadEvents.length] = newEvent;
	},
	
	initializeDOMLoadEvents: function() {
		document.bsdDOMLoadInitialized = true;
		if(!document.bsdDOMLoadEvents) {
			document.bsdDOMLoadEvents = new Array();
		}

		/*@cc_on @*/
		/*@if (@_win32)
		document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
		var script = document.getElementById("__ie_onload");
		script.onreadystatechange = function() {
			if (this.readyState == "complete") {
		    	BSDEventUtils.doDOMLoadEvents(); // call the onload handler
		  	}
		};
		/*@end @*/
		
		if(/WebKit/i.test(navigator.userAgent)) { // sniff
			var _timer = setInterval(function() {
				if(/loaded|complete/.test(document.readyState)) {
					clearInterval(_timer);
					BSDEventUtils.doDOMLoadEvents(); // call the onload handler
			    }
			}, 10);
		} else if(document.addEventListener) { // for Mozilla browsers
			document.addEventListener("DOMContentLoaded", BSDEventUtils.doDOMLoadEvents, false);
		}
	},
	
	doDOMLoadEvents: function() {
		if(!document.bsdDOMLoadEvents) {
			return;
		} 
		for(var i = 0; i < document.bsdDOMLoadEvents.length; i++) {
			document.bsdDOMLoadEvents[i].call();
		}
		
		document.bsdDOMLoadEvents = null;
	}

}


BSDNavigationUtils = {
	DEPENDENCIES: new Array("BSDEventUtils"),
	VERSION: 1.1,
	
	registerClickNavigation: function(element, href) {  

		this.navigateToHref = function(event) {
			window.location = href;
		}
		BSDEventUtils.registerEvent(element, "click", navigateToHref);
	},
	
	refreshPage: function() {

		if(window.location && window.location.reload) {
			window.location.reload(true);
		} else if(window.location && window.location.replace) {
			window.location.replace(document.URL);
		} else {
			window.location.href = documentURL;
		}
	},
	
	refreshWithArgs: function(queryArgs) {
		var url = document.URL;
		var args = BSDNavigationUtils.getDocumentQueryArgs();
		if(url.indexOf("?") > 0) {
			url = url.substring(0, url.indexOf("?"));
		}

		for(var name in queryArgs) {
			args[name] = queryArgs[name];
		}

		url += "?";
		var i = 0;
		for(var name in args) {
			var value = args[name];
			if(!value || value.length < 1) {
				continue;
			}
			if(i != 0) {
				url += "&";
			}
			url += name;
			url += "="
			url += value;
			i++;
		}

		BSDNavigationUtils.navigateTo(url);
	},
	
	navigateTo: function(href) {
		window.location.href = href;
	},
	
	getHost: function() {
		return window.location.protocol + "//" + window.location.host;
	},
	
	getDocumentURI: function(includeQueryString) {
		var url = document.URL;
		return BSDNavigationUtils.getURI(url, includeQueryString);
	},
	
	getURI: function(url, includeQueryString) {
		var beginIndex = url.indexOf("://");
		if(beginIndex < 0) {
			beginIndex = 0;
		} else {
			beginIndex += 4;
		}
		var slashIndex = url.indexOf("/", beginIndex);
		if(slashIndex < 0) {
			return;
		}
		
		var qIndex = -1;
		if(!includeQueryString) {
			qIndex = url.indexOf("?", beginIndex);
		}
		if(qIndex > 0) {	
			return url.substring(slashIndex, qIndex);
		} else {
			return url.substring(slashIndex);
		}
		
	},
	
	populateQueryArgs: function(args, dashToUnderscore, unescape) {
		args = BSDNavigationUtils.populateQueryArgsByUrl(args, dashToUnderscore, document.URL, unescape);
		return args;
	},
	
	populateQueryArgsByUrl: function(args, dashToUnderscore, url, unescape) {

		var queryIndex = url.indexOf("?");
		var hashIndex = url.indexOf("#");
		if(queryIndex < 0) {
			return args;
		}
		
		var query;
		if(hashIndex > 0) {
			query = url.substring(queryIndex + 1, hashIndex);
		} else {
			query = url.substring(queryIndex + 1);
		}
		
		var argsArray = query.split("&");
		for(var i = 0; i < argsArray.length; i++) {
			var parts = argsArray[i].split('=');
			if(parts.length > 1) {
				var name = parts[0];
				if(dashToUnderscore) {		
					var nameRegex = /-/g;
					name = name.replace(nameRegex, "_");
				}
				var value = BSDStringUtils.trim(parts[1]);
				if(value && unescape && BSDTypeUtils.isString(value) && value.indexOf('%') > -1) {
					if(window.unescape && BSDTypeUtils.isFunction(unescape)) {
						value = unescape(value);
					} else if(window.decodeURIComponent) {
						value = window.decodeURIComponent(value);
					}
				}
				args[BSDStringUtils.trim(name)] = value;
			}
		}
		return args;
	},
	
	getQueryStringByHash: function(args) {
		var strQueryArgs = "";
		for(var key in args) {
			strQueryArgs += escape(key);
			strQueryArgs += "=";
			strQueryArgs += escape(args[key]);
			strQueryArgs += "&";
		}
		return strQueryArgs;
	},
		
	getDocumentQueryArgs: function() {
		var args = {};
		BSDNavigationUtils.populateQueryArgs(args);
		return args;
	}
}	
BSDPostMessage = {
    DEPENDENCIES: new Array("BSDDOMUtils", "util/BSDBrowserUtils", "BSDNavigationUtils", "BSDTypeUtils"),
	cacheBuster: 0,

	getUseUrlHash: function() {
		var hasPostMsg = window.postMessage && !BSDBrowserUtils.getIsOpera(); 
		return !hasPostMsg;
	},
	
	createProxyFrame: function(targetWindowName, targetDomain) {
		var site = BSDNavigationUtils.getHost();
		var proxyUrl = site + '/favicon.ico';
		document.write('<iframe id="' + targetWindowName + '" name="' + targetWindowName + '" width="10" height="10" frameborder="0" src="' + proxyUrl + '"' + ' style="position: absolute; left: -150px; top:0px"></iframe>');
		var frame = window.top[targetWindowName];
		return frame;
  	},
		
  	postMessage: function(message, targetWindowName, targetUrl) {
  		var hasPostMsg = !BSDPostMessage.getUseUrlHash();
  		if(hasPostMsg) {
  			var target = window.parent;
  			target.postMessage(message, targetUrl.replace( /([^:]+:\/\/[^\/]+).*/, '$1'));
  		} else if (targetUrl) {

  	  		var target = window.frames[targetWindowName];
  	  		if(!target) {
  	  			target = BSDPostMessage.createProxyFrame(targetWindowName);
  	  		}




  			var newLocation = targetUrl.replace( /#.*$/, '' ) + '#' + (+new Date) + (BSDPostMessage.cacheBuster++) + '&' + message;
  			target.location = newLocation;
  		}
  	},

  	receiveMessage: function(targetWindowName, targetDomain, callback, sourceOrigin, count) {
  		var hasPostMsg = !BSDPostMessage.getUseUrlHash();
	    if(hasPostMsg) {


	      
	    	var rmCallback;
	    	if(callback) {


	    		rmCallback = function(e) {
	    			if ( ( typeof sourceOrigin === 'string' && e.origin !== sourceOrigin )
	    					|| ( BSDTypeUtils.isFunction( sourceOrigin ) && sourceOrigin( e.origin ) === FALSE ) ) {
	    				return FALSE;
	    			}
	    			callback.call( e );
	    		};
	    	}
	      
	    	BSDEventUtils.registerEvent(window, 'message', callback);
	    } else {
	  		var target = window.top.frames[targetWindowName];

	  		if(target) {
		    	target = target.frames[targetWindowName + 'proxy'];
	    	}
		 
	  		var hash;
		    var re = /^#?\d+&/;
		    if(target) {
		    	hash = target.location.hash;
		    }
		    if(hash && re.test( hash ) ) {
		    	hash = hash.replace(re, '');
		    	var rtn = callback.call(this, hash);
		    } else {
		    	if(!count) {
		    		count = 1;
		    	}
				function doAgain() {
					BSDPostMessage.receiveMessage(targetWindowName, targetDomain, callback, sourceOrigin, count + 1);
				}
				if(count < 200) {
					setTimeout(doAgain, 50);
				}
		    }
	    }	 
  	}
  
}
  

BSDJSAdUtils = {
	DEPENDENCIES: new Array("BSDDOMUtils", "BSDClass", "BSDDebugUtils", "BSDTimeoutUtils", "iframe/BSDPostMessage"),
	VERSION: 1.1,
	
	addPosition: function(positionId, site, width, height) {
		if(!document.jsAdsInitialized) {
			BSDJSAdUtils.initializePage();
		}		
		
		var adElement = document.jsAdElements[positionId];
		if(!adElement) {
			adElement = new BSDAdElement(positionId);
			document.jsAdElements[positionId] = adElement;
		}
		var index = adElement.size();
		var elementId = positionId + "-" + index;
		
		if(!site) {
			site = 'ads.instiads.com';
		}
		if(site.toLowerCase().indexOf('http') != 0) {
			site = 'http://' + site;
		}
		
		var referer = escape(window.location.toString());
		var url = site + '/ads/display?p=' + positionId + '&url=' + referer + '&i=' + index;
		
		var dimensions = '';
		
		if(width > 0) {
			dimensions += ' width="' + width + '"';
			url += '&width=' + width;
		}
		if(height > 0) {
			dimensions += ' height="' + height + '"';
			url += '&height=' + height;
		}
		
		function sizeCallback(message) {			
			BSDJSAdUtils.updateSize(elementId, site, width, height, message);
		}
		
		BSDPostMessage.receiveMessage(elementId, null, sizeCallback);
		
		document.write('<iframe id="' + elementId + '" name="' + elementId + '"' + dimensions + '" src="' + url + '"' 
				+ ' frameborder="0" hspace="0" vspace="0" marginwidth="0" marginheight="0" scrolling="no" allowtransparency="true"></iframe>');
		
		adElement.addElementId(elementId);
		
	},
	
	updateSize: function(elementId, site, width, height, message) {
		if(!message || (message.origin && message.origin != site)) {
			function sizeCallback(message) {
				BSDJSAdUtils.updateSize(message);
			}
			BSDPostMessage.receiveMessage(elementId, null, sizeCallback);
			return;
		} else if(message.origin) {
			message = message.data;
		}

		var re = /positionId=([^&]+)/;
		var results = re.exec(message);
		if(results.length < 2) {
			return;
		}
		var testId = results[1];
		if(testId != elementId) {
			return;
		}
		
		var iFrame = BSDDOMUtils.getObjectById(elementId);
		
		BSDJSAdUtils.resizeFrame(iFrame, width, height, message);

	},

	notifyParent: function(positionId, positionIndex, targetUrl) {
		var proxyId = positionId + "-" + positionIndex + "proxy";

		var width = document.body.scrollWidth;
		var height = 0;
		for(var i = 0; i < document.body.childNodes.length; i++) {
			var element = document.body.childNodes[i];
			if(element.id == 'AD') {

				height += BSDDOMUtils.getElementHeight(element);
			}
		}

		if(height >= document.body.scrollHeight || height < document.body.scrollHeight*.4) {
			height = document.body.scrollHeight;
		}
		
		var msg = "positionId=" + positionId + "-" + positionIndex + "&size=" + width + "x" + height;
		BSDPostMessage.postMessage(msg, proxyId, targetUrl);

	},
	
	resizeFrame: function(iFrame, width, height, sizeMsg) {
		if(!iFrame) {
			return;
		}
		
		var re = /size=([0-9]+)x([0-9]+)/;
		var results = re.exec(sizeMsg);
		
		if(results.length < 3) {
			alert("No dimensions: " + sizeMsg);
			return;
		}
		var docWidth = results[1];
		var docHeight = results[2];
		if(docWidth > width) {
			if(iFrame.style) {
				iFrame.style.width = docWidth + 'px';
			} else {
				BSDDOMUtils.setAttributeValue(iFrame, "width", docWidth);
			}
		}

		if(docHeight) {
			docHeight = parseInt(docHeight);
		}
		if(height) {
			height = parseInt(height);
		}

		if(docHeight != height && docHeight > height*.4) {
			if(iFrame.style) {
				iFrame.style.height = docHeight + 'px';
			} else {
				BSDDOMUtils.setAttributeValue(iFrame, "height", docHeight);
			}
		}
		
	},
	
	initializePage: function() {
		document.jsAdsInitialized = true;
		document.jsAdIdes = new Array();
		document.jsAdElements = new Object();
	}		
	
}

BSDAdElement = BSDClass.create();
BSDAdElement.prototype = {

	className: "BSDAnimatedElement",
	initialize: function(positionIde) {	
		this.elementIds = new Array(); 
		this.positionIde = positionIde;
	},
	
	addElementId: function(newElementId) {
		if(newElementId) {
			this.elementIds[this.elementIds.length] = newElementId;
		}
	},
	
	size: function() {
		return this.elementIds.length;
	}

}

if(!BSDTypeUtils.isUndefined(window.instiadsPId)) {
	BSDJSAdUtils.addPosition(window.instiadsPId, window.instiadsSite, window.instiadsWidth, window.instiadsHeight);
} else if(!BSDTypeUtils.isUndefined(window.instiadsPId)) {
	document.write("ERROR: Invalid ad declaration - missing position");
}