// cookieMonster.js
// Tony Schilling
// Created:  01/20/2007
// Last Updated:  03/16/2014

// Use XPCOM to detect browser tab changes and
// interface to the cookie manager and the
// permission manager,
// in order to read and possibly update
// the cookie status for the current URI

// Define "namespace" for Cookie Monster objects
if(!s1tony) var s1tony = {};
if(!s1tony.CM) s1tony.CM = {};
//let s1tony.CM = {}

// Constants
const nsIPermissionManager = Components.interfaces.nsIPermissionManager;
const nsICookiePermission = Components.interfaces.nsICookiePermission;

const CM_ICON_DEFAULT_ORIGINAL = "chrome://cookiemonster/skin/face-monkey-small.png";
const CM_ICON_DEFAULT = "chrome://cookiemonster/skin/cookie-monster-logo.png";
const CM_ICON_TEMP_ALLOW = "chrome://cookiemonster/skin/face-angel-temp.png";
const CM_ICON_ALLOW = "chrome://cookiemonster/skin/face-angel.png";
const CM_ICON_DENY = "chrome://cookiemonster/skin/face-devil-grin.png";
const CM_ICON_SESSION = "chrome://cookiemonster/skin/face-glasses.png";
const CM_ICON_ALLOW_OG = "chrome://cookiemonster/skin/face-angel-og.png";
const CM_ICON_SESSION_OG = "chrome://cookiemonster/skin/face-glasses-og.png";

const CM_TOP_LEVEL = 0;
const CM_SECOND_LEVEL = 1;
const CM_URL_STANDARD_LEVEL = 2;
const CM_CA_LEVEL_TEMP_ALLOW = -1;
const CM_CA_LEVEL_DEFAULT = 0;

const CM_COOKIE_ACCESS_DEFAULT = "Default";
const CM_COOKIE_ACCESS_DEFAULT_ORIGINAL = "DefaultOriginal";
const CM_COOKIE_ACCESS_DENY = "Deny";
const CM_COOKIE_ACCESS_ALLOW = "Allow";
const CM_COOKIE_ACCESS_SESSION = "Session";
const CM_COOKIE_ACCESS_TEMP_ALLOW = "Temp";
const CM_COOKIE_ACCESS_ALLOW_OG = "AllowOG";
const CM_COOKIE_ACCESS_SESSION_OG = "SessionOG";

const CM_PERMISSION_TYPE_COOKIE = "cookie";
const CM_PREFERENCE_TYPE_COOKIE_TEMP = "tempcookie";
const CM_PREFERENCE_TYPE_GLOBAL_OVERRIDE = "overrideglobal";
const CM_PREF_COOKIE_BEHAVIOR = 0;
const CM_PREF_LIFETIME_POLICY = 1;
const CM_PREF_BLOCK_THIRD_PARTY = 1;
const CM_GLOBAL_COOKIE_PERM_REJECTED = "Rejected";

// Retrieve the URL for the current (active) browser
/*function getURL()
{
    var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].
        getService(Components.interfaces.nsIWindowMediator);
    var recentWindow = wm.getMostRecentWindow("navigator:browser");
    return recentWindow ? recentWindow.content.document.location : null;
}*/

// Based upon code sample from MozillaZine
// http://kb.mozillazine.org/Progress_listeners
// Progress listeners allow extensions to be notified of events associated
// with documents loading in the browser and with tab switching events.
// Progress listeners implement the nsIWebProgressListener interface.
// Create an object which implements nsIWebProgressListener
s1tony.CM.urlBarListener =
{
    QueryInterface: function(aIID)
    {
        if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
            aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
            aIID.equals(Components.interfaces.nsISupports))
            return this;
        throw Components.results.NS_NOINTERFACE;
    },

    onLocationChange: function(aProgress, aRequest, aURI)
    {
    	if ((aURI != null) && s1tony.CM.cookieMonster.extGetIsAllowGlobalOverride())
    	{
    		s1tony.CM.cookieMonster.extCheckGlobalCookiePref(aURI);
    	}
    	if (!aProgress.DOMWindow.frameElement)
    	{
        	s1tony.CM.cookieMonster.processNewURL(aProgress, aRequest, aURI);
    	}
        return 0;
    },

    onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus)
	{
    	// If you use myListener for more than one tab/window, use
		// aWebProgress.DOMWindow to obtain the tab/window which triggers the state change
//		if (aStateFlags & Components.interfaces.nsIWebProgressListener.STATE_START)
//		{
//			// This fires when the load event is initiated
//			//alert("Start State Flags:  " + aStateFlags  + "  Request Name:  " + aRequest.name);
//		}
//		
//		if (aStateFlags & Components.interfaces.nsIWebProgressListener.STATE_STOP)
//		{
//			// This fires when the load finishes
//			//alert("Stop State Flags:  " + aStateFlags + "  Host:  " + aWebProgress.DOMWindow.document.baseURIObject.host  + "  Request Name:  " + aRequest.name);
//			
//			// Filter out the REQUEST only stops, as they do not indicate
//			// the completion of the page load
//			if (aStateFlags & Components.interfaces.nsIWebProgressListener.STATE_IS_NETWORK)
//			//if(aStateFlags & Components.interfaces.nsIWebProgressListener.STATE_IS_WINDOW &
//			//	aStateFlags & Components.interfaces.nsIWebProgressListener.STATE_IS_NETWORK)
//			{
//				var currentBrowser = aWebProgress.DOMWindow.document;
//				var location = aRequest.QueryInterface(Components.interfaces.nsIChannel).URI;
////				alert("Load Event Finished for gBrowser :  " + gBrowser.currentURI.host +
////					  " and aWebProgress.DOMWindow:  " + currentBrowser.baseURIObject.host +				
////					  " and aRequest URI:  " + location);
//
//				// Process any cookies not assigned to a host
//				//cookieMonster_ThirdParty.processUnassigned(this._currentLoadHost);
//                //cookieMonster.setThirdPartyCookieSubMenu(cookieMonster_ThirdParty.retrieveData(this._currentLoadHost));				
//			}
//		}
		
		return 0;
	},
    onProgressChange: function() {return 0;},
    onStatusChange: function() {return 0;},
    onSecurityChange: function() {return 0;},
    onLinkIconAvailable: function() {return 0;}
};

// Based upon code sample from MozillaZine
// http://kb.mozillazine.org/Progress_listeners
// Progress listeners allow extensions to be notified of events associated
// with documents loading in the browser and with tab switching events.
// Progress listeners implement the nsIWebProgressListener interface.
// Create an object which implements nsIWebProgressListener
s1tony.CM.tabProgressListener =
{
    QueryInterface: function(aIID)
    {
        if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
            aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
            aIID.equals(Components.interfaces.nsISupports))
            return this;
        throw Components.results.NS_NOINTERFACE;
    },

    onLocationChange: function(aBrowser, aProgress, aRequest, aURI)
    {
    	//alert("Location Change:  " + aBrowser.currentURI.asciiHost);
        return 0;
    },

    onStateChange: function(aBrowser, aWebProgress, aRequest, aStateFlags, aStatus)
	{
		const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;

		if (aStateFlags & nsIWebProgressListener.STATE_START && aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK)
		{
			// This fires when the load event of type network is initiated
			//alert("Start State Flags:  " + aStateFlags  + "  Request Name:  " + aRequest.name);
			s1tony.CM.cookieRequest.clearBrowser(aBrowser);			
		}
		
		if (aStateFlags & nsIWebProgressListener.STATE_STOP && aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK)
		{
				// Process any cookie requests made by browser during load
				s1tony.CM.cookieRequest.processCookieRequests(aBrowser);					
		}
		
		return 0;
	},
    onProgressChange: function() {return 0;},
    onStatusChange: function() {return 0;},
    onSecurityChange: function() {return 0;},
    onLinkIconAvailable: function() {return 0;}
};

s1tony.CM.customizableUIListener = 
{
	onWidgetAfterDOMChange: function(aNode, aNextNode, aContainer, aWasRemoval)
	{
    	if (aNode.id === "cookiemonster-status")
    	{
			s1tony.CM.cookieMonsterButton.checkButtonClick();
    		//console.log("onWidgetAfterDOMChange - node: " + aNode.id + ", aContainer: " + aContainer.id);    		
    	}		
	}
};

s1tony.CM.cookieMonsterButton = 
{
	_elementId: null,
	_element: null,
	_cmReference: null,
	_currentIcon: null,
	_currentPopupId: null,

    /**
     * Initialize this object
     */	
	init: function(cmReference, elementId)
	{
		this._cmReference = cmReference;
		this._elementId = elementId;
		
		// Determine if Australis
		if (document.getElementById("PanelUI-menu-button"))
		{
	        var cmButtonLocation = CustomizableUI.getPlacementOfWidget(this._elementId);    
	        CustomizableUI.addListener(s1tony.CM.customizableUIListener);	        
	    	console.log("Firefox running Australis");

			if (cmButtonLocation)
			{
				this._element = document.getElementById(this._elementId);								
			}
			else if (!s1tony.CM.nsPreferences.getBoolPref("firstRunDone", false))
			{
	        	s1tony.CM.nsPreferences.setBoolPref("firstRunDone", true);

	        	// Since first run, place on nav-bar bar
		    	CustomizableUI.addWidgetToArea(this._elementId, "nav-bar");
				this._element = document.getElementById(this._elementId);
			}
		}
		else
		{
	    	console.log("Firefox running Old School");
		
			this._element = document.getElementById(this._elementId);
			
			if (!this._element && !s1tony.CM.nsPreferences.getBoolPref("firstRunDone", false))
			{
	        	s1tony.CM.nsPreferences.setBoolPref("firstRunDone", true);
	        	
	        	// Since first run, place on nav-bar bar
		    	installButton("nav-bar", this._elementId);
				this._element = document.getElementById(this._elementId);				
			}
		}
			
		// Set tooltip attribute for enhanced tool tip info,
		// if element available
		if (this._element)
		{
	        this._element.removeAttribute("tooltiptext");
			this._element.setAttribute("tooltip", "cookie-results");
			
			this._element.addEventListener('command',
				function(event) {cmReference.extThirdPartyMenuLoadHandler(event)}, false);
		}
	
		/**
		 * Installs the toolbar button with the given ID into the given
		 * toolbar, if it is not already present in the document.
		 *
		 * @param {string} toolbarId The ID of the toolbar to install to.
		 * @param {string} id The ID of the button to install.
		 * @param {string} afterId The ID of the element to insert after. @optional
		 */
		function installButton(toolbarId, id, afterId) {
		    if (!document.getElementById(id)) {
		        var toolbar = document.getElementById(toolbarId);
		
		        // If no afterId is given, then append the item to the toolbar
		        var before = null;
		        if (afterId) {
		            let elem = document.getElementById(afterId);
		            if (elem && elem.parentNode == toolbar)
		                before = elem.nextElementSibling;
		        }
		
		        toolbar.insertItem(id, before);
		        toolbar.setAttribute("currentset", toolbar.currentSet);
		        document.persist(toolbar.id, "currentset");
		
		        if (toolbarId == "addon-bar")
		            toolbar.collapsed = false;
		    }
		}			
	},

    /**
     * Get the cookie monster button
     */
	getButton: function()
	{
		var result = null;
		
		if (this._element)
		{
			result = this._element;
		}
		else
		{
			// Try to obtain reference
			this._element = document.getElementById(this._elementId);

			// Set tooltip attribute for enhanced tool tip info,
			// if element available
			if (this._element && this._element.hasAttribute("tooltiptext"))
			{
				this._element.removeAttribute("tooltiptext");
				this._element.setAttribute("tooltip", "cookie-results");				
				var that = this;
				
				this._element.addEventListener('command',
					function(event) {that._cmReference.extThirdPartyMenuLoadHandler(event)}, false);
			}

			result = this._element;
		}

		return result;
	},

    /**
     * Set the icon for the Cookie Monster menu button
     * @param {String} icon
     */
	setIcon: function(icon)
	{
		this._currentIcon = icon;
		var button = this.getButton();
		
		if (button)
		{
    		button.setAttribute("image", icon);				
		}
	},
	
    /**
     * Get the current icon,
     * representing cookie access for the URI
     */
	getIcon: function()
	{
		return this._currentIcon;
	},
	
    /**
     * Set the popup attribute for the Cookie Monster menu button
     * @param {String} id
     */
	setPopup: function(id)
	{
		this._currentPopupId = id;
		var button = this.getButton();
		
		if (button)
		{
    		button.setAttribute("popup", id);				
		}			
	},

    /**
     * This should only be called if the Cookie Monster menu button
     * has not yet been found (could occur if button in panel)
     */
	checkButtonClick: function()
	{	
		if (this._currentPopupId && this._currentPopupId.length > 0)
		{
			this.setIcon(this._currentIcon);
			this.setPopup(this._currentPopupId);
		}
	}
};

s1tony.CM.cookieMonster =
{
    _oldURL: null,
    _oldAccess: null,
    _menuBundle: null,
    _userDefault: null,
    _cookieMonsterMenu: null,
    _cookieMonsterMenuId: null,
    _cookieMonsterSubMenu: null,
    _cookieMonsterSubMenuId: null,
    _cookieMonsterMenuArray: null,
    _secondLevel: false,
    _secondLevelId: null,
    _secondLevelMenuOption: null,
    _thirdPartyMenuOption: null,
    _thirdPartyId: null, 
    _globalOverrideId: null,
    _globalOverrideMenuOption: null,    
    _usingGlobalOverride: false,
    _allowGlobalOverride: false,
    _currentGlobalPreference: new Array(),
    _currentSubMenu: CM_SECOND_LEVEL,
    _reloadOnPermissionChange: false,
    _menuStatus: false,
    _iconList: null,
    _flagMenuEvent: false,
    _flagGlobalCookieEvent: false,
    //_statusImageAttribute: "src",

    init: function()
    {
        var copyURI = null;
        var that = this;
        
        // Listen for webpage loads
        gBrowser.addProgressListener(s1tony.CM.urlBarListener);
        gBrowser.addTabsProgressListener(s1tony.CM.tabProgressListener); 
		gBrowser.tabContainer.addEventListener("TabClose", this.tabUnload, false);

        copyURI = Components.classes["@mozilla.org/network/io-service;1"].
            getService(Components.interfaces.nsIIOService);
        this._oldURL = copyURI.newURI("about:blank", null, null);
        this._oldAccess = new Array(CM_COOKIE_ACCESS_DEFAULT, CM_COOKIE_ACCESS_DEFAULT, CM_COOKIE_ACCESS_DEFAULT);

        // Add extension name to s1tony.CM.nsPreferences
        s1tony.CM.nsPreferences.mBranch = "cookiemonster";
        
        // Initialize CookieInfo, Utils, ShowCookieMenu, ShowCookieExceptions and CookieMonsterButton
        s1tony.CM.cookieInfo.init();
        s1tony.CM.utils.init();
        s1tony.CM.showCookiesMenu.init();
        s1tony.CM.showCookieExceptions.init();
        s1tony.CM.cookieMonsterButton.init(this, "cookiemonster-status");

        // Register preferences and permission observers
        s1tony.CM.prefObserver.register();
        s1tony.CM.observerService.register();

        // Retrieve users's default cookie permissions
        this._userDefault = s1tony.CM.prefObserver.getCookiePrefString();
		this._currentGlobalPreference = s1tony.CM.prefObserver.getCookiePrefArray();
        
        // Create a reference to all the menu elements
        this._menuBundle = document.getElementById("cookie-menu-labels");
        this._cookieMonsterMenuId = "cookiemonster-menu";
    	this._secondLevelId = "option-second-level";
    	this._cookieMonsterSubMenuId = "cookie-access-alternate";
    	this._globalOverrideId = "show-global-override";
    	this._thirdPartyId = "cookie-thirdparty-permissions";
    	
        // Retrieve the current value for secondlevelurl and
        // initialize secondlevelurl in StatusbarMenu
        this._secondLevel = s1tony.CM.nsPreferences.getBoolPref("secondlevelurl", false);
        this._cookieMonsterMenu = document.getElementById(this._cookieMonsterMenuId);
        this._cookieMonsterMenu.addEventListener('command', function(event) {that.extMenuCommandHandler(event)},
            true);
          	
        this._cookieMonsterSubMenu = document.getElementById(this._cookieMonsterSubMenuId);        
        this._cookieMonsterMenuArray = new Array(this._cookieMonsterMenu, this._cookieMonsterSubMenu);
        this._secondLevelMenuOption = document.getElementById(this._secondLevelId);
        
        if (this._secondLevel)
        {
            this._secondLevelMenuOption.setAttribute("checked", "true");
        	this.switchCookieSubMenu();
        }

        this._thirdPartyMenuOption = document.getElementById(this._thirdPartyId);
                
        // Retrieve the current value for enableglobalcookieoverride
        this._allowGlobalOverride = s1tony.CM.nsPreferences.getBoolPref("enableglobalcookieoverride", false);
		this._globalOverrideMenuOption = document.getElementById(this._globalOverrideId);
		this._globalOverrideMenuOption.setAttribute("disabled", !this._allowGlobalOverride);
		
        // Retrieve the current value for reloadOnPermissionChange
        this._reloadOnPermissionChange = s1tony.CM.nsPreferences.getBoolPref("reloadonpermissionchange", false);		
		
        // Load icons into _iconList (actually an object)
        this._iconList = new Object();
        
        // Determine what default icon to use
        if (!s1tony.CM.nsPreferences.getBoolPref("originaldefaulticon", false))
        {
        	this._iconList[CM_COOKIE_ACCESS_DEFAULT] = CM_ICON_DEFAULT;       	
        }
        else
        {
        	this._iconList[CM_COOKIE_ACCESS_DEFAULT] = CM_ICON_DEFAULT_ORIGINAL;        	
        }

        this._iconList[CM_COOKIE_ACCESS_TEMP_ALLOW] = CM_ICON_TEMP_ALLOW;
        this._iconList[CM_COOKIE_ACCESS_ALLOW] = CM_ICON_ALLOW;
        this._iconList[CM_COOKIE_ACCESS_DENY] = CM_ICON_DENY;
        this._iconList[CM_COOKIE_ACCESS_SESSION] = CM_ICON_SESSION;
        this._iconList[CM_COOKIE_ACCESS_ALLOW_OG] = CM_ICON_ALLOW_OG;
        this._iconList[CM_COOKIE_ACCESS_SESSION_OG] = CM_ICON_SESSION_OG;
    },

    uninit: function()
    {
        gBrowser.removeProgressListener(s1tony.CM.urlBarListener);
        gBrowser.removeTabsProgressListener(s1tony.CM.tabProgressListener);       
		gBrowser.tabContainer.removeEventListener("TabClose", this.tabUnload, false);
        
        // Unregister all observers
        s1tony.CM.prefObserver.unregister();
        s1tony.CM.observerService.unregister();
    },
    
    tabUnload: function(evt)
    {
    	var browser = gBrowser.getBrowserForTab(evt.target);
    	//s1tony.CM.cookieRequest.removeHost(browser.currentURI.asciiHost);
    	s1tony.CM.cookieRequest.removeBrowser(browser);
    },

    processNewURL: function(aProgress, aRequest, aURI)
    {
        // Check to see if the URI contains any data
        if ((aURI != null) && (aURI.asciiHost != undefined))
        {
            // If necessary, "Enable" popup menu for statusbar panel
            this.setStatusMenuEnabled(true);

            // Check if the URI is changing
            if (aURI.spec != this._oldURL.spec)
            {
                // Update oldURL and oldAccess
                this._oldURL = aURI.clone();
                this._oldAccess = s1tony.CM.cookieInfo.checkPermissionArray(aURI, CM_PERMISSION_TYPE_COOKIE);

                // if host is empty, "disable" statusbar menu \s\w*
                if (aURI.asciiHost.replace(/^\s*$/, "") == "")
                {
                    this.setStatusMenuEnabled(false);
                }
            }

            // Update statusbar menu
            this.updateStatusbarMenu(this._oldURL.asciiHost, this._oldAccess);
        }
        else
        {
            // If URI is blank, then "disable" popup menu for statusbar panel
            this.setStatusMenuEnabled(false);
        }
    },

    // Update the text and menuitems in the statusbar popup menu
    updateStatusbarMenu: function(aHost, aAccess)
    {
        //alert("Host:  " + aHost + "  Access:  " + aAccess[CM_TOP_LEVEL]);
        var menuNodes = null;
        var hostDisplay = aHost;
        var hostDomain = s1tony.CM.cookieInfo.getSecondLevelHost(aHost);
        var hostAccess = aAccess[CM_URL_STANDARD_LEVEL];
        var checkOldAccess = aAccess[CM_TOP_LEVEL];
        var permissionsDisplayTop = document.getElementById("permissions-top");
        var permissionsDisplaySecond = document.getElementById("permissions-second");
        var permissionsDisplayResult = document.getElementById("permissions-result");
        var cookieTooltipSite = document.getElementById("cookie-group-site");
        var cookieTooltipDomain = document.getElementById("cookie-group-domain");
        var cookieTooltipResult = document.getElementById("cookie-group-result");
        var showCookiesCurrentDomain = document.getElementById("show-cookies-site");
        var deleteCookiesCurrentDomain = document.getElementById("delete-cookies-site");
        
        // If the user has selected 2nd Level domains,
        // then display as such
        if (this._secondLevel)
        {
            hostDisplay = hostDomain;
            checkOldAccess = aAccess[CM_SECOND_LEVEL];
        }

        // Walk the menus to update the menuitems
        for (var x = 0; x < this._cookieMonsterMenuArray.length; x++)
        {
	        if (this._cookieMonsterMenuArray[x].hasChildNodes())
	        {
	            menuNodes = this._cookieMonsterMenuArray[x].childNodes;
	            for (var i = 0; i < menuNodes.length; i++)
	            {
	                var menu = menuNodes [i];
	                if (menu.nodeName != "menuitem")
	                {
	                    continue;
	                }
	
	                // If access level matches node, then name
	                // current-access in order for image to show
	                var idName = menu.getAttribute("id").split("-");
	                var idDomain = idName[idName.length - 2];
	                var idParsed = idName[idName.length - 1];
	
	                if (idDomain == "top")
	                {
	                    if (idParsed == aAccess[CM_TOP_LEVEL].toString().toLowerCase())
	                    {
	                        menu.setAttribute("name","current-access");
	                    }
	                    else
	                    {
	                        menu.setAttribute("name","cookie-top");
	                    }
	                    menu.setAttribute("label", this._menuBundle.getString(idParsed) + " " + aHost);
	                }
	                else if (idDomain == "second")
	                {
	                    if (idParsed == aAccess[CM_SECOND_LEVEL].toString().toLowerCase())
	                    {
	                        menu.setAttribute("name","current-access");
	                    }
	                    else
	                    {
	                        menu.setAttribute("name","cookie-two");
	                    }
	                    menu.setAttribute("label", this._menuBundle.getString(idParsed) + " " + hostDomain);
	                }
	                else if (idDomain == "default")
	                {
	                    if (idParsed == aAccess[CM_URL_STANDARD_LEVEL].toString().toLowerCase())
	                    {
	                        menu.setAttribute("name","current-access");
	                    }
	                    else
	                    {
	                        menu.setAttribute("name","cookie-default");
	                    }
	                    menu.setAttribute("label", this._menuBundle.getString(idParsed) + " (" + this._userDefault + ")");
	                }
	                else if (idDomain == "access")
	                {
	                	// This is for the old version of the menu
	                    if (idParsed == checkOldAccess.toString().toLowerCase())
	                    {
	                        menu.setAttribute("name","current-access");
	                    }
	                    else
	                    {
	                        menu.setAttribute("name","cookie-access");
	                    }
	                    menu.setAttribute("label", this._menuBundle.getString(idParsed) + " " + hostDisplay);
	
		                // For default, display users cookie permission preferences
		                if (idParsed == CM_COOKIE_ACCESS_DEFAULT.toLowerCase())
		                {
		                    menu.setAttribute("label", this._menuBundle.getString(idParsed) + " (" + this._userDefault + ")");
		                }
	                }
	            }
	        }
        }

        // Add domain name to show cookies for current site and delete cookies
        // for current site
        showCookiesCurrentDomain.setAttribute("label", this._menuBundle.getString("showcurrentcookies") + " " + hostDomain);
        showCookiesCurrentDomain.setAttribute("name", hostDomain);
        deleteCookiesCurrentDomain.setAttribute("label", this._menuBundle.getString("deletecurrentcookies") + " " + hostDomain);
        deleteCookiesCurrentDomain.setAttribute("name", hostDomain);
        
        // Update permissions Synopsis and Enhanced Tooltip
        permissionsDisplayTop.setAttribute("label", this._menuBundle.getString("sitepermissions") +
        						" (" + aHost + "):  " + this._menuBundle.getString(aAccess[CM_TOP_LEVEL]));
        permissionsDisplaySecond.setAttribute("label", this._menuBundle.getString("domainpermissions") +
        						" (" + hostDomain + "):  " + this._menuBundle.getString(aAccess[CM_SECOND_LEVEL]));
        permissionsDisplayResult.setAttribute("label", this._menuBundle.getString("permissionsresultfor") +
        						" " + aHost + ":  " + this._menuBundle.getString(hostAccess));

        permissionsDisplayTop.setAttribute("image", this.getIcon(aAccess[CM_TOP_LEVEL])); //this._iconList[aAccess[CM_TOP_LEVEL]]
        permissionsDisplaySecond.setAttribute("image", this.getIcon(aAccess[CM_SECOND_LEVEL]));
        permissionsDisplayResult.setAttribute("image", this.getIcon(hostAccess));

        cookieTooltipSite.firstChild.setAttribute("label", this._menuBundle.getString("sitepermissions") +
        											":  " + this._menuBundle.getString(aAccess[CM_TOP_LEVEL]));
        cookieTooltipDomain.firstChild.setAttribute("label", this._menuBundle.getString("domainpermissions") +
        											":  " + this._menuBundle.getString(aAccess[CM_SECOND_LEVEL]));
        cookieTooltipResult.firstChild.setAttribute("label", this._menuBundle.getString("permissionsresult") +
        											":  " + this._menuBundle.getString(hostAccess));

        cookieTooltipSite.firstChild.setAttribute("image", this.getIcon(aAccess[CM_TOP_LEVEL]));
        cookieTooltipDomain.firstChild.setAttribute("image", this.getIcon(aAccess[CM_SECOND_LEVEL]));
        cookieTooltipResult.firstChild.setAttribute("image", this.getIcon(hostAccess));

        cookieTooltipSite.lastChild.setAttribute("value", aHost);
        cookieTooltipDomain.lastChild.setAttribute("value", hostDomain);
        cookieTooltipResult.lastChild.setAttribute("value", aHost);
        
        // Set the icon for the status bar menu
        //this._cookieMonsterButton.setAttribute(this._statusImageAttribute, this.getIcon(hostAccess));
        s1tony.CM.cookieMonsterButton.setIcon(this.getIcon(hostAccess));
    },

    // Swap the menu items in the submenu
    // with those in the main menu,
    // based on the _secondLevel flag
    switchCookieSubMenu: function()
    {
    	if (this._secondLevel)
    	{
    		this.setCookieSubMenu(CM_TOP_LEVEL);
    	}
    	else
    	{
    		this.setCookieSubMenu(CM_SECOND_LEVEL);    		
    	}
    },
    
    // Move cookie setting menu items for aUrlLevel
    // to the submenu and place the cookie setting menu items
    // for the other aUrlLevel in the main menu
    setCookieSubMenu: function(aUrlLevel)
    {
    	var that = this;
    	var cookieMenuItems = new Array(
     			new Array(document.getElementById("cookie-access-top-temp"), document.getElementById("cookie-access-second-temp")),
    			new Array(document.getElementById("cookie-access-top-allow"), document.getElementById("cookie-access-second-allow")),
    		 	new Array(document.getElementById("cookie-access-top-deny"), document.getElementById("cookie-access-second-deny")),
    			new Array(document.getElementById("cookie-access-top-session"), document.getElementById("cookie-access-second-session"))
    			);	
    	var cookieMenuSeparator = document.getElementById("temp-after-this");
        var altAccessMenu = document.getElementById("cookie-access-menu");
        var accessMenuLabel = this._menuBundle.getString("sitemenulabel");
    	var swapCookieMenuItems;
    	
    	// Check current setting to see if
    	// a switch is necessary
    	if (aUrlLevel != this._currentSubMenu)
    	{
    		// Configure how the cookieMenuItems array values
    		// are sent to the replace command
    		if (aUrlLevel == CM_SECOND_LEVEL)
    		{
				// Reverse the array order for each menu item
				for (var i = 0, menuItems; menuItems = cookieMenuItems[i]; i++)
				{
					menuItems.reverse();
				}
				
				// Change the label to (2nd) Domain level
				accessMenuLabel = this._menuBundle.getString("domainmenulabel");
    		}

    		// Replace menu items in sub menu
			swapCookieMenuItems = cookieMenuItems.map(function(menuItem)
			{
				//alert("swapCookieMenuItems: menuItem " + menuItem[0].getAttribute("id"));
				var replaceItem = this._cookieMonsterSubMenu.replaceChild(menuItem[0], menuItem[1]);
				return replaceItem;
			}, that);
			
			// Add replaced menu items to main status bar menu
			for (var i = 0, swapMenuItem; swapMenuItem = swapCookieMenuItems[i]; i++)
			{
				// Place menu item temp after correct menu separator
				if (i == 0)
				{
					this._cookieMonsterMenu.insertBefore(swapMenuItem, cookieMenuSeparator.nextSibling);
				}
				else
				{
					this._cookieMonsterMenu.appendChild(swapMenuItem);					
				}
			}
			
			// Change this._currentSubMenu to aUrllevel
			this._currentSubMenu = aUrlLevel;
			altAccessMenu.setAttribute("label", this._menuBundle.getString("alternatecookieaccess") + " (" + accessMenuLabel + ")");
    	}
    },

    /**
     * Update the sub menu structure for any 3rd Party Cookies,
     * including creating menu items for each one
     * @param {CookieInfo[]} aThirdPartyCookieList
     */
    setThirdPartyCookieSubMenu: function(aThirdPartyCookieList)
    {
    	var that = this;
    	var defaultMenuItem;
    	var tempAllowAllMenuItem;
    	var tempRevokeAllMenuItem;
    	var thirdPartyHosts = new Array();
    	var menu = this._thirdPartyMenuOption;

    	// Remove all menuitems
		if (menu.hasChildNodes())
		{
			while(menu.hasChildNodes())
			{
				menu.removeChild(menu.firstChild);
			}
		}
		
		// If aThirdPartyCookieList contains no cookie info,
		// make the default menu item visible
		// Else Add menu items for each third party cookie and
		// make the default menu item invisible
    	if (aThirdPartyCookieList == null || aThirdPartyCookieList.length == 0)
    	{
		    defaultMenuItem = document.createElement("menuitem");
		    defaultMenuItem.id = "cookie-thirdparty-default-none";
		    defaultMenuItem.setAttribute("label", this._menuBundle.getString("thirdpartynone"));
		    defaultMenuItem.setAttribute("class", "menuitem-iconic");
		    defaultMenuItem.setAttribute("disabled", "true");
		    menu.appendChild(defaultMenuItem);
    	}
    	else
    	{
		    aThirdPartyCookieList.forEach(
			    function(tempCookieItem, index)
			    {
			    	// First construct the menu
			    	var tempMenuItem = document.createElement("menu");
			    	var hostAccess = s1tony.CM.cookieInfo.getPermissionString(tempCookieItem.accessValue);
			    	
			    	tempMenuItem.id = "cookie-thirdparty-" + index;
	        		tempMenuItem.setAttribute("label", this._menuBundle.getString("permissionsresultfor") +
	        						" " + tempCookieItem.host + ":  " + this._menuBundle.getString(hostAccess));
			    	tempMenuItem.setAttribute("image", this.getIcon(hostAccess));
					tempMenuItem.setAttribute("class", "menu-iconic");
					tempMenuItem.addEventListener('command',
						function(event) {that.extThirdPartyMenuSiteHandler(event, tempCookieItem.host)}, false);
					menu.appendChild(tempMenuItem);
					
					// Then create a popup containing all of the cookie access choices
					var tempMenuPopup = tempMenuItem.appendChild(document.createElement("menupopup"));

				    tempMenuPopup.appendChild(this._createThirdPartyMenuItem("default", 0, tempCookieItem));					
				    tempMenuPopup.appendChild(document.createElement("menuseparator"));
				    tempMenuPopup.appendChild(this._createThirdPartyMenuItem("temp", -1, tempCookieItem));
				    tempMenuPopup.appendChild(document.createElement("menuseparator"));
				    tempMenuPopup.appendChild(this._createThirdPartyMenuItem("allow", 1, tempCookieItem));
				    tempMenuPopup.appendChild(this._createThirdPartyMenuItem("deny", 2, tempCookieItem));
				    tempMenuPopup.appendChild(this._createThirdPartyMenuItem("session", 8, tempCookieItem));
				    
				    // Add host to third party host array
				    thirdPartyHosts.push(tempCookieItem.host);
		    	}, this
		    );
		    		    
		    menu.appendChild(document.createElement("menuseparator"));
		    tempAllowAllMenuItem = document.createElement("menuitem");
		    tempAllowAllMenuItem.id = "cookie-thirdparty-tempallow-all";
		    tempAllowAllMenuItem.setAttribute("label", this._menuBundle.getString("thirdpartytempallowall"));
		    tempAllowAllMenuItem.setAttribute("class", "menuitem-iconic");
		    tempAllowAllMenuItem.addEventListener('command',
						function(event) {that.extThirdPartyMenuAllHandler(event, thirdPartyHosts)}, false);
		    menu.appendChild(tempAllowAllMenuItem);

		    tempRevokeAllMenuItem = document.createElement("menuitem");
		    tempRevokeAllMenuItem.id = "cookie-thirdparty-tempallow-revoke";
		    tempRevokeAllMenuItem.setAttribute("label", this._menuBundle.getString("thirdpartytemprevokeall"));
		    tempRevokeAllMenuItem.setAttribute("class", "menuitem-iconic");
		    tempRevokeAllMenuItem.addEventListener('command',
						function(event) {that.extThirdPartyMenuAllHandler(event, thirdPartyHosts, true)}, false);
		    menu.appendChild(tempRevokeAllMenuItem);
	    }	    
    },
    
    /**
     * Create menu item for third party cookie menu
     * @param {String} aType
     * @param {Integer} aMenuItemValue
     * @param {CookieInfo} aCookieItem
     * @return {nsIDOMElement} menu item
     */
    _createThirdPartyMenuItem: function(aType, aMenuItemValue, aCookieItem)
    {
		var cookieMenuItem = document.createElement("menuitem");
		
		cookieMenuItem.id = "cookie-access-third-" + aType;
		cookieMenuItem.value = aMenuItemValue.toString();
		cookieMenuItem.setAttribute("name", "cookie-three");
		cookieMenuItem.setAttribute("label", this._menuBundle.getString(aType) + " " + aCookieItem.host);
		cookieMenuItem.setAttribute("class", "menuitem-iconic");
		
		// Update label if default
		if (aType == "default")
		{
			if (this._currentGlobalPreference[CM_PREF_COOKIE_BEHAVIOR] != CM_PREF_BLOCK_THIRD_PARTY)
			{
				cookieMenuItem.setAttribute("label", this._menuBundle.getString(aType) + " (" + this._userDefault + ")");				
			}
			else
			{
				cookieMenuItem.setAttribute("label", this._menuBundle.getString("thirdpartyblocked"));				
			}
		}
		
		if (aCookieItem.accessValue == aMenuItemValue)
		{
			cookieMenuItem.setAttribute("name", "current-access");		    		
		}
		
		return cookieMenuItem;
    },
    
    setStatusMenuEnabled: function(aEnable)
    {	
        // Set popup attribute to desired status, if necessary
        if (aEnable != this._menuStatus)
        {
            if (aEnable)
            {
                //this._cookieMonsterButton.setAttribute("popup", this._cookieMonsterMenuId);
                s1tony.CM.cookieMonsterButton.setPopup(this._cookieMonsterMenuId);
            }
            else
            {
                // If disable popup, then
                // set the icon for the status bar menu to default
//                this._cookieMonsterButton.setAttribute("popup", "");
//                this._cookieMonsterButton.setAttribute(this._statusImageAttribute, this._iconList[CM_COOKIE_ACCESS_DEFAULT]);
                s1tony.CM.cookieMonsterButton.setPopup("");
                s1tony.CM.cookieMonsterButton.setIcon(this._iconList[CM_COOKIE_ACCESS_DEFAULT]);
        	}

            // Set member variable to track status of the menu
            this._menuStatus = aEnable;
        }
    },

    // Get the appropriate icon for the access type
    // (Replaces _iconList for now, in order to
    // properly handle the Global Override functionality)
    getIcon: function(aAccess)
    {
    	var retValue = this._iconList[aAccess];
 
    	// Check Global Override settings
    	if (this._usingGlobalOverride && this._allowGlobalOverride)
    	{
    		if (aAccess == CM_COOKIE_ACCESS_ALLOW)
    		{
    			retValue = this._iconList[CM_COOKIE_ACCESS_ALLOW_OG];
    		}
    		else if (aAccess == CM_COOKIE_ACCESS_SESSION)
    		{
    			retValue = this._iconList[CM_COOKIE_ACCESS_SESSION_OG];    			
    		}
    	}
    	
    	return retValue;
    },
    
    // External access to current URI
    extGetCurrentURI: function()
    {
    	return this._oldURL;
    },

    // External access to current URI.asciihost,
    // based on domain type
    extGetCurrentHost: function()
    {
    	var currentHost = this._oldURL.asciiHost;
    	
    	if (this._secondLevel)
    	{
    		currentHost = s1tony.CM.cookieInfo.getSecondLevelHost(currentHost);
    	}

    	return currentHost;
    },
    
    // External access to current domain type
    extGetCurrentDomainType: function()
    {
    	var domainType = CM_URL_STANDARD_LEVEL;
    	
    	if (this._secondLevel)
    	{
    		domainType = CM_SECOND_LEVEL;
    	}
    	else
    	{
    		domainType = CM_TOP_LEVEL;    		
    	}
    	
    	return domainType;
    },

    // External access to _allowGlobalOverride
    extGetIsAllowGlobalOverride: function()
    {
    	return this._allowGlobalOverride;
    },
    
    // External access to reloading the current page
    extReloadCurrentPage: function()
    {
    	gBrowser.reload(gBrowser.webNavigation.LOAD_FLAGS_BYPASS_CACHE);
    },

    // Return numeric representation of cookie access level
    // for current URL and domainType
    // If domainType is not passed, then domainType = CM_URL_STANDARD_LEVEL
    // by default
    // If aURI is not passed, then aURI = current URL
    extGetCookieAccess: function()
    {
    	var domainType = CM_URL_STANDARD_LEVEL;
    	var aURI = this._oldURL;
    	
    	if (arguments.length == 1)
    	{
    		domainType = arguments[0];	
    	}
    	else if (arguments.length == 2)
    	{
      		domainType = arguments[0];
      		aURI = arguments[1];
    	}
    	
        var accessLevel = s1tony.CM.cookieInfo.checkPermissionArray(aURI, CM_PERMISSION_TYPE_COOKIE);
        return s1tony.CM.cookieInfo.getPermissionValue(accessLevel[domainType]);
    },
    
    extSetCookieAccess: function(aAccess, domainType)
    {
        //alert("Setting Cookie Status for " + this._oldURL.asciiHost);
        s1tony.CM.cookieInfo.setCookieAccess(this._oldURL, aAccess, domainType);
        this._oldAccess = s1tony.CM.cookieInfo.checkPermissionArray(this._oldURL, CM_PERMISSION_TYPE_COOKIE);
    },

    extResetTempCookies: function(/*, aQuit */)
    {
		var aQuit = false || Boolean(arguments[0]);
    			
 		// Set menu event flag so we don't double trigger a permissions update
        this._flagMenuEvent = true;
        
        s1tony.CM.tempAllow.resetTempCookies();
 
        if (!aQuit)
        {
	        this._oldAccess = s1tony.CM.cookieInfo.checkPermissionArray(this._oldURL, CM_PERMISSION_TYPE_COOKIE);
	    	
	        // Only reload page if reloadOnPermissionChange preference == true
	        if (this._reloadOnPermissionChange)
	        {	
	        	gBrowser.reload(gBrowser.webNavigation.LOAD_FLAGS_BYPASS_CACHE);
	        }
	        
	        this.updateStatusbarMenu(this._oldURL.asciiHost, this._oldAccess);
        }
        
        // Reset menu event flag
        this._flagMenuEvent = false;
    },

    // If current URL is part of override global cookie list,
    // then the global cookie prefs will be changed to match
    // the individual cookie prefs for the URL
    // Else if current URL is NOT part of override global cookie list
    // then the global cookies prefs will be set to the user's current
    // global preferences
    extCheckGlobalCookiePref: function(aURI)
    {
    	var overrideGlobal = null;
    	var currentSiteAccess = CM_CA_LEVEL_DEFAULT;
//    	var domainType = CM_TOP_LEVEL;
//  	
//    	if (this._secondLevel)
//    	{
//    		domainType = CM_SECOND_LEVEL;
//    	}

    	overrideGlobal = s1tony.CM.cookieInfo.checkOverrideGlobal(aURI);

    	// For now, set _usingGlobalOverride if either CM_TOP_LEVEL or
    	// CM_SECOND_LEVEL are set, as the Global Override setting
    	// allows cookies, period, thus paying no attention to the
    	// domain level of the cookie
    	this._usingGlobalOverride = overrideGlobal[CM_TOP_LEVEL] || overrideGlobal[CM_SECOND_LEVEL];
 	
		if (this._usingGlobalOverride && this._allowGlobalOverride)
		{
			// Set _flagGlobalCookieEvent so _currentGlobalPreferences
			// are not changed during a global override
			this._flagGlobalCookieEvent = true;

			// Check for the resulting current site access (CM_URL_STANDARD_LEVEL)
			// to coincide with the preface of setting global override
			// if either CM_TOP_LEVEL or CM_SECOND_LEVEL are set
			currentSiteAccess = this.extGetCookieAccess(CM_URL_STANDARD_LEVEL, aURI);
			//alert("Current URL Access: " + currentSiteAccess);
			
			if (currentSiteAccess == Components.interfaces.nsIPermissionManager.ALLOW_ACTION)
			{
				s1tony.CM.prefObserver.setCookiePref(new Array(0, 0));
			}
			else if (currentSiteAccess == Components.interfaces.nsICookiePermission.ACCESS_SESSION)
			{
				s1tony.CM.prefObserver.setCookiePref(new Array(0, 2));				
			}
			else
			{
				this.extResetGlobalCookiePref();	
			}
			
			// Reset flag
			this._flagGlobalCookieEvent = false;
		}
		else
		{
			this.extResetGlobalCookiePref();				
		}
    },
    
    // Either add or remove current URL from override global list
    extSetGlobalCookiePref: function()
    {
    	//var aSet = this._usingGlobalOverride;
    	var domainType = CM_TOP_LEVEL;
    	
    	if (this._secondLevel)
    	{
    		domainType = CM_SECOND_LEVEL;
    	}
    	//alert("Setting Global Cookie Status for " + this._oldURL.asciiHost);

    	if (this._usingGlobalOverride)
    	{
        	s1tony.CM.cookieInfo.addOverrideGlobal(this._oldURL.asciiHost, domainType);
    	}
    	else
    	{
    		s1tony.CM.cookieInfo.removeOverrideGlobal(this._oldURL.asciiHost, domainType);	
    	}
    },
    
    extResetGlobalCookiePref: function()
    {
    	// Have the global permissions been changed
    	var curGlobalCookie = s1tony.CM.prefObserver.getCookiePrefArray();
    	
    	//alert("curGlobalCookie: " + curGlobalCookie + "  defaultGlobPref: " + this._currentGlobalPreference);
    	if ((curGlobalCookie[CM_PREF_COOKIE_BEHAVIOR] != this._currentGlobalPreference[CM_PREF_COOKIE_BEHAVIOR]) ||
    		(curGlobalCookie[CM_PREF_LIFETIME_POLICY] != this._currentGlobalPreference[CM_PREF_LIFETIME_POLICY]))
		{
			s1tony.CM.prefObserver.setCookiePref(this._currentGlobalPreference);
		}
    },
    
    // Process the commands pertaining
    // to the menu choices made by the user
    extMenuCommandHandler:  function(evt)
    {
        var checkExpCookie = /^cookie-access/i;
        var checkExpOptions = /^option-/i;
        var itemPicked = null;
        var accessString = null;
        var accessValue = null;

        var itemPicked = document.getElementById(evt.target.id);
        //alert("Menu Command  Event Id:  " + evt.target.id + "  CM_TOP_LEVEL:  " + this._oldAccess[CM_TOP_LEVEL]);
         		
 		// Set menu event flag so we don't double trigger a permissions update
        this._flagMenuEvent = true;
            	
        // If id contains cookie-access and name = cookie, then assign new
        // cookie access and reload page
        if (checkExpCookie.test(evt.target.id))
        {
            if (itemPicked.getAttribute("name") == "cookie-top")
            {
                this.extSetCookieAccess(evt.target.value, CM_TOP_LEVEL);
            }
            else if(itemPicked.getAttribute("name") == "cookie-two")
            {
                this.extSetCookieAccess(evt.target.value, CM_SECOND_LEVEL);
            }
            else if(itemPicked.getAttribute("name") == "cookie-access")
            {
            	if (this._secondLevel)
            	{
                	this.extSetCookieAccess(evt.target.value, CM_SECOND_LEVEL);
            	}
            	else
            	{
                	this.extSetCookieAccess(evt.target.value, CM_TOP_LEVEL);            		
            	}
            }
            else if(itemPicked.getAttribute("name") == "cookie-default")
            {
                this.extSetCookieAccess(evt.target.value, CM_TOP_LEVEL);
            	this.extSetCookieAccess(evt.target.value, CM_SECOND_LEVEL);
            }
            
            // Only reload page if reloadOnPermissionChange preference == true
            if (this._reloadOnPermissionChange)
            {	
            	gBrowser.reload(gBrowser.webNavigation.LOAD_FLAGS_BYPASS_CACHE);
            }
            
            //accessString = cookieMonster_CookieInfo.getPermissionString(evt.target.value);
            this.updateStatusbarMenu(this._oldURL.asciiHost, this._oldAccess);
        }
        else if (checkExpOptions.test(evt.target.id))
        {
	        // If id=second-level, then determine
	        // if it is checked and set variable and
	        // user preference cookiemonster.secondlevelurl and
	        // call switchCookieSubMenu to check if the cookie
	        // submenu needs to be switched
        	// Else if id = this._globalOverrideId, then
        	// update user cookie preferences
        	if ((evt.target.id == this._secondLevelId) &&
	        		 (this._secondLevel != itemPicked.getAttribute("checked")))
	        {
	            this._secondLevel = itemPicked.getAttribute("checked");        		
	            s1tony.CM.nsPreferences.setBoolPref("secondlevelurl", this._secondLevel);    
	        }
/*	        else if((evt.target.id == this._globalOverrideId) &&
	        		 (this._usingGlobalOverride != itemPicked.getAttribute("checked")))
    		{
	        	itemPicked.setAttribute("checked", this._usingGlobalOverride);
	        	//this.extSetGlobalCookiePref();
            	//this._browser.reload(this._browser.webNavigation.LOAD_FLAGS_BYPASS_CACHE);
	        	//alert("Global Override Option: " + this._usingGlobalOverride);
    		} */
    	}
 
        // Reset menu event flag
        this._flagMenuEvent = false;
        
        return false;
    },
 
    /**
     * Handle the command event for loading the third party menu
     * @param {Event} evt
     */
    extThirdPartyMenuLoadHandler: function(evt)
    {
		var cookieRequestData = s1tony.CM.cookieRequest.getRequestList(this._oldURL.asciiHost);
		this.setThirdPartyCookieSubMenu(cookieRequestData);	
		//alert("length:  " + cookieRequestData.length);
    	evt.stopPropagation();
    },
    
    /**
     * Handle the command event for the third party menu items
     * @param {Event} evt
     * @param {String} aHost
     */
    extThirdPartyMenuSiteHandler: function(evt, aHost)
    {
    	var hostURI = s1tony.CM.utils.createURIFromHostName(aHost);
    	s1tony.CM.cookieInfo.setCookieAccess(hostURI, evt.target.value, CM_TOP_LEVEL);  
    	
    	if (!this._reloadOnPermissionChange)
    	{
    		s1tony.CM.cookieRequest.updateCookieRequest(aHost, this._oldURL.asciiHost);
    	}
		    	
    	evt.stopPropagation();
    },
    
    /**
     * Handle the command event for the third party menu items
     * of temp allow all or temp allow revoke
     * @param {Event} evt
     * @param {String[]} aHosts
     * @optional {Boolean} aRevoke
     */
    extThirdPartyMenuAllHandler: function(evt, aHosts /*, aRevoke */)
    {
		var aRevoke = false || Boolean(arguments[2]);
    			
	    aHosts.forEach(
		    function(host, index)
		    {
		    	if (!aRevoke)
		    	{	    		
		    		var hostURI = s1tony.CM.utils.createURIFromHostName(host);
		    		s1tony.CM.cookieInfo.setCookieAccess(hostURI, -1, CM_TOP_LEVEL);
		    	}
		    	else
		    	{
		    		s1tony.CM.tempAllow.resetTempCookie(host);
		    	}
		    	
		    	if (!this._reloadOnPermissionChange)
		    	{
		    		s1tony.CM.cookieRequest.updateCookieRequest(host, this._oldURL.asciiHost);
		    	}
	    	}, this
    	);
		
        // Only reload page if reloadOnPermissionChange preference == true
        if (this._reloadOnPermissionChange)
        {	
        	gBrowser.reload(gBrowser.webNavigation.LOAD_FLAGS_BYPASS_CACHE);
        }
	
    	evt.stopPropagation();
    },
    
    extSetSiteRequestedSetCookie: function(evt)
    {
        var cookieTooltipAttempt = document.getElementById("cookie-group-attempt");
        var attemptDisplay = null;

	    // Set the tool tip text indicating if the site has requested
	    // to leave cookies
        if (s1tony.CM.cookieRequest.hasMadeCookieRequest(this._oldURL.asciiHost))
        {
        	attemptDisplay = this._menuBundle.getString("siteattemptedcookie");
        }
        else
        {
         	attemptDisplay = this._menuBundle.getString("sitenotattemptedcookie");      	
        }
        
        cookieTooltipAttempt.lastChild.setAttribute("value", attemptDisplay);
        
    	evt.stopPropagation();
    },

    // Set values based on preferences
    extUpdateFromPreferences: function(aPref)
    {
        var globalOverridePref = null;
        
        if (aPref == "secondlevelurl")
        {
            this._secondLevel = s1tony.CM.nsPreferences.getBoolPref("secondlevelurl", false);

            if (this._secondLevel)
            {
                this._secondLevelMenuOption.setAttribute("checked", "true");
            }
            else
            {
            	this._secondLevelMenuOption.setAttribute("checked", "false");
            }

            this.updateStatusbarMenu(this._oldURL.asciiHost, this._oldAccess);
			this.switchCookieSubMenu();
        }
        else if (aPref == "enableglobalcookieoverride")
        {
	        // Retrieve the new value for enableglobalcookieoverride
        	globalOverridePref = s1tony.CM.nsPreferences.getBoolPref("enableglobalcookieoverride", false);

        	// If enableglobalcookieoverride has changed then assign
        	// the updated value, update the menu, reset global cookie
        	// prefs if _allowGlobalOverride is false, and reload page
        	// if the current URI is using global override 
	        if (this._allowGlobalOverride != globalOverridePref)
	        {
		        this._allowGlobalOverride = globalOverridePref;
				this._globalOverrideMenuOption.setAttribute("disabled", !this._allowGlobalOverride);

		        if (!this._allowGlobalOverride)
		        {
		        	this.extResetGlobalCookiePref();	
		        }
		        
		        if (this._usingGlobalOverride)
		        {
		        	gBrowser.reload(gBrowser.webNavigation.LOAD_FLAGS_BYPASS_CACHE);
		        }
	        }
        }
        else if (aPref == "enablekeyboardshortcut")
        {
        	document.getElementById("cookiemonster-key").setAttribute("disabled", !s1tony.CM.nsPreferences.getBoolPref("enablekeyboardshortcut", true));
        }
        else if (aPref == "originaldefaulticon")
        {
	        // Determine what default icon to use
	        if (!s1tony.CM.nsPreferences.getBoolPref("originaldefaulticon", false))
	        {
	        	this._iconList[CM_COOKIE_ACCESS_DEFAULT] = CM_ICON_DEFAULT;       	
	        }
	        else
	        {
	        	this._iconList[CM_COOKIE_ACCESS_DEFAULT] = CM_ICON_DEFAULT_ORIGINAL;        	
	        }        	

	        this.updateStatusbarMenu(this._oldURL.asciiHost, this._oldAccess);           
	    }
	    else if (aPref == "reloadonpermissionchange")
	    {
        	this._reloadOnPermissionChange = s1tony.CM.nsPreferences.getBoolPref("reloadonpermissionchange", false);	    	
	    }
        else if ((aPref == "cookieBehavior") || (aPref == "lifetimePolicy"))
        {
            // Retrieve users's updated default cookie permissions and
            // update Statusbar menu
            this._userDefault = s1tony.CM.prefObserver.getCookiePrefString();
            
            if (!this._flagGlobalCookieEvent)
            {
				this._currentGlobalPreference = s1tony.CM.prefObserver.getCookiePrefArray();
            }
            
            this.updateStatusbarMenu(this._oldURL.asciiHost, this._oldAccess);
        }
    },

    // Set values based on permissions
    extUpdateFromPermissions: function(aHost)
    {
        var currentURL = this._oldURL.host;
    	
        // If the user has selected 2nd Level domains, then compare as such
        if (this._secondLevel)
        {
            currentURL = s1tony.CM.cookieInfo.getSecondLevelHost(this._oldURL.host);
        }
 
        // Retrieve new cookies permission for current URL, reload page and
        // update status bar      
        if ((aHost == currentURL) && !this._flagMenuEvent)
        {
        	//alert("Permission Event and Not Menu Event: " + this._oldAccess);
            this._oldAccess = s1tony.CM.cookieInfo.checkPermissionArray(this._oldURL, CM_PERMISSION_TYPE_COOKIE);
        	
            // Only reload page if reloadOnPermissionChange preference == true
            if (this._reloadOnPermissionChange)
            {	
            	gBrowser.reload(gBrowser.webNavigation.LOAD_FLAGS_BYPASS_CACHE);
            }
            
            this.updateStatusbarMenu(this._oldURL.asciiHost, this._oldAccess);
        }
    }
};

// Edit: for me on Firefox 2.0, I had to change "document" to "window"
// for the following lines to work
window.addEventListener("load", function() {s1tony.CM.cookieMonster.init()},
false);
window.addEventListener("unload", function() {s1tony.CM.cookieMonster.uninit()},
false);
