function firstCommonAncestor(elm1, elm2){
	var p = elm1.parentNode;
	while( !elm2.descendantOf(p) ){
		p = p.parentNode;
	}
	return p;
}
function stopEvent(e){
	try{
		e.stop();
	}catch(ex){}
}

if (Prototype.Browser.IE6 != true) {
document.observe('mouseout', function(e){
	var from = e.element();
	var to = e.relatedTarget;
	if( to && !from.descendantOf(to)){
		/* bubble up only to the child elements */
		var stopOn = null;
		if( to.descendantOf(from)){
			stopOn = from.childElements();
		}else{
			// bubble up to first common ancestor's children, see below.
			parent = firstCommonAncestor(to, from);
			stopOn = parent.childElements();
		}
		if( stopOn ){
			stopOn.invoke('observe', 'custom:mouseenter', stopEvent);
		}
		to.fire('custom:mouseenter');
		if( stopOn ){
			stopOn.invoke('stopObserving', 'custom:mouseenter', stopEvent);
		}
	}
	if ( !to || (from !== to && !to.descendantOf(from))) {
		/* mouseleave should bubble up until the to element because we have left all elements up to that one */
		var stopOn = null;
		if( to ){
			if( from.descendantOf(to) ){
				stopOn = to.childElements();
			}else{
				parent = firstCommonAncestor(from, to);
				if( parent && to.descendantOf(parent) ){
					stopOn = parent.childElements();
				}
			}
		}
		if( stopOn ){
			stopOn.invoke('observe', 'custom:mouseleave', stopEvent);
		}
		from.fire('custom:mouseleave');
		if( stopOn ){
			stopOn.invoke('stopObserving', 'custom:mouseleave', stopEvent);
		}
	}
});
}
/* end */

