	function MozillaMenuItem(id, body, link)
	{
		//MozillaMenuItem.BACKGRD_HILITE_COLOR = "#E5D083";
		//MozillaMenuItem.BACKGRD_NORMAL_COLOR = "#EBE2C7";

		this.id = id;
		this.link = link;

		this.menuItem = MenuFactory.getMenuFactory().createDivElement(this.id, body);
		this.element = this.menuItem.element;
		this.style = this.element.style;

		this.style.visibility = "hidden";
		this.style.background = Menu.getBackgroundColor();
		this.style.paddingRight = "10px";
		this.style.paddingLeft = "10px";
		this.style.fontFamily = "Arial, Helvetica, sans-serif";
		this.style.fontSize = "10px";

		// changes cursor to pointer and sets status window to print out the MenuItems link
		// thus we emulate an actual links behavior
		this.element.addEventListener("mouseover", function(event)
		{
			this.style.cursor = "pointer";
			window.status = link;
			event.currentTarget.style.background = Menu.getRolloverColor();

		}, false);

		this.element.addEventListener("mouseout", function(event)
		{
			window.status = "";
			event.currentTarget.style.background = Menu.getBackgroundColor();

		}, false);

		this.element.addEventListener("mouseup", function(event)
		{
			window.top.location.href = link;

		}, false);
	}

	// this class creates the master menu list
	// which controls macro behavior of menuItem subelements
	//
	function MozillaMainMenu()
	{
		// obtain unique id for menu and register menu object with registrar object
		this.id = "mainMenu" + MainMenuRegistrar.getRegistrar().getMainMenus().length;
		MainMenuRegistrar.getRegistrar().addMainMenu(this);

		this.mainMenu = MenuFactory.getMenuFactory().createDivElement(this.id, null);
		this.element = this.mainMenu.element;
		this.style = this.element.style;

		this.style.position = "absolute";
		this.style.visibility = "hidden";
		this.style.border = "solid black 1px";

		// some browsers cannot account for body margins specified in css... account for them here
		// (see setAnchorImageTop and setAnchorImageLeft)
		//
		this.cssTopPadding = (Menu.getTopMargin() != null ? Menu.getTopMargin() : 0);
		this.cssLeftPadding = (Menu.getLeftMargin() != null ? Menu.getLeftMargin() : 0);

		// controls behavior when a user mouses on or off the menu itself (v the triggerElement)
		// the mouseout function is set on a timer; this allows a buffer to re-mouse over menu items
		// the mouseover function releases the timer but will not reveal hidden menus; that is the job of the triggerElement
		//
		this.element.addEventListener("mouseout", function(event) { Menu.menuTimer = setTimeout("MozillaMainMenu.hideMenuById('" + event.currentTarget.id + "'); MozillaMainMenu.showAnchorOffById('" + event.currentTarget.id + "');", 500); }, false);
		this.element.addEventListener("mouseover", function(event) { clearTimeout(Menu.menuTimer); }, false);

		MozillaMainMenu.prototype.setAnchorImageTop = function(imageElement)
		{
			this.anchorElement = imageElement;
			this.anchorElementPosition = "top";

			this.element.anchorElement = imageElement;

			// position the MozillaMainMenu beneath and left justified to the imageElement image
			if(browser.isKHTML)
			{
				// bug no. 51472: Konqueror no longer correctly calculates
				// absolute position when summing offsetTop and offsetLeft of all offsetParents... works on KHTML browsers earlier than 3.1
				// this padding compensates for the offage on the current site
				//
				this.style.left = (Element.getLeftPosition(this.anchorElement) + this.cssLeftPadding) + "px";
				this.style.top = (Element.getTopPosition(this.anchorElement) + this.cssTopPadding + this.anchorElement.height) + "px";
			}
			else
			{
				this.style.left = Element.getLeftPosition(this.anchorElement) + "px";
				this.style.top = (Element.getTopPosition(this.anchorElement) + this.anchorElement.height) + "px";
			}

			// make the anchor element also a trigger to display the MozillaMainMenu
			this.setTriggerElement(this.anchorElement);
		}

		MozillaMainMenu.prototype.setAnchorImageLeft = function(imageElement)
		{
			this.anchorElement = imageElement;
			this.anchorElementPosition = "left";

			this.element.anchorElement = imageElement;

			// position the MozillaMainMenu beneath and left justified to the imageElement image
			if(browser.isKHTML)
			{
				// bug no. 51472: Konqueror no longer correctly calculates
				// absolute position when summing offsetTop and offsetLeft of all offsetParents... works on KHTML browsers earlier than 3.1
				// this padding compensates for the offage on the current site
				//
				this.style.left = (Element.getLeftPosition(this.anchorElement) + this.cssLeftPadding + this.anchorElement.width) + "px";
				this.style.top = (Element.getTopPosition(this.anchorElement) + this.cssTopPadding) + "px";
			}
			else
			{
				this.style.left = (Element.getLeftPosition(this.anchorElement) + this.anchorElement.width) + "px";
				this.style.top = Element.getTopPosition(this.anchorElement) + "px";
			}

			// make the anchor element also a trigger to display the MozillaMainMenu
			this.setTriggerElement(this.anchorElement);
		}

		MozillaMainMenu.prototype.resetAnchorImage = function()
		{
			if(this.anchorElement != null)
			{
				if(this.anchorElementPosition == "left")
				{
					this.setAnchorImageLeft(this.anchorElement);
				}
				else this.setAnchorImageTop(this.anchorElement);
			}
		}

		MozillaMainMenu.prototype.setTriggerElement = function(documentElement)
		{
			if(documentElement != this.triggerElement)
			{
				this.triggerElement = documentElement;

				// create a reference within the trigger element to point back to this menu (for use in events)
				// and vice versa
				this.triggerElement.attachedMenu = this.element;
				this.element.triggerElement = documentElement;

				// event control when a user mouses on or off the trigger element
				//
				this.triggerElement.addEventListener("mouseout", function(event) { Menu.menuTimer = setTimeout("MozillaMainMenu.hideMenuById('" + event.currentTarget.attachedMenu.id + "'); MozillaMainMenu.showAnchorOffById('" + event.currentTarget.attachedMenu.id + "');", 500); }, false);
				this.triggerElement.addEventListener("mouseover", function(event) { clearTimeout(Menu.menuTimer); MozillaMainMenu.showMenuById(event.currentTarget.attachedMenu.id); MozillaMainMenu.showAnchorOnById(event.currentTarget.attachedMenu.id); }, false);
			}
		}

		MozillaMainMenu.prototype.setAnchorImageRollOverSrc = function(imageLocation)
		{
				// cache the image
				//
				this.triggerElement.rolloverImage = new Image();
				this.triggerElement.rolloverImage.src = imageLocation;
				// save the on and off url locations for easy retrieval and storage
				this.triggerElement.onsrc = this.triggerElement.rolloverImage.src;
				this.triggerElement.offsrc = this.triggerElement.src;
		}
		MozillaMainMenu.prototype.setAnchorImageRollOver = function(image)
		{
				// allow users to input image object... this is
				// inefficient however as the object is recached in the
				// function call below
				//
				this.setAnchorImageRolloverSrc(image.src);
		}

		// trigger rollover methods (static and object methods)
		//
		// points to showAnchorOnById to avoid code redundancy
		//
		MozillaMainMenu.prototype.showAnchorOn = function()
		{
			MozillaMainMenu.showAnchorOnById(this.element.id);
		}
		// provide mainMenuId to this method
		function showAnchorOnById(elementId)
		{
			var triggerElement = document.getElementById(elementId).triggerElement;
			// change source of trigger image to that designated as "on"
			// if there is no "on" image attribute, skip
			if(triggerElement && triggerElement.offsrc) triggerElement.src = triggerElement.onsrc;
		}

		// points to showAnchorOffById to avoid code redundancy
		//
		MozillaMainMenu.prototype.showAnchorOff = function()
		{
			MozillaMainMenu.showAnchorOffById(this.element.id);
		}
		// provide mainMenuId to this method
		function showAnchorOffById(elementId)
		{
			var triggerElement = document.getElementById(elementId).triggerElement;
			// change source of trigger image to that designated as "off"
			// if there is no "off" image attribute, skip
			if(triggerElement && triggerElement.offsrc) triggerElement.src = triggerElement.offsrc;
		}

		MozillaMainMenu.prototype.addMenuItem = function(body, link)
		{
			// dynamically generate the id attribute of the menuItem
			// by appending the current number of menuItems children to the MozillaMainMenu id
			//
			var menuItemId = this.id + "_" + this.element.childNodes.length;

			var menuItem = MenuFactory.getMenuFactory().createMenuItem(menuItemId, body, link);

			// inject the menuitem element into the MozillaMainMenu element
			this.element.appendChild(menuItem.element);
		}

		// object method... points to static method MozillaMainMenu.hideMenuById() to avoid redundancy
		//
		MozillaMainMenu.prototype.hideMenu = function()
		{
			MozillaMainMenu.hideMenuById(this.element.id);
		}

		// static method
		// there isnt a way to pass object references into a function through setTimeout()... therefore we need to use the element id 
		// instead of actual element reference here
		//
		function hideMenuById(elementId)
		{
			var childMenuItems = document.getElementById(elementId).childNodes;
			for(var i=0; i < childMenuItems.length; i++) childMenuItems[i].style.visibility = "hidden";
			document.getElementById(elementId).style.visibility = "hidden";
		}

		// object method... points to static method MozillaMainMenu.showMenuById() to avoid redundancy
		//
		MozillaMainMenu.prototype.showMenu = function()
		{
			MozillaMainMenu.showMenuById(this.element.id);
		}

		// static method
		// this method takes an id as an arugment in order to remain consistent with the hideMenuById method above
		function showMenuById(elementId)
		{
			// hide all other menus before displaying this one
			MainMenuRegistrar.getRegistrar().hideMainMenus();

			var childMenuItems = document.getElementById(elementId).childNodes;
			for(var i=0; i < childMenuItems.length; i++) childMenuItems[i].style.visibility = "visible";
			document.getElementById(elementId).style.visibility = "visible";
		}

		MozillaMainMenu.prototype.write = function()
		{
			document.body.appendChild(this.element);
		}

	}
