var CollapsibleMenus = ( function ( ) {

	var hasClass = function ( className ) {
		return (" "+this.className+" ").indexOf(" "+className+" ") >= 0;
	}

	var addClass = function ( className ) {
		removeClass.call ( this, className );
		this.className = this.className + " " + className;
	}
	
	var removeClass = function ( className ) {
		if ( hasClass.call ( this, className ) ) {
			var re = new RegExp ( "\\b" + className + "\\b", "g" );
			this.className = this.className.replace ( re, "" );
		}
	}

	var getLists = function ( context ) {
		if ( !context ) context = document;
		var lists = [];
		var els = [
			context.getElementsByTagName("ul"),
			context.getElementsByTagName("ol")
		]
		try {
			lists = lists.concat (
				Array.prototype.slice.apply ( els[0] ),
				Array.prototype.slice.apply ( ols[1] )
			);
		} catch ( e ) {
			for ( var i = 0; i < els.length; i ++ ) {
				for ( var j = 0; j < els[i].length; j ++ ) {
					lists.push ( els[i][j] );
				}
			}
		}
		return lists;
	}
	
	var getHandle = function ( ) {
		var handle = this.firstChild;
		while ( handle.nodeType != 1 ) handle = handle.nextSibling;
		return handle;
	}

	var handle_click = function ( menu ) {
		return function ( ) {
			if ( menu.visible = !menu.visible ) {
				addClass.call ( menu, "open" );
				var items = menu.parentNode.childNodes;
				for ( var i = 0; i < items.length; i ++ ) {
					if ( items[i].nodeType == 1 ) {
						if ( items[i] != menu ) {
							items[i].visible = false;
							removeClass.call ( items[i], "open" );
						}
					}
				}
			} else {
				removeClass.call ( menu, "open" );
			}
			return false;
		}
	}

	var setupMenu = function ( menu ) {
		if ( menu instanceof Array ) {
			for ( var i = 0; i < menu.length; i ++ ) {
				setupMenu ( menu[i] );
			}
		} else {
			var items = menu.getElementsByTagName("li");
			for ( var i = 0; i < items.length; i ++ ) {
				if ( items[i].parentNode == menu ) {
					var submenu = getLists(items[i])[0];
					if ( submenu ) {
						var handle = getHandle.call ( items[i] );
						addClass.call ( handle, "handle" );
						handle.onclick = handle_click ( items[i] );
						items[i].visible = hasClass.call ( items[i], "open" );
					}
				}
			}
		}
	}

	var $ = {
		init : function ( className ) {
			if ( arguments.callee.called ) return;
			arguments.callee.called = true;
			if ( !className ) className = "collapsibleMenu";
			var lists = getLists();
			for ( var i = 0; i < lists.length; i ++ ) {
				if ( hasClass.call ( lists[i], className ) ) {
					setupMenu ( lists[i] );
					addClass.call ( lists[i], "init" );
					if ( hasClass.call ( lists[i], "inherit" ) ) {
						setupMenu ( getLists ( lists[i] ) );
					}
				}
			}
		}
	}
	
	return $;

} )();
