		//use browser sniffing to determine if IE or Opera (ugly, but required)
		var isOpera, isIE = false;
		if(typeof(window.opera) != 'undefined'){isOpera = true;}
		if(!isOpera && navigator.userAgent.indexOf('Internet Explorer')){isIE = true;}

		//fix both IE and Opera (adjust when they implement this method properly)
		if(isOpera || isIE){
		  document.nativeGetElementById = document.getElementById;
		  //redefine it!
		  document.getElementById = function(id){
		    var elem = document.nativeGetElementById(id);
		    if(elem){
		      //verify it is a valid match!
		      if(elem.attributes['id'] && elem.attributes['id'].value == id){
		        //valid match!
		        return elem;
		      } else {
		        //not a valid match!
		        //the non-standard, document.all array has keys for all name'd, and id'd elements
		        //start at one, because we know the first match, is wrong!
		        for(var i=1;i<document.all[id].length;i++){
		          if(document.all[id][i].attributes['id'] && document.all[id][i].attributes['id'].value == id){
		            return document.all[id][i];
		          }
		        }
		      }
		    }
		    return null;
		  };
		
		
		document.getElementsByName = function(name, tag){
			if(!tag){
				tag = '*';
			}
			var elems = document.getElementsByTagName(tag);
			var res = []
			for(var i=0;i<elems.length;i++){
				att = elems[i].getAttribute('name');
				if(att == name) {
					res.push(elems[i]);
				}
			}
			return res;
		}
		}
		
		
		/**
		 * X-browser event handler attachment and detachment
		 * TH: Switched first true to false per http://www.onlinetools.org/articles/unobtrusivejavascript/chapter4.html
		 *
		 * @argument obj - the object to attach event to
		 * @argument evType - name of the event - DONT ADD "on", pass only "mouseover", etc
		 * @argument fn - function to call
		 */
		function o2AddEvent (obj, evType, fn) {
		 if (obj.addEventListener != null){
			obj.addEventListener(evType, fn, false);
		    return true;
		 } else if (obj.attachEvent){
			var r = obj.attachEvent("on"+evType, fn);
		    return r;
		 } else {
		    return false;
		 }
		}
		function removeEvent(obj, evType, fn, useCapture){
		  if (obj.removeEventListener){
		    obj.removeEventListener(evType, fn, useCapture);
		    return true;
		  } else if (obj.detachEvent){
		    var r = obj.detachEvent("on"+evType, fn);
		    return r;
		  } else {
		    alert("Handler could not be removed");
		  }
		}