if (typeof HD == "undefined" || !HD) {
	/**
	 * The HD global namespace object.  If HD is already defined, the
	 * existing HD object will not be overwritten so that defined
	 * namespaces are preserved.
	 * 
	 * @class HD
	 * @static
	 */
	var HD = {
		// temporarily holds events event listeners until YUI is loaded
		onLoadQueue : [],
		isYuiLoaded : false,
		util : {},
		loader : null,
		classMap : {},
		
		get : function(identifier) {
			return YAHOO.util.Dom.get(identifier);
		},
		
		getByClass : function(className, elementType, containerEl, apply, o, overrides) {
			return YAHOO.util.Dom.getElementsByClassName.apply(YAHOO.util.Dom, arguments);
		},
		
		addModules : function(loader) {
			for(var key in this.modules) {
				loader.addModule(this.modules[key]);
			}
		},
		
		insert : function(config) {
			var loader = this.getLoader();
			if(loader !== null) {
				loader.insert(config);
			}
		},
		
		getLoader : function() {
			if(this.loader === null) {
				this.loader = new YAHOO.util.YUILoader();
				this.addModules(this.loader);
			}
			return this.loader;
		},
		
		extend : function(subClass, superClasses) {
			/*
			if(typeof YAHOO != "undefined" && !!YAHOO) {
				YAHOO.lang.extend(subClass, superClass);
			}
			*/
			for(var i = 0, len = superClasses.length; i < len; i++) {
				var superClass = superClasses[i];
				for(var a in superClass.prototype) {
					if(!subClass.prototype[a]) {
						subClass.prototype[a] = superClass.prototype[a];
					}
				}
			}
			//return subClass;
		},
		
		// Clone an object (deep cloning will break with object instances).
		clone : function(source, deep) {
			var result = {};
			for (var prop in source) {
				if (deep && typeof source[prop] == 'object') {
					result[prop] = this.clone(source[prop], deep);
				}
				else {
					result[prop] = source[prop];
				}
			}
			return result;
		},
		
		// Create a merged object.
		merge : function(source, override, deep, clone) {
			for (var prop in override) {
				source[prop] = override[prop];
			}
			return source;
		},
		
		register : function(name, className, info) {
			/*
			if(typeof YAHOO != "undefined" && !!YAHOO) {
				YAHOO.register(name, className, info);
			}
			*/
			HD.classMap[name] = className;
		},
		
		onLoad : function(callback) {
			if(typeof YAHOO != "undefined") {
				YAHOO.util.Event.onDOMReady(callback);
			} else {
				this.onLoadQueue.push(callback);
			}
		},
		
		addClass : function(element, className) {
			YAHOO.util.Dom.addClass(element, className);
		},
		
		removeClass : function(element, className) {
			YAHOO.util.Dom.removeClass(element, className);
		},
		
		replaceClass : function(element, oldClassName, className) {
			YAHOO.util.Dom.replaceClass(element, oldClassName, className);
		},
		
		hasClass : function(element, className) {
			return YAHOO.util.Dom.hasClass(element, className);
		},
		
		show : function(element) {
			HD.removeClass(element, HD.CSS_CLASSES.HIDDEN);
		},
		
		hide : function(element) {
			HD.addClass(element, HD.CSS_CLASSES.HIDDEN);
		},
		
		// YUI independent method for inserting JS
		includeJs : function(url, callback) {
			var cb = callback;
			var script = document.createElement("script");
			script.type = "text/javascript";
			script.language = "javascript";
			script.src = url;
			
			if(navigator.userAgent.indexOf("IE")>=0) {
				script.onreadystatechange = function(){
					if(script && ("loaded" == script.readyState || "complete" == script.readyState)) {
						script.onreadystatechange=null;
						cb();
					}
				};
			} else {
				script.onload=function(){
					script.onload=null;
					cb();
				};
			}
			
			document.getElementsByTagName("head")[0].appendChild(script);
		},
		
		yuiLoaded : function() {
			for(var i = 0, len = HD.onLoadQueue.length; i < len; i++) {
				HD.onLoad(HD.onLoadQueue[i]);
			}
		},
		
		containsText : function(string, text) {
			if(string === null) {
				return false;
			}
			return string.indexOf(text) > -1;
		},
		
		pluck : function(array, element) {
			var tempArray = [];
			for(var i = 0, len = array.length; i < len; i++) {
				var tempElement = array[i];
				if(tempElement != element) {
					tempArray.push(tempElement);
				}
			}
			array = tempArray;
		},
		
		log : function(message, severity) {
			// TODO use YUI logger
		}
	};
	
	HD.modules = {
		'hd' : {
			'name' : 'hd',
			'type' : 'js',
		    'path' : 'hd.js',
		    'requires' :[],
		    'skinnable' : true
		},
		
		'hd_common' : {
			'name' : 'hd_common',
			'type' : 'js',
		    'path' : 'hd_common/hd_common.js',
		    'requires' :[]
		},
		
		'hd_dwr' : {
			'name' : 'hd_dwr',
			'type' : 'js',
		    'path' : 'hd_dwr/hd_dwr.js',
		    'requires' :[]
		},
		
		'hd_event' : {
			'name' : 'hd_event',
			'type' : 'js',
		    'path' : 'hd_event/hd_event.js',
		    'requires' :[]
		},
		
		'hd_paging' : {
			'name' : 'hd_paging',
			'type' : 'js',
		    'path' : 'hd_paging/hd_paging.js',
		    'requires' :['hd_event'],
		    'skinnable' : true
		},
		
		'hd_widget' : {
			'name' : 'hd_widget',
			'type' : 'js',
		    'path' : 'hd_widget/hd_widget.js',
		    'requires' :[],
		    'skinnable' : true
		},
		
		'hd_widget_cluster' : {
			'name' : 'hd_widget',
			'type' : 'js',
		    'path' : 'hd_widget/hd_widget.js',
		    'requires' :['hd_event'],
		    'skinnable' : true
		},
		
		'hd_gallery_widget' : {
			'name' : 'hd_gallery_widget',
			'type' : 'js',
		    'path' : 'hd_gallery_widget/hd_gallery_widget.js',
		    'requires' :['hd_paging'],
		    'skinnable' : true
		},
		
		'hd_detail_widget' : {
			'name' : 'hd_detail_widget',
			'type' : 'js',
		    'path' : 'hd_detail_widget/hd_detail_widget.js',
		    'requires' :[],
		    'skinnable' : true
		},
		
		'hd_upload_widget' : {
			'name' : 'hd_upload_widget',
			'type' : 'js',
		    'path' : 'hd_upload_widget/hd_upload_widget.js',
		    'requires' :[],
		    'skinnable' : true
		},
		
		'hd_comments_widget' : {
			'name' : 'hd_comments_widget',
			'type' : 'js',
		    'path' : 'hd_comments_widget/hd_comments_widget.js',
		    'requires' :[],
		    'skinnable' : true
		},
		
		'hd_most_popular_widget' : {
			'name' : 'hd_most_popular_widget',
			'type' : 'js',
		    'path' : 'hd_most_popular_widget/hd_most_popular_widget.js',
		    'requires' :[],
		    'skinnable' : true
		},
		
		'hd_monthly_widget' : {
			'name' : 'hd_monthly_widget',
			'type' : 'js',
		    'path' : 'hd_monthly_widget/hd_monthly_widget.js',
		    'requires' :[],
		    'skinnable' : true
		},
		
		'hd_member_widget' : {
			'name' : 'hd_member_widget',
			'type' : 'js',
		    'path' : 'hd_member_widget/hd_member_widget.js',
		    'requires' :[],
		    'skinnable' : true
		},
		
		'hd_email' : {
			'name' : 'hd_email',
			'type' : 'js',
		    'path' : 'hd_email/hd_email.js',
		    'requires' :[],
		    'skinnable' : true
		}
	};
	
	HD.SORTS = {
		NEW_TO_OLD : "newToOld",
		OLD_TO_NEW : "oldToNew",
		HIGHEST_RATED : "highestRated",
		MOST_POPULAR : "mostPopular",
		MOST_VOTED : "mostVoted",
		MOST_VIEWED : "mostViewed",
		MOST_COMMENTED : "mostCommented"
	};
	
	HD.CSS_CLASSES = {
		WIDGET : "hdWidget",
		GALLERY : "hdGallery",
		MINI_GALLERY : "hdMiniGallery",
		DETAIL : "hdDetail",
		UPLOAD : "hdUpload",
		HANDLE : "hdHandle",
		CONTROL : "hdControl",
		CONTROL_PANEL : "hdControlPanel",
		CONTENT_PANEL : "hdContentPanel",
		SORT : "hdSort",
		MORE : "hdMore",
		LESS : "hdLess",
		PAGING : "hdPaging",
		PAGING_ARROW : "hdPagingArrow",
		PAGING_NONE : "hdNoPaging",
		NEXT : "hdNext",
		CURRENT : "hdCurrent",
		PREVIOUS : "hdPrevious",
		TITLE : "hdTitle",
		AUTHOR : "hdAuthor",
		LABEL : "hdLabel",
		VALUE : "hdValue",
		THUMB : "hdThumb",
		SMALL_THUMB : "hdSmallThumb",
		LARGE_THUMB : "hdLargeThumb",
		SMALL_THUMB_WRAPPER : "hdSmallThumbWrapper",
		LARGE_THUMB_WRAPPER : "hdLargeThumbWrapper",
		THUMB_OVERLAY : "hdThumbOverlay",
		DESCRIPTION : "hdDescription",
		COMMENTS : "hdComments",
		SUBMIT_COMMENT : "hdSubmitComment",
		COMMENT : "hdComment",
		CONSENT : "hdConsent",
		ITEM : "hdItem",
		DATE : "hdDate",
		SHARE : "hdShare",
		SEND_FRIEND : "hdSendFriend",
		SUBSCRIBE : "hdSubscribe",
		LOADING : "hdLoading",
		TOOL_TIP : "hdToolTip",
		HIDDEN : "hdHidden",
		WRAPPER : "hdWrapper",
		EMAIL : "hdEmail",
		EMAIL_FORM : "hdEmailForm",
		BLOG : "hdBlog",
		PHOTO : "hdPhoto",
		VIDEO : "hdVideo",
		VIDEO_PLAYER : "hdVideoPlayer",
		RATING : "hdRating",
		TAG_CLOUD : "hdTagCloud",
		TAG_LIST : "hdTagList",	
		CATEGORIES : "hdCategories",
		CATEGORY : "hdCategory",	
		TAG : "hdTag",	
		TAGS : "hdTags",
		PREVIEW : "hdPreview",
		FULL : "hdFull",
		SHORT : "hdShort",
		MOST_POPULAR : "hdMostPopular",
		MONTHLY_BREAKDOWN : "hdMonthlyBreakdown",
		AUTHOR_BREAKDOWN : "hdAuthorBreakdown",
		STAR_ON : "hdStarOn",
		STAR_OFF : "hdStarOff",
		STAR_OVER: "hdStarOver",
		STAR_HALF : "hdStarHalf",
		SUBMIT : "hdSubmit",
		FIRST : "hdFirst",
		LAST : "hdLast",
		LEFT : "hdLeft",
		RIGHT : "hdRight",
		CENTER : "hdCenter",
		AGREEMENT : "hdAgreement",
		RATED : "hdRated",
		UNRATED : "hdUnrated",
		STATIC : "hdStatic",
		EMPTY : "hdEmpty",
		ERROR: "hdError",
		NAVIGATION : "hdNavigation",
		BACK : "hdBack",
		ACTIVE : "hdActive",
		LIST : "hdList",
		FEATURE_STORIES : "hdFeatureStories",
		CAROUSEL : "hdCarousel",
		EVENTS : "hdEvents",
		EVENT : "hdEvent",
		EVENT_RSVP : "hdEventRSVP",
		RIDES : "hdRides",
		RIDE : "hdRide",
		LOCATION : "hdLocation",
		VIEW_ALL : "hdViewAll",
		VIEW : "hdView",
		CONFIRMATION : "hdConfirmation",
		MEMBER : "hdMember",
		CLOSE : "hdClose",
		ACTION : "hdAction",
		RIDE_PLANNER : "hdRidePlanner",
		SHOW_VIEW : "hdShowView",
		SHOW_ALL : "hdShowAll",
		SHOW_MAX : "hdShowMax",
		SHOW_DEFAULT : "hdShowDefault",
		NO_FLASH : "hdNoFlash",
		MEDIA : "hdMedia",
		TYPE : "hdType",
		CONTEXT : "hdContext",
		SEPARATOR : "hdSeparator",
		TWEET : "hdTweet",
		RETWEET : "hdReTweet",
		REPLY : "hdReply",
		FACEOFF : "hdFaceoff"
	};
}