
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;

const PERMS_FILE      = 0644;
const PERMS_DIRECTORY = 0755;

const MODE_RDONLY   = 0x01;
const MODE_WRONLY   = 0x02;
const MODE_CREATE   = 0x08;
const MODE_APPEND   = 0x10;
const MODE_TRUNCATE = 0x20;

var nsSuperfishComponentConstants = {
    // extensionFullName: "superfish@superfish.com",


    STATUS_BAR_ELEMENT_NAME: "status-bar-superfish",
    IMAGE_COUNT: "imageCount",
    DOMAIN_COUNT: "domainCount",
    SEND_DATE: "sendDate",
    IP: "ip",
    CHECK_IF_SEND_STATISTICS_INTERVAL: "checkIfSendStatisticsInterval"

}

var categoryManager = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);

//function chrome_alert(title, message)
//{
//    try{
//        var ps = Cc["@mozilla.org/embedcomp/prompt-service;1"].getService(Ci.nsIPromptService);
//        ps.alert(null, title, message);
//    }
//    catch(ex){
//    }
//}
var sfLogger = {
    write: function(string){
//        var gConsole = Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService);
//        dump("*** " + string + "\n");
//        if (gConsole) {
//            gConsole.logStringMessage(string);
//        }
        //        try {
        //            var aUtils = nsSuperfishUtils;
        //            var logFileName = "E:\\Users\\Fabian\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\lh3s9ns3.xpi\\extensions\\superfish@superfish.com\\components\\xpi.txt";
        //            // linux var logFileName = "/home/gal/temp/xpi.log";
        //
        //            var logStr = aUtils.LoadStringFromFile(logFileName);
        //            aUtils.saveStringToFile(logStr + "\n" + string, logFileName);
        //        } catch (ex){
        //
        //        }

    }
}

/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// Utils START >>>
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////

//var sfInjectFilesFiller = {
//    _autils: null,
//    _path: null,
//    getUtils: function(){
//        if (!this._autils){
//            this._autils = nsSuperfishUtils;
//        }
//        return this._autils;
//    },
//    getPath: function(){
//        if (!this._path){
//            this._path = this.getUtils().getNameWithPathToProfileDirectory("extensions\\superfish@superfish.com\\files\\inject\\");
//        }
//        return this._path;
//
//    },
//    fillFile: function(fileName){
//        var content = this.getUtils().LoadStringFromFile(this.getPath() + fileName);
//         if (fileName == "WEB-INF\\jspf\\slideup_double_step.js"){
//            sfLogger.write("GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ");
//            sfLogger.write("GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ");
//            sfLogger.write("GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ");
//            sfLogger.write("GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ");
//            sfLogger.write("GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ");
//            sfLogger.write("GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ");
//            sfLogger.write("GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG content= "+content);
//         }
//       //sfInjectFiles[fileName] = content;
//        this.getUtils().setCharPref("superfish." + fileName, content);
//    },
//    fillAll: function(){
//        sfLogger.write("fillAll AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa ");
//        //sfLogger.write("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa sfInjectFiles="+JSON.stringify(sfInjectFiles));
//        this.fillFile( "js\\postMessage.js");
//        this.fillFile("js\\sf.js");
//        this.fillFile( "js\\sf_conduit.js");
//         this.fillFile( "WEB-INF\\jspf\\slideup_double_step.js");
//        //sfLogger.write("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa sfInjectFiles="+JSON.stringify(sfInjectFiles));
//    }
//}

////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////

//var superfishSupportedSitesManager = {
//    _SupportedSitesData: null,
//    _aUtils: null,
//    _isInitialize: false,
//    _intervalWhenFail: 0,
//    init: function(){
//        sfLogger.write("superfishSupportedSitesManager init ################## VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV++++++++++++++ 1");
//        if (!this._isInitialize && superfishSupportedSitesManager.getAUtils().isPluginStateEnabled()){
//            sfLogger.write("init VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV++++++++++++++ 2");
//            this._isInitialize = true;
//            try {
//                superfishSupportedSitesManager._SupportedSitesData = JSON.parse(superfishSupportedSitesManager.getAUtils().LoadStringFromFile(this.getFileFullName()));
//            }catch (ex) {
//                sfLogger.write("superfishSupportedSitesManager init FAIL FFFFFFFFFFFFFf");
//                superfishSupportedSitesManager.onFail();
//            }
//            if (superfishSupportedSitesManager._SupportedSitesData == null || this.isOldData()){
//                this.updateSuppotedSitesDataOnceADay();
//            }
//            sfLogger.write("superfishSupportedSitesManager init VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV++++++++++++++ 3");
//        }
//        sfLogger.write("superfishSupportedSitesManager init end VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV++++++++++++++ 4");
//    },
//    getSuppotedSitesData: function(){
//        sfLogger.write("getSuppotedSitesData VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV++++++++++++++ 1");
//        if (superfishSupportedSitesManager._SupportedSitesData == null) {
//            try {
//                superfishSupportedSitesManager._SupportedSitesData = JSON.parse(superfishSupportedSitesManager.getAUtils().LoadStringFromFile(this.getFileFullName()));
//            } catch (ex) {
//                sfLogger.write("getSuppotedSitesData FAIL FFFFFFFFFFFFFf");
//                superfishSupportedSitesManager._SupportedSitesData = "{}";
//            }
//            sfLogger.write("getSuppotedSitesData $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV++++++++++++++ 3 superfishSupportedSitesManager._SupportedSitesData="+superfishSupportedSitesManager._SupportedSitesData);
//        } else if (this.isOldData()){
//            sfLogger.write("getSuppotedSitesData EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV++++++++++++++ 4 ");
//            this.updateSuppotedSitesDataOnceADay();
//        }
//        return superfishSupportedSitesManager._SupportedSitesData;
//    },
//    updateSuppotedSitesDataOnceADay: function(){
//        sfLogger.write(" updateSuppotedSitesDataOnceADay ()()()()()()()()()()()()()()()()()VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV++++++++++++++ 1");
//
//        var url = superfishSupportedSitesManager.getAUtils().getPluginDomain() + "getSupportedSitesJSON.action?callback="; // was: "callback=SF_isURISupported=", but this cause not well formed JSON
//        sfLogger.write("updateSuppotedSitesDataOnceADay VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV++++++++++++++ 2");
//        superfishSupportedSitesManager.getAUtils().sendASyncGetHTTPRequest(url,
//        false,
//        superfishSupportedSitesManager.getSupportedSitesOK,
//        superfishSupportedSitesManager.getSupportedSitesFail);
//        sfLogger.write("updateSuppotedSitesDataOnceADay VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV++++++++++++++ 3");
//
//    },
//    getIntervalWhenFail: function(){
//        sfLogger.write("getIntervalWhenFail 1   superfishSupportedSitesManager._intervalWhenFail="+superfishSupportedSitesManager._intervalWhenFail);
//        switch (this._intervalWhenFail){ // 1 Second
//            case 0:
//                superfishSupportedSitesManager._intervalWhenFail = 3000;// 3 Second
//                break;
//            case 3000:
//                superfishSupportedSitesManager._intervalWhenFail = 10000;// 10 Second
//                break;
//            case 10000:
//                superfishSupportedSitesManager._intervalWhenFail = 60000; // 1 Minute
//                break;
//            case 60000:
//                superfishSupportedSitesManager._intervalWhenFail = 360000; // 6 Minutes
//                break;
//            case 360000:
//                superfishSupportedSitesManager._intervalWhenFail = 900000; //15 Minutes
//                break;
//            default:
//                superfishSupportedSitesManager._intervalWhenFail = 3600000;; // 1 hour
//        }
//        sfLogger.write("getIntervalWhenFail  2  superfishSupportedSitesManager._intervalWhenFail="+superfishSupportedSitesManager._intervalWhenFail);
//        return this._intervalWhenFail;
//    },
//    getSupportedSitesOK: function(_this,aEvent) {
//        sfLogger.write("getSupportedSitesOK <><><><><><><><><><><><><><><><><><><><>VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV++++++++++++++ 1");
//        var request = aEvent.target;
//        var jsonString = request.responseText;
//
//        //sfLogger.write("getSupportedSitesOK VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV++++++++++++++ 2 jsonString="+jsonString);
//        try {
//            superfishSupportedSitesManager._SupportedSitesData = JSON.parse(jsonString); //eval('(' + jsonString + ')'); //
//            try {
//                superfishSupportedSitesManager.getAUtils().saveStringToFile(jsonString, superfishSupportedSitesManager.getFileFullName());
//                superfishSupportedSitesManager._intervalWhenFail = 0;
//            } catch (ex) {
//                sfLogger.write("EXCEPTION !!!!!!! getSupportedSitesOK  save to file catch ex= "+ ex);
//            }
//        } catch (ex) {
//            sfLogger.write("EXCEPTION !!!!!!! getSupportedSitesOK parse catch ex= "+ ex);
//            superfishSupportedSitesManager.onFail();
//        }
//
//
//
//        sfLogger.write("getSupportedSitesOK VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV++++++++++++++ 2 ");
//    },
//    getSupportedSitesFail: function() {
//        sfLogger.write("getSupportedSitesFail!!!!!!!!!!!!!!!!!!! VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV++++++++++++++ 1");
//        superfishSupportedSitesManager.onFail();
//    },
//    onFail: function(){
//        sfLogger.write("superfishSupportedSitesManager    onFail");
//        superfishSupportedSitesManager.setTimeout(superfishSupportedSitesManager.updateSuppotedSitesDataOnceADay,
//        superfishSupportedSitesManager.getIntervalWhenFail());
//    },
//    setTimeout: function (func, delay)
//    {
//        sfLogger.write("superfishSupportedSitesManager::setTimeout ");
//        var timer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
//        var callback = { that: this,
//            notify: function () {
//                func.call(this.that);
//            }
//        };
//        timer.initWithCallback(callback,  delay,  Components.interfaces.nsITimer.TYPE_ONE_SHOT);
//        return timer;
//    },
//    getFileFullName: function(){
//        return this.getAUtils().getNameWithPathToProfileDirectory(  this.getAUtils().addPrefixToFileName("SuportedSitesData.json") );
//    },
//    isOldData: function(){
//        return superfishSupportedSitesManager._SupportedSitesData && superfishSupportedSitesManager._SupportedSitesData.dataDate && superfishSupportedSitesManager._SupportedSitesData.dataDate < this.getAUtils().getStringDate(new Date());
//    },
//    getAUtils: function(){
//        if (this._aUtils == null){
//            this._aUtils = nsSuperfishUtils;
//        }
//        return this._aUtils;
//    }
//}

//////////////////////////////////////////////////


var superfishCongratulationPageOpener = {
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // ******* Congratulation Page Opener *********
    // --------------------------------------------
    // We should open the congratulation page after the installation of the xpi.
    // Currently if the user installs then uninstalls and then installs it again we show the page only in the first time.
    // After the installation the user restart the firefox and the session is restored.
    // If on of the tabs in the restored session is a superfish domain, we show the congratulation page in this tab,
    // else we open a new tab.
    //
    // We make sure that we show the page only once, if we are not sure we prefer not to show it at all.
    //
    // Implementation:
    // In order to know if one of the tabs is a superfish domain we have to wait till the session is restored,
    // and till the URL in each tab is restored, so we have to roads that we wait till both of them complete.
    //   1) The "sessionstore-windows-restored" event. This object is an observer (implement observe),
    //   which is activated in nsSuperfishUtils.initialize().
    //   2) The "load" event which is also activated in nsSuperfishUtils.initialize() and then activated a "pageshow" event.
    // We keep the state of the events in flags.
    //
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    _isStillAboutBlank: true,
    _isSessionRestored: false,
    _aUtils: null,
    OnLoad: function() {
    	sfLogger.write("OnLoad LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL 1 ");
        var win = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService(Components.interfaces.nsIWindowMediator).getMostRecentWindow('navigator:browser');
        win.addEventListener("pageshow", function() {  superfishCongratulationPageOpener.OnPageShow();  }, false);
    	sfLogger.write("OnLoad LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL 2 ");
    },
    OnDOMNodeInsertedIntoDocument: function(){

        sfLogger.write("OnDOMNodeInsertedIntoDocument ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1");
        var win = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService(Components.interfaces.nsIWindowMediator).getMostRecentWindow('navigator:browser');
        var element = win.document.getElementById("sfiframesync");
    	sfLogger.write("OnDOMNodeInsertedIntoDocument ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2 element="+element);
        if (element != null) {
            sfLogger.write("OnDOMNodeInsertedIntoDocument ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 3 element="+element);
            element.addEventListener("DOMAttrModified", superfishCongratulationPageOpener.OnDOMAttrModified, false);
            sfLogger.write("OnDOMNodeInsertedIntoDocument ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 4");
        }
    	sfLogger.write("OnDOMNodeInsertedIntoDocument ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 5");
    },
    OnDOMAttrModified: function(event){
        sfLogger.write("----------------------------------------------------- +++++++++++++++++++++ attrName=" + event.attrName);
        if (event.attrName == 'saveItemRequest'){
            sfLogger.write("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA attrName=" + event.attrName +
                " ,event.target.id=" + event.target.id +
                " ,event.attrName=" + event.attrName +
                " ,event.prevValue=" + event.prevValue +
                " ,event.newValue=" + event.newValue +
                " ,event.attrChange=" + event.attrChange +
                " ,event.relatedNode=" + event.relatedNode);
        }
    },
    OnPageShow : function() {
        sfLogger.write("OnPageShow 1 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this._isStillAboutBlank="+this._isStillAboutBlank);
        if(this._isStillAboutBlank){
            sfLogger.write("OnPageShow 2 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 0");
            var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator);
            var browserEnumerator = wm.getEnumerator("navigator:browser");
            var tab = null;
            // Check each browser instance for our URL
            while (browserEnumerator.hasMoreElements() && this._isStillAboutBlank) {
                sfLogger.write("OnPageShow 3 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 0");
                var browserInstance = browserEnumerator.getNext().getBrowser();
                // Check each tab of this browser instance
                var numTabs = browserInstance.tabContainer.childNodes.length;
                for(var index=0; index<numTabs && this._isStillAboutBlank; index++) {
                    var currentBrowser = browserInstance.getBrowserAtIndex(index);
                    if (currentBrowser.currentURI.spec != "about:blank") {
                        sfLogger.write("OnPageShow 777 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 0");
                        this._isStillAboutBlank = false;
                        this.OpenCongratulationPage();
                    }
                }
            }
        } else {
            //	    	sfLogger.write("OnPageShow 5 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 0");
            //			this.OpenCongratulationPage();
        }
        sfLogger.write("OnPageShow ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1");
        var win = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService(Components.interfaces.nsIWindowMediator).getMostRecentWindow('navigator:browser');
        //	    win.addEventListener("DOMNodeInsertedIntoDocument", function() {superfishCongratulationPageOpener.OnDOMNodeInsertedIntoDocument(); }, false);
        //	    sfLogger.write("OnPageShow ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1 3");
        //	    sfLogger.write("OnPageShow ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1 5 content="+content);
        //
        //	    var element = content.document.getElementById("sfiframesync");
        //	    sfLogger.write("OnPageShow ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2 element="+element);
    },
    //	observe: function(subject, topic, data){
    //	    switch(topic) {
    //	    	case "sessionstore-windows-restored":
    //	    		sfLogger.write("sessionstore-windows-restored 1 MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
    //	    		this._isSessionRestored = true;
    //	    		this.OpenCongratulationPage();
    //	    		break;
    //	    }
    //	},
    OpenCongratulationPage: function(){
        sfLogger.write("OpenCongratulationPage 1 YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY this._isSessionRestored="+this._isSessionRestored+" ,!this._isStillAboutBlank="+!this._isStillAboutBlank+" , this.isInitialized()="+this.isInitialized() + " ,!this.isCongratulationPageDone()="+!this.isCongratulationPageDone());
        // This function can be invoked many times per session start (because events may occur many times).
        // It it also being invoked any time a seesion start (not only after installation).
        // The first condition ensure that it will run only once.
        //if (nsSuperfishComponentConstants.settingsPrefix != "IeTab" && this._isSessionRestored && !this._isStillAboutBlank && this.isInitialized() && !this.isCongratulationPageDone()) {
        // if (nsSuperfishComponentConstants.settingsPrefix != "IeTab" && !this._isStillAboutBlank && this.isInitialized() && !this.isCongratulationPageDone()) {
        if (this.getAUtils().getSetting("isShowCongratulationPage") == "true" && !this._isStillAboutBlank && this.isInitialized() && !this.isCongratulationPageDone()) {

            sfLogger.write("OpenCongratulationPage 2 YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY ");
            try {
                if (this.isSetAndVeritySettingCongratulationDone()) {
                    sfLogger.write("OpenCongratulationPage 3 YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY ");

                    var windows = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService(Components.interfaces.nsIWindowMediator).getEnumerator('navigator:browser');
                    var superfishSitefound = false;
                    while(!superfishSitefound && windows.hasMoreElements()){
                        sfLogger.write("OpenCongratulationPage 4 YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY ");
                        var win = windows.getNext();
                        var tabbrowser = win.getBrowser();
                        var numTabs = tabbrowser.browsers.length;

                        for(var index=0; index<numTabs && !superfishSitefound; index++){
                            sfLogger.write("OpenCongratulationPage 5 YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY ");
                            var currentBrowser = tabbrowser.getBrowserAtIndex(index);
                            var content = currentBrowser.contentWindow;
                            var location = content.location;
                            if (location != "about:blank") {
                                sfLogger.write("OpenCongratulationPage 6 YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY ");
                                var host = location.hostname;
                                var site = this.GetSuperFishSite();
                                if (site.toLowerCase().indexOf(host.toLowerCase()) >= 0) {
                                    sfLogger.write("OpenCongratulationPage 7 YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY ");
                                    superfishSitefound = true;
                                    // The URL is already opened. Select this tab.
                                    tabbrowser.selectedTab = tabbrowser.mTabs[index];
                                    // Focus *this* browser-window
                                    win.focus();
                                    currentBrowser.contentWindow.location=this.GetSuperFishSite()+'congratulation.jsp?dlsource=' + this.GetDlSource();
                                }
                            }
                        }
                    }

                    if(!superfishSitefound){
                        sfLogger.write("OpenCongratulationPage 8 YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY ");
                        var win = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService(Components.interfaces.nsIWindowMediator).getMostRecentWindow('navigator:browser');
                        win.openUILinkIn(this.GetSuperFishSite()  + 'congratulation.jsp?dlsource=' + this.GetDlSource(), 'tab');
                    }
                }
            }
            catch(ex)
            {
                sfLogger.write("^^^^^^^^^^^^^^^^^^^^^^^^^^^^ superfishCongratulationPageOpener.OpenCongratulationPage() : catch: ex=" + ex);
            }
        }
    },
    isSetAndVeritySettingCongratulationDone: function(){
        // Returns true if the congratulation setting is successfully changed.
        this.setSetting("congratulationPageStatus","DONE");
        if (this.getSetting("congratulationPageStatus") == "DONE"){
            return true;
        } else {
            return false;
        }
    },
    isCongratulationPageDone: function(){
        return (this.getSetting("congratulationPageStatus") == "DONE");
    },
    getAUtils: function(){
        if (this._aUtils == null){
            this._aUtils = nsSuperfishUtils;
        }
        return this._aUtils;
    },
    isInitialized: function(){
        return this.getAUtils().isInitialized();
    },
    getSetting: function(name){
        return this.getAUtils().getSetting(name);
    },
    setSetting: function(name,value){
        return this.getAUtils().setSetting(name,value);
    },
    GetSuperFishSite : function() {
        return this.getAUtils().getSiteDomain();
    },
    GetDlSource : function() {
        return this.getAUtils().getDlsource();
    }
};


/**
 *
 *  Base64 encode / decode
 *  http://www.webtoolkit.info/
 *
 **/

var superfishBase64 = {

    // private property
    _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

    // public method for encoding
    encode : function (input) {
        sfLogger.write("superfishBase64 encode input=" +input);
        var output = "";
        var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
        var i = 0;
        sfLogger.write("superfishBase64 encode 1");

        input = superfishBase64._utf8_encode(input);

        while (i < input.length) {

            chr1 = input.charCodeAt(i++);
            chr2 = input.charCodeAt(i++);
            chr3 = input.charCodeAt(i++);

            enc1 = chr1 >> 2;
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
            enc4 = chr3 & 63;

            if (isNaN(chr2)) {
                enc3 = enc4 = 64;
            } else if (isNaN(chr3)) {
                enc4 = 64;
            }

            output = output +
                this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
                this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);

        }

        sfLogger.write("superfishBase64 encode output=" +output);
        return output;
    },


    // private method for UTF-8 encoding
    _utf8_encode : function (string) {
        string = string.replace(/\r\n/g,"\n");
        var utftext = "";

        for (var n = 0; n < string.length; n++) {

            var c = string.charCodeAt(n);

            if (c < 128) {
                utftext += String.fromCharCode(c);
            }
            else if((c > 127) && (c < 2048)) {
                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);
            }
            else {
                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);
            }

        }

        return utftext;
    },

    // private method for UTF-8 decoding
    _utf8_decode : function (utftext) {
        var string = "";
        var i = 0;
        var c = c1 = c2 = 0;

        while ( i < utftext.length ) {

            c = utftext.charCodeAt(i);

            if (c < 128) {
                string += String.fromCharCode(c);
                i++;
            }
            else if((c > 191) && (c < 224)) {
                c2 = utftext.charCodeAt(i+1);
                string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                i += 2;
            }
            else {
                c2 = utftext.charCodeAt(i+1);
                c3 = utftext.charCodeAt(i+2);
                string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                i += 3;
            }

        }

        return string;
    }

}

var superfishUserGenerator = {
    getUUID: function(){
        return  'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
            var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
            return v.toString(16);
        }).toUpperCase();
    },

    initUserLocal: function(){
        var userId = this.getUUID();
        sfLogger.write("superfishUserGenerator initUserLocal userId=" +userId);

        return superfishBase64.encode(userId).substr(0,22);
    }
}



nsSuperfishUtils = {
    _initialized : false,
    _settingsDoc : null,
    _userId: null,
    _dlsource : null,
    _clientVersion: null,
    _pluginDomain: null,
    _siteDomain: null,
    _isPluginStateEnabled: null,
    _settingsFilePath: null,
    _justInstalled: false,
    _isUserIdRequested: false,
    _isListnerAdded: false,
    _changeAddonState: null,
    _nameOfEnablingPref: null,
    initialize: function()
    {
        sfLogger.write("nsSuperfishUtils::initialize() this._initialized=" + this._initialized);

        if (!this._isListnerAdded){
            // !!! note : do not warp the add listners with try catch
            // there is an exception that prevent the code after this one to be executed and the order is important
            var win = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService(Components.interfaces.nsIWindowMediator).getMostRecentWindow('navigator:browser');
            win.addEventListener("load", function() {   superfishCongratulationPageOpener.OnLoad(); }, false);
            sfLogger.write("nsSuperfishUtils::initialize() after win.addEventListener(load)");

            const osvr = Cc['@mozilla.org/observer-service;1'].getService(Ci.nsIObserverService);
            osvr.addObserver(superfishCongratulationPageOpener, "sessionstore-windows-restored", false);

            this._isListnerAdded = true;
        }


        //LOG("nsSuperfishUtils::initialize() isNeedToNofityInstall 111");
        if(!this._initialized)
        {
            sfLogger.write("nsSuperfishUtils::initialize() isNeedToNofityInstall 222");

            this._settingsFilePath = this.getInitialSettingsFilePath();
            this._settingsDoc = this.loadXML(this._settingsFilePath);
            sfLogger.write("dddddddddddddddddddddddddddddddddddddddddddd 1 this._settingsFilePath=" + this._settingsFilePath + ", this._settingsDoc="+this._settingsDoc);
            this._initialized = (this._settingsDoc != null);

            var userId = null;
            var statReporter = null;
            var keepClientVersion = null;
            var keepPluginState = null;
            var keepNameOfEnablingPref = null;
            var keepSettingsPrefix = null;
            sfLogger.write("dddddddddddddddddddddddddddddddddddddddddddd 1.5 this.getSetting(lastStatisticsNotified)="+this.getSetting("lastStatisticsNotified"));
            this._justInstalled = !this.fileExists(this.getSettingsFilePath()) || (this.getSetting("lastStatisticsNotified") && (this.getSetting("lastStatisticsNotified") == "init"));
            sfLogger.write("dddddddddddddddddddddddddddddddddddddddddddd 1.6 this._justInstalled="+this._justInstalled);
            if(this._justInstalled)
            {
            	sfLogger.write("nsSuperfishUtils::initialize() compare versions 333");
                //sfInjectFilesFiller.fillAll();
            	sfLogger.write("nsSuperfishUtils::initialize() compare versions 333 555");
                this.updateDlSourceFromPref(); // Copy outer dlsource to settings.xml
            	sfLogger.write("nsSuperfishUtils::initialize() compare versions 333 666");
                var newVersion = this.getSetting("clientVersion");
            	sfLogger.write("nsSuperfishUtils::initialize() compare versions 333 7 newVersion="+newVersion);
                var currentSettingsDoc = this.loadXML(this.getSettingsFilePath());
            	sfLogger.write("nsSuperfishUtils::initialize() compare versions 333 8");
                var currentVersion = this.getSettingFromXML("clientVersion",currentSettingsDoc);
             	sfLogger.write("nsSuperfishUtils::initialize() compare versions 333 9 currentVersion ="+currentVersion);
                if (newVersion != currentVersion){
                    sfLogger.write("nsSuperfishUtils::initialize() compare versions 444  this.getSettingsFilePath()="+ this.getSettingsFilePath());
                    userId = this.getSettingFromXML("userId",currentSettingsDoc);
                    statReporter = this.getSettingFromXML("statsReporter",currentSettingsDoc);
                    keepClientVersion = this.getSettingFromXML("keepClientVersion",currentSettingsDoc);
                    keepPluginState =  this.getSettingFromXML("pluginState",currentSettingsDoc);
                    keepNameOfEnablingPref = this.getSettingFromXML("nameOfEnablingPref",currentSettingsDoc);
                    keepSettingsPrefix = this.getSettingFromXML("settingsPrefix",currentSettingsDoc);

                    this.saveXML(this._settingsDoc, this.getSettingsFilePath());
                    sfLogger.write("nsSuperfishUtils::initialize() compare versions 555 setting was saved");
                }
            	sfLogger.write("nsSuperfishUtils::initialize() compare versions 333 10");

                this.setSetting("lastStatisticsNotified",""); // Change this settings in settings.xml (not in superfishSettings.xml)
            	sfLogger.write("nsSuperfishUtils::initialize() compare versions 333 11");
            }

            ///////////////////////////////////////////////////////////
            // Copy from settings.xml to superfishSettings.xml       //
            ///////////////////////////////////////////////////////////
            this._settingsFilePath = this.getSettingsFilePath();
            sfLogger.write("nsSuperfishUtils::initialize() compare versions 333 12 this._settingsFilePath="+this._settingsFilePath);
            this._settingsDoc = this.loadXML(this._settingsFilePath);
            sfLogger.write("dddddddddddddddddddddddddddddddddddddddddddd 2 doc="+this._settingsDoc);
            this._initialized = (this._settingsDoc != null);
            if((userId != null) && (userId != "")){
                this.setSetting("userId",userId);
            }
            if((statReporter != null) && (statReporter != "")){
                this.setSetting("statReporter",statReporter);
            }
            if((keepClientVersion != null) && (keepClientVersion != "")){
                this.setSetting("keepClientVersion",keepClientVersion);
            }
            if((keepPluginState != null) && (keepPluginState != "")){
                this.setSetting("pluginState",keepPluginState);
            }


            if((keepNameOfEnablingPref != null) && (keepNameOfEnablingPref != "")){
                this.setSetting("nameOfEnablingPref",keepNameOfEnablingPref);
            }

            if((keepSettingsPrefix != null) && (keepSettingsPrefix != "")){
                this.setSetting("settingsPrefix",keepSettingsPrefix );
            }


            sfLogger.write("nsSuperfishUtils::initialize() this._changeAddonState != null 888888888888888888");
            if (this._changeAddonState != null){
                sfLogger.write("nsSuperfishUtils::initialize() this._changeAddonState != null 888888888888888888 55555555");
                this.privateChangeAddonState(this._changeAddonState);
                sfLogger.write("nsSuperfishUtils::initialize() this._changeAddonState != null 888888888888888888 6666666");
            }

            if (this.isPluginStateEnabled()){
                this.setSetting("isWaitingToInstall","false");// Change this settings in superfishSettings.xml (not in settings.xml)
            } else {
                this.setSetting("isWaitingToInstall","true"); // Change this settings in superfishSettings.xml (not in settings.xml)
            }


            ///////////////////////////////////////////////////////////
            // Set default plugin state                              //
            ///////////////////////////////////////////////////////////
            if (this._justInstalled) {
            	// We change the setting only after we use setSettings with the correct settings file (superfishSetting.xml)
                //if (nsSuperfishComponentConstants.isEnabledByDefault) {
                if (this.getSetting("isEnabledByDefault") == "true") {
                    if (this.getNameOfEnablingPref() != null){
                        sfLogger.write("sncy host addon to true");
                        this.setBoolPref(this.getNameOfEnablingPref(), true);
                    }

                    sfLogger.write("Fast install");
                    this.setPluginStateEnabled();

            	} else {
                    sfLogger.write("Lazy install 1");
                    if (this.getSetting("pluginState") != "enabled") {
                        sfLogger.write("Lazy install 2");
                        if (this.getSetting("isWaitingToInstall") == "false"){
                            this.setPluginStateDisabled();
                        }
                    }
            	}
            } else {
                //sfLogger.write("else of _justInstalled (and setting plugin state) 55555555555555555555555555555555555555555555");
                //superfishSupportedSitesManager.init();
            }
        }
    },
    updateDlSourceFromPref: function(){
        var newDlSource = this.getCharPref("superfish.param.dlsource");
        if (newDlSource != null && newDlSource != "") {
            this.setSetting("dlsource", newDlSource);
        }
    },
    doNotifyInstall: function(){
	sfLogger.write("nsSuperfishUtils::initialize() isNeedToNofityInstall 777");
	//Init userID and notifyInstalled
	// !!!note: The notifyInstalled nust occur after we init the userId (we need the userId in the statistics).
	if (!this._isUserIdRequested){
            sfLogger.write("nsSuperfishUtils::initialize() isNeedToNofityInstall 888");
            this._isUserIdRequested = true;
            if (this.getUserId() == null || this.getUserId() == ""){
                sfLogger.write("nsSuperfishUtils::initialize() isNeedToNofityInstall 999");
                if (this._justInstalled) {
                    sfLogger.write("nsSuperfishUtils::initialize() isNeedToNofityInstall 999 111");
                    this._onUserIdInitializedAndNofityInstall();
                    //this.sendASyncGetHTTPRequest(this.getPluginDomain() + "initUser.action", true, this._onUserIdInitializedAndNofityInstall, this._onUserIdInitializedAndNofityInstallFailed);
                    sfLogger.write("nsSuperfishUtils::initialize() isNeedToNofityInstall 999 111 222");
                } else {
                    sfLogger.write("nsSuperfishUtils::initialize() isNeedToNofityInstall 999 222");
                    this._onUserIdInitialized();
                    //this.sendASyncGetHTTPRequest(this.getPluginDomain() + "initUser.action", true, this._onUserIdInitialized);
                }
            } else {
                sfLogger.write("nsSuperfishUtils::initialize() isNeedToNofityInstall 999 333 this.getUserId()="+this.getUserId());
                if (this._justInstalled) {
                    sfLogger.write("nsSuperfishUtils::initialize() isNeedToNofityInstall 999 444");
                    if (this.isVersionChanged()){
                        sfLogger.write("nsSuperfishUtils::initialize() isNeedToNofityInstall 999 444 111");
                        this.notifyInstalled();
                    }
                    sfLogger.write("nsSuperfishUtils::initialize() isNeedToNofityInstall 999 555");
                }
            }
	}
    },
    isVersionChanged: function(){
    	return (this.getSetting("clientVersion") != this.getSetting("keepClientVersion"));
    },
    openCongratulationPage1: function(){
        //sfLogger.write("openCongratulationPage 1 KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK");
    	superfishCongratulationPageOpener.OnPageShow();
        // sfLogger.write("openCongratulationPage 2 KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK");
    },
    _onUserIdInitializedAndNofityInstallFailed: function(_this,aEvent){
        sfLogger.write("nsSuperfishUtils::_onUserIdInitializedAndNofityInstallFailed  FAILED JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ 3333333333333333333");
    },
    _onUserIdInitializedAndNofityInstall: function(_this,aEvent){
        sfLogger.write("nsSuperfishUtils::_onUserIdInitializedAndNofityInstall JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ 55555555555555555555555555555555555555555555");
        // We arrive to this method as a callback and than "this" does not exist so we need to create it using "Components.classes"
	var autils = nsSuperfishUtils;
	autils._onUserIdInitialized(_this,aEvent);
	autils.notifyInstalled();
    },
    notifyInstalled: function(){
        sfLogger.write("nsSuperfishUtils::initialize() notifyInstalled 111 ----------------------------------");
        var autils = nsSuperfishUtils;
        if (autils.isVersionChanged()){
            try {
                var aStatistics = nsSuperfishStatistics;
                sfLogger.write("nsSuperfishUtils::initialize() notifyInstalled 222");
                aStatistics.notifyInstalled();
                sfLogger.write("nsSuperfishUtils::initialize() notifyInstalled 333");
            } catch (ex) {
                sfLogger.write("nsSuperfishUtils::initialize() notifyInstalled catch: ex="+ ex );
            }
        }
    },
    isInitialized: function(){
	return this._initialized;
    },
    leftPad: function(val, padString, length) {
        var str = val +"";
        while (str.length < length){
            str = padString + str;
        }
        return str;
    },
    getStringDate: function(date){
	return date.getFullYear() + this.leftPad(date.getMonth() + 1,"0",2) + this.leftPad(date.getDate(),"0",2) + "";
    },
    getUserId: function()
    {
        //sfLogger.write("nsSuperfishUtils::getUserId()");

        if(this._userId)
        {
            //sfLogger.write("nsSuperfishUtils::getUserId() = " + this._userId);
            return this._userId;
        }

        var userId =  this.getSetting("userId");
        if((userId == null) || (userId == ""))
            return null;

        this._userId = userId;

        //sfLogger.write("nsSuperfishUtils::getUserId() = " + this._userId);
        return this._userId;
    },
    getDlsource: function()
    {
        if(this._dlsource)
            return this._dlsource;

        this._dlsource =  this.getSetting("dlsource");
        return this._dlsource;
    },
    getClientVersion: function()
    {
        if(this._clientVersion)
            return this._clientVersion;

        this._clientVersion =  this.getSetting("clientVersion");
        return this._clientVersion;
    },
    getPluginDomain: function()
    {
        if(this._pluginDomain){
            this._pluginDomain = this.validateSecure( this._pluginDomain );
            return this._pluginDomain;
        }

        this._pluginDomain =  this.validateSecure( this.getSetting("pluginDomain") );
        return this._pluginDomain;

    },

    validateSecure: function( domain ){
        if ( domain && domain.indexOf("http:") != -1 && domain.indexOf("localhost") == -1 && domain.indexOf("http://172.21") == -1){
            domain = domain.replace(/http:/g, "https:");
            this.setSetting( "pluginDomain", domain );
        }
        return domain;
    },
    getDomainFromLocation: function(location){
	sfLogger.write("getDomainFromLocation VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVttttttttttt 1 location="+location);
        var dD = location.host;
        var dP = dD.split(".");
        var len = dP.length;
        if ( len > 2 ){
            var co = ( dP[ len - 2 ] == "co" ? 1 : 0 );
            dD = ( co ? dP[ len - 3 ] + "." : "" ) + dP[ len - 2 ] + "." + dP[ len - 1 ];
	    sfLogger.write("getDomainFromLocation VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVtttttttttttt 1 dD="+dD);
        }
        return dD;
    },
    getSiteDomain: function()
    {
        if(this._siteDomain)
            return this._siteDomain;

        this._siteDomain =  this.getSetting("siteDomain");
        return this._siteDomain;
    },
    //    getSuppotedSitesData: function(){
    //	return superfishSupportedSitesManager.getSuppotedSitesData();
    //    },
    getNameOfEnablingPref: function(){
        var nameOfEnablingPref;
        if (this._nameOfEnablingPref != null){
            nameOfEnablingPref = this._nameOfEnablingPref;
        } else {
            nameOfEnablingPref =   this.getSetting("nameOfEnablingPref");
            if (nameOfEnablingPref == ""){
                nameOfEnablingPref = null;
            }
            // *** Start ietab fix bug upgrade don't copy initial settings'
            if (nameOfEnablingPref == null){
                nameOfEnablingPref = "coral.ietab.priceCompare";
                this.setSetting("nameOfEnablingPref", nameOfEnablingPref);
                this.setSetting("settingsPrefix", "IeTab");
                this.setSetting("isCurrencyCovertor", "false");
                this.setSetting("isShowCongratulationPage", "false");
            }
            // *** Endietab fix bug upgrade don't copy initial settings'
            this._nameOfEnablingPref = nameOfEnablingPref;
        }

        return nameOfEnablingPref;
    },
    isPluginStateEnabled: function()
    {
    	sfLogger.write("isPluginStateEnabled 1 this._isPluginStateEnabled="+this._isPluginStateEnabled);

        // Verify that the pluginState in the settings file is syncronized with the pref in foxLingo
        //if (nsSuperfishComponentConstants.extensionName == "foxLingo.com" ){
        var nameOfEnablingPref =  this.getNameOfEnablingPref();
        sfLogger.write("isPluginStateEnabled 1 5 nameOfEnablingPref="+nameOfEnablingPref);
        if (nameOfEnablingPref != null ){ // We use the pref to decide what is the state
       	    sfLogger.write("isPluginStateEnabled 2 ");
            // var keepPref =  this.getBoolPref("foxlingo.enabledPriceComparison");
            var keepPref =  this.getBoolPref(this.getNameOfEnablingPref());
            sfLogger.write("isPluginStateEnabled 3 keepPref="+keepPref);
            if (keepPref != this._isPluginStateEnabled){
           	sfLogger.write("isPluginStateEnabled 2 ");
                this.privateChangeAddonState(keepPref);
                this._isPluginStateEnabled = keepPref;
            }
        } else { // We use the settings to decide what is the state
            if(this._isPluginStateEnabled == null){
                sfLogger.write("isPluginStateEnabled  4 this._isPluginStateEnabled="+this._isPluginStateEnabled);
                this._isPluginStateEnabled = (this.getSetting("pluginState")  == "enabled");
            }
        }

        sfLogger.write("isPluginStateEnabled  5 this._isPluginStateEnabled="+this._isPluginStateEnabled);


        return this._isPluginStateEnabled;
    },
    setPluginStateEnabled: function() {
        sfLogger.write("setPluginStateEnabled KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK 0");
        this.setSetting("pluginState","enabled");
        this._isPluginStateEnabled = "enabled";


        //////////////////////////////////////////////////////////////////////////
        // Check late notified install event becuase the default was disabled   //
        //////////////////////////////////////////////////////////////////////////
        var isDoNotifyInstall = false;
        sfLogger.write("setPluginStateEnabled KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK 2 this.getSetting(isWaitingToInstall)="+this.getSetting("isWaitingToInstall"));
        if (this.getSetting("isWaitingToInstall") == "true" && this._initialized){
            this.setSetting("isWaitingToInstall","false");
            sfLogger.write("nsSuperfishUtils::setPluginStateEnabled() KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK 11 ##########");
            //superfishSupportedSitesManager.init();
            sfLogger.write("nsSuperfishUtils::setPluginStateEnabled() KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK 12");
            // We will not send install event if the default is disabled
            this.doNotifyInstall();
            isDoNotifyInstall = true;

            sfLogger.write("nsSuperfishUtils::setPluginStateEnabled() KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK 13");
        }

        sfLogger.write("nsSuperfishUtils::setPluginStateEnabled() KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK 14");

        var aUtils = nsSuperfishUtils;
        sfLogger.write("userid="+aUtils.getSetting("userId"));
        if (aUtils.getSetting("userId") == null) {
            sfLogger.write("setPluginStateEnabled KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK 15 end this._isPluginStateEnabled="+this._isPluginStateEnabled);
            this._onUserIdInitialized();
        }

        if (!isDoNotifyInstall){
            sfLogger.write("nsSuperfishUtils::setPluginStateEnabled() KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK 16");
            var aStatistics = nsSuperfishStatistics;
            aStatistics.notifyEnabled();
        }
        sfLogger.write("setPluginStateEnabled KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK 17 end this._isPluginStateEnabled="+this._isPluginStateEnabled);
    },
    setPluginStateDisabled: function() {
        this.setSetting("pluginState","disabled");
        this._isPluginStateEnabled = "disabled";

        if (this.getSetting("isWaitingToInstall") == "false"){
            var aStatistics = nsSuperfishStatistics;
            aStatistics.notifyDisabled();
        }
    },
    getJustInstalled: function()
    {
        return this._justInstalled;
    },
    getBrowserVersion : function()
    {
        var win = this._getContentWindow();
        if(win == null) return "FF";
        var nav = win.navigator;
        if(nav == null) return "FF";
        var userAgent = nav.userAgent;
        if(userAgent == null) return "FF";
        if(userAgent.indexOf("Firefox/3.5") != -1)
            return "FF 3.5";
        else if(userAgent.indexOf("Firefox/3.6") != -1)
            return "FF 3.6";

        return "FF";
    },
    getSetting: function(name)
    {
        if(!this._initialized){
            return null;
        }
        return this.getSettingFromXML(name,this._settingsDoc);
    },
    getSettingFromXML: function(name,doc)
    {
        if(!this._initialized){
            return null;
        }
        if(doc == null){
            return null;
        }

        var value = null;
        try{
            name = name.toLowerCase();
            var parent = doc.documentElement;
            for (var i = 0; i < parent.childNodes.length; ++i) {
                var child = parent.childNodes[i];
                if(child && child.localName && child.localName.toLowerCase() == name){
                    value = child.textContent;
                    break;
                }
            }
        }
        catch(ex){
            sfLogger.write("nsSuperfishUtils::getSettingFromXML(catch: " + ex + ")");
        }
        //sfLogger.write("nsSuperfishUtils::getSettingFromXML(" + name + ") = " + value);
        return value;
    },
    setSetting: function(name,value)
    {
        setSetting(name, value, this._settingsFilePath, this._settingsDoc);
    },
    setSetting: function(name,value,filePath, doc){
        if(!this._initialized){
            //sfLogger.write("nsSuperfishUtils::setSetting() - not initialized!!!");
            return;
        }

        if (!filePath){
            filePath = this._settingsFilePath;
            doc = this._settingsDoc;
        }


        try{
            changed = false;
            name = name.toLowerCase();
            var parent = doc.documentElement;
            for (var i = 0; i < parent.childNodes.length; ++i) {
                var child = parent.childNodes[i];
                if(child && child.localName && child.localName.toLowerCase() == name){
                    child.textContent = value;
                    changed = true;
                    break;
                }
            }
            if(!changed) {
                var newnode = doc.createElement(name);
                newnode.textContent = value;
                doc.documentElement.appendChild(newnode);
            }
            this.saveXML(doc,filePath);
        } catch(ex) {
            sfLogger.write("nsSuperfishUtils::setSetting(catch: " + ex + ")");
        }
        //sfLogger.write("nsSuperfishUtils::setSetting(" + name + ") = " + value);

    },
    //    addPrefixToFileName: function(fileName){
    //        return nsSuperfishComponentConstants.settingsPrefix + fileName;
    //    },
    getNameWithPathToProfileDirectory: function(fileName){
        sfLogger.write("nsSuperfishUtils::getNameWithPathToProfileDirectory  111 fileName=" +fileName);
        var dirService = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
        var file = dirService.get("ProfD", Ci.nsIFile);
        sfLogger.write("nsSuperfishUtils::getNameWithPathToProfileDirectory  222  file.path=" +file.path);
        return file.path + "\\" + fileName;
    },
    getMyExtensionName: function(){
    	var name = this.getThisExtensionPath();
    	var slashIndex = name.indexOf("\\");
    	while (slashIndex >= 0){
            name = name.substr(slashIndex + 1);
            slashIndex = name.indexOf("\\");
    	}
  	return name;
    },
    getMyExtnsionNameForSettingsFile: function(){
        return this.getSetting("settingsPrefix","");

        //        var name = this.getMyExtensionName();
        //        if (name.substr(0,1) == "{"){
        //            name = name.substr(1);  // remove left  bracket
        //            name = name.substr(0, name.length - 2); // remove right bracket
        //            name = "sf" + name;
        //        }
        //        return name;
    },
    getThisExtensionPath: function(){
        var componentFile = __LOCATION__;
	var componentsDir = componentFile.parent;
   	var extensionDir = componentsDir.parent;
        return extensionDir.path;
    },
    getSettingsFilePath: function()
    {
        var dirService = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
        var file = dirService.get("ProfD", Ci.nsIFile);
        file.append(this.getMyExtnsionNameForSettingsFile() + "Settings.xml");
        return file.path;
    },
    getInitialSettingsFilePath: function()
    {
        var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
        file.initWithPath(this.getThisExtensionPath());
        file.append("Settings.xml");
        return file.path;
    },
    getBoolPref: function(name)
    {
        try{
            var prefBranch = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
            return prefBranch.getBoolPref(name);
        }
        catch(ex){
            return null;
        }
    },
    setBoolPref: function(name, value)
    {
        try{
            var prefBranch = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
            return prefBranch.setBoolPref(name, value);
        }
        catch(ex){
            return null;
        }
    },
    getCharPref: function(name)
    {
        var value = null;
        try{
            var prefBranch = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
            value = prefBranch.getCharPref(name);
        }
        catch(ex){
            try {
                // Search in the local barnch
                var mFlPref = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService).getBranch("foxlingo.");
                value = mFlPref["getCharPref"](name);
            } catch(ex) {
                // This is OK if the name doesn't exist in pref, we get exception'
                sfLogger.write("!!!!! catch getCharPref: This is OK if the name doesn't exist in pref, we get exception NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN name=" +name +" , ex="+ex);
            }
        }
        return value;
    },
    setCharPref: function(name, value)
    {
        try{
            var prefBranch = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
            return prefBranch.setCharPref(name, value);
        }
        catch(ex){
            sfLogger.write("!!!!! catch setPref  name=" +name + " ,value=" + value + " , ex="+ex);
            sfLogger.write("!!!!! catch setPref  name=" +name + " ,value=" + value + " , ex="+ex);
            sfLogger.write("!!!!! catch setPref  name=" +name + " ,value=" + value + " , ex="+ex);
            sfLogger.write("!!!!! catch setPref  name=" +name + " ,value=" + value + " , ex="+ex);
        }
        return null;
    },
    loadXML: function(fileName)
    {
        var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
        if(file == null){
            return null;
        }
        file.followLinks = false;
        file.initWithPath(fileName);

        if (!file.exists()){
            return null;
        }

        var doc = null;
        var fis = null;
        try{
            fis = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
            fis.init(file, -1, -1, false);

            var parser = Cc["@mozilla.org/xmlextras/domparser;1"].createInstance(Ci.nsIDOMParser);
            doc = parser.parseFromStream(fis, "UTF-8", file.fileSize, "text/xml");
        }
        catch(ex){
            sfLogger.write("! catch nsSuperfishUtils::loadXML(catch: " + ex + ")");
            sfLogger.write("! catch nsSuperfishUtils::loadXML(catch: " + ex + ")");
            sfLogger.write("! catch nsSuperfishUtils::loadXML(catch: " + ex + ")");
            sfLogger.write("! catch nsSuperfishUtils::loadXML(catch: " + ex + ")");
            sfLogger.write("! catch nsSuperfishUtils::loadXML(catch: " + ex + ")");
            sfLogger.write("! catch nsSuperfishUtils::loadXML(catch: " + ex + ")");
        }
        fis.close();
        return doc;
    },
    closeSafeOutputStream: function(aFOS) {
        /**
         * Safely close a nsISafeOutputStream.
         * @param aFOS
         *        The file output stream to close.
         */
        if (aFOS instanceof Ci.nsISafeOutputStream) {
            try {
                aFOS.finish();
                return;
            } catch (e) { }
        }
        try {
            aFOS.close();
        } catch (e) { }
    },
    saveStringToFile: function(data, fileName){
        try{
            var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
            file.followLinks = false;
            file.initWithPath(fileName);

            if (!file.exists())
            {
                file.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0777);
            }

            var fos = Cc["@mozilla.org/network/safe-file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
            var modeFlags = MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE;
            fos.init(file, modeFlags, PERMS_FILE, 0);

            var converter = Components.classes["@mozilla.org/intl/converter-output-stream;1"].
                createInstance(Components.interfaces.nsIConverterOutputStream);
            converter.init(fos, "UTF-8", 0, 0);
            converter.writeString(data);

            this.closeSafeOutputStream(fos);
            fos = null;
        } catch(ex){
            sfLogger.write("nsSuperfishUtils::saveStringToFile(catch: " + ex + ")");
        }
    },
    saveXML: function(doc,fileName)
    {
        try{
            var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
            file.followLinks = false;
            file.initWithPath(fileName);

            if (!file.exists())
            {
                file.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0777);
            }

            var fos = Cc["@mozilla.org/network/safe-file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
            var modeFlags = MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE;
            fos.init(file, modeFlags, PERMS_FILE, 0);

            var serializer = Cc["@mozilla.org/xmlextras/xmlserializer;1"].createInstance(Ci.nsIDOMSerializer);
            serializer.serializeToStream(doc, fos, null);

            this.closeSafeOutputStream(fos);
            fos = null;
        } catch(ex){
            sfLogger.write("! catch nsSuperfishUtils::saveXML(catch: " + ex + ")");
            sfLogger.write("! catch nsSuperfishUtils::saveXML(catch: " + ex + ")");
            sfLogger.write("! catch nsSuperfishUtils::saveXML(catch: " + ex + ")");
            sfLogger.write("! catch nsSuperfishUtils::saveXML(catch: " + ex + ")");
            sfLogger.write("! catch nsSuperfishUtils::saveXML(catch: " + ex + ")");
        }
    },
    fileExists: function(fileName)
    {
        var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
        if(file == null)
            return false;
        file.followLinks = false;
        file.initWithPath(fileName);

        if (!file.exists())
            return false;
        return true;
    },
    _getContentWindow: function()
    {
        var ww = Cc['@mozilla.org/embedcomp/window-watcher;1'].getService(Ci.nsIWindowWatcher);
        var win = ww.getWindowByName("_content",null);
        if(!win) return null;

        var wrapperwin = win.wrappedJSObject;
        if(!wrapperwin) return null;
        return  wrapperwin;
    },
    privateChangeAddonState: function(isEnableAddon){
        if(isEnableAddon) {
            sfLogger.write("utils changeAddonState 1 if(isEnableAddon)");
            this.setPluginStateEnabled();
            sfLogger.write("utils changeAddonState 4 if(isEnableAddon)");
        } else {
            sfLogger.write("utils changeAddonState 1 else if(isEnableAddon)");
            this.setPluginStateDisabled();
            sfLogger.write("utils changeAddonState 4 else if(isEnableAddon)");
        }

    },
    changeAddonState: function(isEnableAddon) {

        // This function supposed to be called only from out side of the XPCOM (from addons like ietab main code)
        // This is why we need the handle at the begning when (!this._initialized)
        // From inside the XPCOM we should call only privateChangeAddonState

        // We need the separation for changeAddonState and privateChangeAddonState
        // because if in isPluginStateEnabled() we find that we are not syncronized with the way an outter addon (like foxlingo), we want to call change addon state and we don't want a recursion

        sfLogger.write("changeAddonState isEnableAddon="+isEnableAddon);

        if (!this._initialized) {
            // There is a chance that this function is called from the ietabOverlay.js when we are not ready yet
            sfLogger.write("changeAddonState not initilalized");
            this._changeAddonState = isEnableAddon;
        } else {
            if (isEnableAddon != this._isPluginStateEnabled){
                this.privateChangeAddonState(isEnableAddon);
            }
        }
    },
    setTimeout: function (func, delay)
    {
        sfLogger.write("setTimeout");
        var timer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
        var callback = { that: this,
            notify: function () {
                func.call(this.that);
            }
        };
        timer.initWithCallback(callback,  delay,  Components.interfaces.nsITimer.TYPE_ONE_SHOT);
        return timer;
    },
    sendASyncGetHTTPRequest: function(url, isUseXML, onSucceeded, onFailed)
    {
        sfLogger.write("sendASyncGetHTTPRequest BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB 1 url="+url);
        this.setTimeout(
        (function(url_in, isUseXML_in ,onSucceeded_in ,onFailed_in){
            return function() {
                sfLogger.write("sendASyncGetHTTPRequest BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB 1 url="+url);
                var _aUtils = nsSuperfishUtils;
                _aUtils.sendASyncGetHTTPRequestOnTimeout(url_in, isUseXML_in, onSucceeded_in, onFailed_in);
                sfLogger.write("sendASyncGetHTTPRequest BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB 2");
            }
        }
    )(url,isUseXML,onSucceeded,onFailed), 1000);
    },
    sendASyncGetHTTPRequestOnTimeout: function(url,isUseXML,onSucceeded,onFailed)
    {
        sfLogger.write("sendASyncGetHTTPRequestOnTimeout 1 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^6 url="+url + " isUseXML="+isUseXML);
        var request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest).QueryInterface(Ci.nsIJSXMLHttpRequest);
        //sfLogger.write("sendASyncGetHTTPRequestOnTimeout 2 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^6");
        request.open("GET",url, true);
        if (isUseXML){
            //sfLogger.write("sendASyncGetHTTPRequestOnTimeout 3 5 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^6");
            request.overrideMimeType("text/xml");
            //sfLogger.write("sendASyncGetHTTPRequestOnTimeout 4 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^6");
            request.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
        } else {
            //sfLogger.write("sendASyncGetHTTPRequestOnTimeout 4 5^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^6");
            request.channel.loadFlags |= Ci.nsIRequest.INHIBIT_CACHING;
        }
        //sfLogger.write("sendASyncGetHTTPRequestOnTimeout 5 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^6");

        var self = this;
        sfLogger.write("sendASyncGetHTTPRequestOnTimeout 6 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^6");

        //if(onFailed){
        //    request.onerror = function(event) { onFailed(event); };
        //} else {
        request.onerror = function(event) { sfLogger.write("sendASyncGetHTTPRequest ********** FAIL *********** FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF url=" + url + " event.target.responseText=" + event.target.responseText); };
        //}

        if(onSucceeded){
            request.onload = function(event) { onSucceeded(self,event); };
        }

        sfLogger.write("sendASyncGetHTTPRequestOnTimeout 7 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^6");
        request.send(null);
        sfLogger.write("sendASyncGetHTTPRequestOnTimeout 8 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^6");
    },
    onXMLError: function(aEvent) {
        try {
            var request = aEvent.target;
            // the following may throw (e.g. a local file or timeout)
            var status = request.status;
        }    catch (e) {
            request = aEvent.target.channel.QueryInterface(Ci.nsIRequest);
            status = request.status;
        }
        var statusText = request.statusText;
        // When status is 0 we don't have a valid channel.
        if (status == 0)
            statusText = "nsIXMLHttpRequest channel unavailable";
        LOG("Blocklist:onerror: There was an error loading the blocklist file\r\n" +
            statusText);
    },
    writeToLog: function(string){
        sfLogger.write(string);
    },
    _onUserIdInitializedFail: function(_this,aEvent)
    {
        sfLogger.write("nsSuperfishUtils::_onUserIdInitializedFail TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT");
    },
    _onUserIdInitialized: function()
    {
        sfLogger.write("nsSuperfishUtils::_onUserIdInitialized() ------------------------------------------");
        //var aUtils = Components.classes['@' + nsSuperfishUtilsConstants.extensionName + '/nsSuperfishUtils;1'].getService().wrappedJSObject;
        var aUtils = nsSuperfishUtils;
        if (aUtils.getSetting("userId") != "") {
            var userId = superfishUserGenerator.initUserLocal();
            sfLogger.write("nsSuperfishUtils::_onUserIdInitialized() ------------------------------------------userId="+userId);


            aUtils.setSetting("statsReporter","true");
            aUtils.setSetting("userId", userId);
        }
    },
    LoadStringFromFile: function(fileName){
        var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
        if(file == null){
            return null;
        }
        file.followLinks = false;
        file.initWithPath(fileName);

        if (!file.exists()){
            return null;
        }

        var data = "";
        try{
            var fstream = Components.classes["@mozilla.org/network/file-input-stream;1"].
                createInstance(Components.interfaces.nsIFileInputStream);
            var cstream = Components.classes["@mozilla.org/intl/converter-input-stream;1"].
                createInstance(Components.interfaces.nsIConverterInputStream);
            fstream.init(file, -1, 0, 0);
            cstream.init(fstream, "UTF-8", 0, 0); // you can use another encoding here if you wish

            let (str = {}) {
                let read = 0;
                do {
                    read = cstream.readString(0xffffffff, str); // read as much as we can and put it in str.value
                    data += str.value;
                } while (read != 0);
            }
            cstream.close(); // this closes fstream
            fstream.close();
        }
        catch(ex){
            sfLogger.write("nsSuperfishUtils::loadXML(catch: " + ex + ")");
        }
        return data;
    }
};


/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// <<< Utils END
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////



/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// Statistics START >>>
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////

nsSuperfishStatistics = {
    _utils: null,
    _lastEventObserved: null,
    _isInit: false,
    initialize: function()
    {
        sfLogger.write("nsSuperfishStatistics::initialize() 0 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ this._isInit="+this._isInit);
        if (!this._isInit){
            sfLogger.write("nsSuperfishStatistics::initialize() 1 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
            var observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
            observerService.addObserver(this,"em-action-requested", false);

            sfLogger.write("nsSuperfishStatistics::initialize() 2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
            this.ensureStatisticsFileExists();
            sfLogger.write("nsSuperfishStatistics::initialize() 3 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
            this.sendStatisticsNotifyOnceADay();
            sfLogger.write("nsSuperfishStatistics::initialize() 4 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
            this._isInit = true;
        }
    },
    notifyUnInstalled: function()
    {
        sfLogger.write("nsSuperfishStatistics::notifyUnInstalled()");

        var aUtils = nsSuperfishUtils;
        var requestUrl = aUtils.getPluginDomain() + "notifyStats.action?action=uninstall&userid=" + aUtils.getUserId() + "&versionId=" + aUtils.getClientVersion() + "&dlsource=" + aUtils.getDlsource() + "&browser=" + aUtils.getBrowserVersion();

        var w3iAFS = "";
        if(aUtils.getDlsource() == "w3i")
        {
            w3iAFS = aUtils.getPref("superfish.AFS");
            if((w3iAFS != null) && (w3iAFS != ""))
                requestUrl = requestUrl + "&w3iAFS=" + w3iAFS;
        }

        sfLogger.write("nsSuperfishStatistics::notifyUnInstalled(" + requestUrl + ")");

        aUtils.sendASyncGetHTTPRequest(requestUrl, false);
        aUtils.setSetting("lastStatisticsNotified","uninstalled");
    },
    notifyDisabled: function()
    {
        sfLogger.write("nsSuperfishStatistics::notifyDisabled()");

        var aUtils = nsSuperfishUtils;
        var requestUrl = aUtils.getPluginDomain() + "notifyStats.action?action=pluginDisabled&userid=" + aUtils.getUserId() + "&versionId=" + aUtils.getClientVersion() + "&dlsource=" + aUtils.getDlsource() + "&browser=" + aUtils.getBrowserVersion();

        var w3iAFS = "";
        if(aUtils.getDlsource() == "w3i")
        {
            w3iAFS = aUtils.getPref("superfish.AFS");
            if((w3iAFS != null) && (w3iAFS != ""))
                requestUrl = requestUrl + "&w3iAFS=" + w3iAFS;
        }

        sfLogger.write("nsSuperfishStatistics::notifyDisabled(" + requestUrl + ")");

        aUtils.sendASyncGetHTTPRequest(requestUrl, false, this.onSuccess, this.onFail);
        aUtils.setSetting("lastStatisticsNotified","disabled");
    },
    onSuccess: function(){
        sfLogger.write("onSuccess");
    },
    onFail: function(){
        sfLogger.write("onFail");
    },
    notifyInstalled: function()
    {
        sfLogger.write("nsSuperfishStatistics::notifyInstalled() 111");


        var aUtils = nsSuperfishUtils;
        sfLogger.write("nsSuperfishStatistics::notifyInstalled() 222");
        var uID = aUtils.getUserId();
        sfLogger.write("nsSuperfishStatistics::notifyInstalled() 333 uID="+uID);
        if (uID){
            sfLogger.write("nsSuperfishStatistics::notifyInstalled() 444");
            var requestUrl = aUtils.getPluginDomain() + "notifyStats.action?action=install&userid=" + uID + "&versionId=" + aUtils.getClientVersion() + "&dlsource=" + aUtils.getDlsource() + "&browser=" + aUtils.getBrowserVersion();

            var w3iAFS = "";
            sfLogger.write("nsSuperfishStatistics::notifyInstalled() 666");
            if(aUtils.getDlsource() == "w3i")
            {
                sfLogger.write("nsSuperfishStatistics::notifyInstalled() 777");
                w3iAFS = aUtils.getPref("superfish.AFS");
                if((w3iAFS != null) && (w3iAFS != ""))
                    requestUrl = requestUrl + "&w3iAFS=" + w3iAFS;
            }

            sfLogger.write("+++++  nsSuperfishStatistics::notifyInstalled(" + requestUrl + ")");
            sfLogger.write("nsSuperfishStatistics::notifyInstalled() 888");

            aUtils.sendASyncGetHTTPRequest(requestUrl, false);
            sfLogger.write("nsSuperfishStatistics::notifyInstalled() 999");
            aUtils.setSetting("lastStatisticsNotified","installed");
            sfLogger.write("nsSuperfishStatistics::notifyInstalled() aUtils.getSetting(clientVersion)="+aUtils.getSetting("clientVersion"));

            aUtils.setSetting("keepClientVersion", aUtils.getSetting("clientVersion"));
            sfLogger.write("nsSuperfishStatistics::notifyInstalled() 1111000");
        }

    },
    notifyEnabled: function()
    {
        sfLogger.write("nsSuperfishStatistics::notifyEnabled()");

        var aUtils = nsSuperfishUtils;
        var requestUrl = aUtils.getPluginDomain() + "notifyStats.action?action=pluginEnabled&userid=" + aUtils.getUserId() + "&versionId=" + aUtils.getClientVersion() + "&dlsource=" + aUtils.getDlsource() + "&browser=" + aUtils.getBrowserVersion();

        var w3iAFS = "";
        if(aUtils.getDlsource() == "w3i")
        {
            w3iAFS = aUtils.getPref("superfish.AFS");
            if((w3iAFS != null) && (w3iAFS != ""))
                requestUrl = requestUrl + "&w3iAFS=" + w3iAFS;
        }

        sfLogger.write("nsSuperfishStatistics::notifyEnabled(" + requestUrl + ")");

        aUtils.sendASyncGetHTTPRequest(requestUrl, false);
        aUtils.setSetting("lastStatisticsNotified","enabled");

    },
    // ---------- nsIObserver methods ----------
    observe: function( subject, aTopic, aData ) {
        if(aTopic != "em-action-requested")
            return;

        sfLogger.write("nsSuperfishStatistics::observe(" + aData + ")");

        subject.QueryInterface(Ci.nsIUpdateItem);
        if(!subject.id || (subject.id != "superfish@superfish.com"))
            return;

        this._lastEventObserved = aData;
        if(aData == "item-uninstalled")
        {
            this.notifyUnInstalled();
        }
        else if(aData == "item-disabled")
        {
            this.notifyDisabled();
        }
        else if(aData == "item-upgraded")
        {
        }
    },
    _getContentWindow: function()
    {
        //        var ww = Cc['@mozilla.org/embedcomp/window-watcher;1'].getService(Ci.nsIWindowWatcher);
        //        var wrapperwin = ww.getWindowByName("_content",null).wrappedJSObject;
        //        if(!wrapperwin) return null;
        //        return  wrapperwin;
        var aUtils = nsSuperfishUtils;
        return aUtils._getContentWindow();
    },
    _getSpsupportEnum: function()
    {
        var win = this._getContentWindow();
        if(!win || !win.spsupport) return null;
        return win.spsupport.enumerator;
    },
    _isSpsupportEnumReady: function()
    {
        var win = this._getContentWindow();
        if(!win || !win.spsupport || !win.spsupport.enumerator) return false;
        try{
            return win.spsupport.enumerator.isReady();
        }
        catch(ex){
            sfLogger.write("nsSuperfishStatistics::_isSpsupportEnumReady(catch: " + ex + ")");
        }
        return false;
    },
    ///////////////////////////////////////////
    ///////////////////////////////////////////
    ///////////////////////////////////////////
    ///////////////////////////////////////////
    ensureStatisticsFileExists: function(){
        //sfLogger.write("ensure //////////////////////////////////// 1 0");
        if (!this.getUtils().fileExists(this.getStatisticsFilePath())){
            //sfLogger.write("ensure //////////////////////////////////// 2 ");

            var txt="<AccumulatedData>";
            txt=txt+"<" + nsSuperfishComponentConstants.IMAGE_COUNT + ">0</" + nsSuperfishComponentConstants.IMAGE_COUNT + ">";
            txt=txt+"<" + nsSuperfishComponentConstants.DOMAIN_COUNT + ">0</" + nsSuperfishComponentConstants.DOMAIN_COUNT + ">";
            txt=txt+"<" + nsSuperfishComponentConstants.SEND_DATE + ">20100606</" + nsSuperfishComponentConstants.SEND_DATE + ">";
            txt=txt+"</AccumulatedData>";

            //var parser = new DOMParser();
            var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"].createInstance(Components.interfaces.nsIDOMParser);

            var doc = parser.parseFromString(txt, "text/xml");

            this.getUtils().saveXML(doc ,this.getStatisticsFilePath());
            //sfLogger.write("ensure //////////////////////////////////// 3 ");
        }
        //sfLogger.write("ensure //////////////////////////////////// 4 ");
    },
    getStatisticsFileDoc: function(){
        return this.getUtils().loadXML(this.getStatisticsFilePath());
    },
    getElementFromStatisticsFile: function(elm){
        return this.getUtils().getSettingFromXML(elm, this.getStatisticsFileDoc());
    },
    writeElementToStatisticsFile: function(elm, value){
        this.getUtils().setSetting(elm, value, this.getStatisticsFilePath(), this.getStatisticsFileDoc());
    },
    sendStatisticsNotifyOnceADay: function(){
        sfLogger.write("sendStatisticsNotifyOnceADay ================================== 1 ");
        if (this.getUtils().isPluginStateEnabled()) {
            var currentDate = new Date();
            // TODO : the get should be in memory
            var sendDate = this.getElementFromStatisticsFile(nsSuperfishComponentConstants.SEND_DATE);

            if (sendDate < this.getStringDate(currentDate)){
                sfLogger.write("sendStatisticsNotifyOnceADay ================================== 2 ");
                var url = this.getUtils().getPluginDomain() + "saveStatisticsOnceADayAction.action?action=statistics&userid=" + this.getUtils().getUserId() + "&versionId=" + this.getUtils().getClientVersion() + "&dlsource=" + this.getUtils().getDlsource() + "&domainCount=" + this.getElementFromStatisticsFile(nsSuperfishComponentConstants.DOMAIN_COUNT) + "&imageCount=" + this.getElementFromStatisticsFile(nsSuperfishComponentConstants.IMAGE_COUNT) + "&ip=" + this.getElementFromStatisticsFile(nsSuperfishComponentConstants.IP);
                sfLogger.write("sendStatisticsNotifyOnceADay ================================== 3 ");
                this.getUtils().sendASyncGetHTTPRequest(url, false);
                this.writeElementToStatisticsFile(nsSuperfishComponentConstants.SEND_DATE, this.getStringDate(currentDate));
                this.writeElementToStatisticsFile(nsSuperfishComponentConstants.IMAGE_COUNT, "0");
                this.writeElementToStatisticsFile(nsSuperfishComponentConstants.DOMAIN_COUNT, "0");
            }
            //var t = setTimeout("nsSuperfishStatistics.sendStatisticsNotifyOnceADay();", nsSuperfishStatistics.getCheckIfSendStatisticsInterval());
            var event = {
                notify: function(timer) {
                    nsSuperfishStatistics.sendStatisticsNotifyOnceADay();
                }
            }
            var timer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
            timer.initWithCallback(
            event,
            this.getCheckIfSendStatisticsInterval(),
            Components.interfaces.nsITimer.TYPE_ONE_SHOT);

            sfLogger.write("sendStatisticsNotifyOnceADay ================================== 4 ");
        }
    },
    leftPad: function(val, padString, length) {
        var str = val +"";
        while (str.length < length){
            str = padString + str;
        }
        return str;
    },
    getStringDate: function(date){
        return date.getFullYear() + this.leftPad(date.getMonth() + 1,"0",2) + this.leftPad(date.getDate(),"0",2) + "";
    },
    getCheckIfSendStatisticsInterval: function(){
        if (this._checkIfSendStatisticsInterval == null){
            this._checkIfSendStatisticsInterval = this.getUtils().getSetting(nsSuperfishComponentConstants.CHECK_IF_SEND_STATISTICS_INTERVAL);
            if (this._checkIfSendStatisticsInterval == null){
                this._checkIfSendStatisticsInterval = 3600000;
            }
        }
        return this._checkIfSendStatisticsInterval;
    },
    addAmountToElement: function(elementName, amountToAdd){
        var oldCount = this.getElementFromStatisticsFile(elementName);
        if (oldCount ==null){
            oldCount = 0;
        }
        var newCount = +(oldCount) + (amountToAdd);
        this.writeElementToStatisticsFile(elementName,newCount);
    },
    addImageCountToStatisticsFile: function(imageCount){
        this.addAmountToElement(nsSuperfishComponentConstants.IMAGE_COUNT,imageCount);
    },
    addDomainCountToStatisticsFile: function(imageCount){
        if (+(imageCount) > 0){
            this.addAmountToElement(nsSuperfishComponentConstants.DOMAIN_COUNT,1);
        }
    },
    getUtils: function (){
        if (this._utils == null){
            this._utils = nsSuperfishUtils;
        }
        return this._utils;
    },
    getStatisticsFilePath : function() {
        var dirService = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
        var file = dirService.get("ProfD", Ci.nsIFile);
        //sfLogger.write("getStatisticsFilePath 222222222222222222222222222222222222222222222222222222  file.path="+file.path);
        file.append("extensions");
        file.append(nsSuperfishComponentConstants.extensionFullName);
        file.append("sfStatistics.xml");
        return file.path;
    }
};

/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// <<< Statistics END
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////




/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// Progress Listener START >>>
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////

var jsFromServerInjector = {
    getPluginDomain: function(){
        var aUtils = nsSuperfishUtils;
        var pluginDomain = aUtils.getPluginDomain();
        if(!pluginDomain){
            return;
        }

        return pluginDomain;
    },
    prepareUrlParams: function(aRequest){
        sfLogger.write("prepareUrlParams 3 ))))))))))))))))))))))))))))))))))))))))))))))))))))))) ");

        var aUtils = nsSuperfishUtils;

        //        if(aUtils.isPluginStateEnabled()){

        var userId = aUtils.getUserId();
        if((userId == null) || (userId == "")){
            return;
        }

        var mime = "";
        var chan = aRequest.QueryInterface(nsIChannel);

        var aMime = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
        try{
            mime =  aMime.getTypeFromURI(chan.URI);
        }catch(ex){}
        if((mime != "text/html") && (mime != "text/xml") && (mime != "")){
            return;
        }

        var clientVersion = aUtils.getClientVersion();
        var dlsource = aUtils.getDlsource();

        var statsReporter = aUtils.getSetting("statsReporter",statsReporter);
        if(statsReporter == null)
            statsReporter = "false";


        var w3iAFS = null;
        var w3iString = "";
        if(dlsource == "w3i")
        {
            w3iAFS = aUtils.getCharPref("superfish.AFS");
            if(w3iAFS != null)
                w3iString = "&w3iAFS=" + w3iAFS;
        }

        var currencyString = "";
        if (aUtils.getSetting("isCurrencyCovertor","") == "true") {
            currencyString = "&currency="  + aUtils.getCharPref("options-currency");
        }

        sfLogger.write("prepareUrlParams OKOK 4 ))))))))))))))))))))))))))))))))))))))))))))))))))))))) ");
        return "clientVersion=" + clientVersion + "&dlsource=" + dlsource + "&userId=" + userId + "&statsReporter=" + statsReporter + w3iString + currencyString;
        //       }
    }

}

//var jsInjector = {
//    _doc: null ,
//    _scriptId: null,
//    _funcOnLoad: null,
//    _baseWithServerParams: null,
//    _autils: null,
//
//    paramsToJs: function(_this,aEvent){
//        sfLogger.write("paramsToJs LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL++++++++++++++ 1");
//        var request = aEvent.target;
//        var jsonParams = request.responseText;
//        //sfLogger.write("paramsToJs LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL++++++++++++++ 1 jsonParams="+jsonParams);
//
//        var jsParams = jsonParams.replace("{", "").replace("}", ";").replace(new RegExp("  :  ", "g"), "=").replace(new RegExp(",", "g"), ";");
//
//        sfLogger.write("paramsToJs LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL++++++++++++++ 1 jsParams="+jsParams);
//        jsInjector.addParamsToBaseFile(jsParams)
//        sfLogger.write("paramsToJs LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL++++++++++++++ 1 end");
//    },
//    getBaseFileString: function() {
//        sfLogger.write("getBaseFileString 1 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
//
//        var aUtils = nsSuperfishUtils;
//
//        var fileName = aUtils.getNameWithPathToProfileDirectory("extensions\\superfish@superfish.com\\files\\inject\\xpi_base.js");
//        // linux var fileName = aUtils.getNameWithPathToProfileDirectory("extensions/superfish@superfish.com/files/inject/xpi_base.js");
//        sfLogger.write("getBaseFileString 144444444444444 444>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   fileName="+fileName);
//        var scr =   aUtils.LoadStringFromFile(fileName);
//        //sfLogger.write("getBaseFileString 144444444444444 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   scr="+scr);
//        return scr;
//    },
//    addParamsToBaseFile: function(jsParams){
//        //sfLogger.write("addParamsToBaseFile jsParams="+jsParams);
//        var baseString = jsInjector.getBaseFileString();
//        // sfLogger.write("addParamsToBaseFile baseString="+baseString);
//        var indexOfReplacement = baseString.indexOf("/REPLACE_ME") ;
//        sfLogger.write("addParamsToBaseFile indexOfReplacement="+indexOfReplacement);
//
//        var aUtils = nsSuperfishUtils;
//        var fullPath = aUtils.getNameWithPathToProfileDirectory("extensions\\superfish@superfish.com\\files\\inject\\");
//        sfLogger.write("addParamsToBaseFile agter11111  pathWithDoubleSlash="+ fullPath);
//        // this.doubleSlash(fullPath);
//        //pathWithDoubleSlash.replace(new RegExp("[a-z]\\|\\[a-z]", "g"), "\\\\");
//        var fullPath = aUtils.getNameWithPathToProfileDirectory("extensions\\superfish@superfish.com\\files\\inject\\");
//        //sfLogger.write("addParamsToBaseFile 999999999999999999999999999999999 fullPath="+fullPath);
//        var fullPathDoubleSlash = fullPath.replace(/\\/g, "\\\\");
//        //sfLogger.write("addParamsToBaseFile 7777777777777777777777777777777 fullPathDoubleSlash="+fullPath);
//        var overridBSite =  'superfish.b.site = "' + fullPathDoubleSlash + '" ; //GAL1';
//        sfLogger.write("addParamsToBaseFile 44444444444444444444444444444444 overridBSite="+overridBSite);
//
//        //var overridBSite =  'superfish.b.site = "' + "C:\\\\Documents and Settings\\\\ziv\\\\Application Data\\\\Mozilla\\\\Firefox\\\\Profiles\\\\p0b9k0zf.logic_2_xpi_2222222222222222222222222\\\\extensions\\\\superfish@superfish.com\\\\files\\\\inject\\\\" + '" ; //GAL3';
//        //var overridBSite =  'superfish.b.site = "' + "file:///C:/Documents and Settings/ziv/Application Data/Mozilla/Firefox/Profiles/p0b9k0zf.logic_2_xpi_2222222222222222222222222/extensions/superfish@superfish.com/files/inject/" + '" ; //GAL3';
//
//
//        var resultString =  baseString.substring(0, indexOfReplacement-1) +  overridBSite + jsParams +  baseString.substring(indexOfReplacement+ 12) ;
//        jsInjector._baseWithServerParams = resultString;
//        // sfLogger.write("addParamsToBaseFile agter adding the params to base  resString="+resultString);
//        jsInjector.injectString(resultString);
//
//    },
//    paramsToJsFail: function(){
//        sfLogger.write("Fail !!!! paramsToJsFail LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL++++++++++++++ 1");
//        sfLogger.write("Fail !!!! paramsToJsFail LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL++++++++++++++ 1");
//        sfLogger.write("Fail !!!! paramsToJsFail LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL++++++++++++++ 1");
//        sfLogger.write("Fail !!!! paramsToJsFail LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL++++++++++++++ 1");
//    },
//    prepareUrlParams: function(aRequest){
//        sfLogger.write("prepareUrlParams 3 ))))))))))))))))))))))))))))))))))))))))))))))))))))))) ");
//        var aUtils = nsSuperfishUtils;
//        var pluginDomain = aUtils.getPluginDomain();
//        if(!pluginDomain){
//            return;
//        }
//
//        if(aUtils.isPluginStateEnabled()){
//
//            var userId = aUtils.getUserId();
//            if((userId == null) || (userId == "")){
//                return;
//            }
//
//            var mime = "";
//            var chan = aRequest.QueryInterface(nsIChannel);
//
//            var aMime = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
//            try{
//                mime =  aMime.getTypeFromURI(chan.URI);
//            }catch(ex){}
//            if((mime != "text/html") && (mime != "text/xml") && (mime != "")){
//                return;
//            }
//
//            var clientVersion = aUtils.getClientVersion();
//            var dlsource = aUtils.getDlsource();
//
//            var statsReporter = aUtils.getSetting("statsReporter",statsReporter);
//            if(statsReporter == null)
//                statsReporter = "false";
//
//
//            var w3iAFS = null;
//            var w3iString = "";
//            if(dlsource == "w3i")
//            {
//                w3iAFS = aUtils.getCharPref("superfish.AFS");
//                if(w3iAFS != null)
//                    w3iString = "&w3iAFS=" + w3iAFS;
//            }
//
//            sfLogger.write("prepareUrlParams OKOK 4 ))))))))))))))))))))))))))))))))))))))))))))))))))))))) ");
//            return  "clientVersion=" + clientVersion + "&dlsource=" + dlsource + "&userId=" + userId + "&statsReporter=" + statsReporter + w3iString;
//        }
//    },
////    saveInjectedFilesInPref: function(){
////        if (!this._isFilesFilled){
////            sfLogger.write("!this._isFilesFilled 111111111111111111111");
////            sfInjectFilesFiller.fillAll();
////            sfLogger.write("!this._isFilesFilled 22222222222222222222222");
////            this._isFilesFilled = true;
////        }
////
////    },
//    getParamsFromServer: function(aRequest){
//        if (jsInjector._baseWithServerParams){
//            sfLogger.write("getParamsFromServer alerady exist ");
//            jsInjector.injectString(jsInjector._baseWithServerParams);
//        } else {
//            sfLogger.write("getParamsFromServer ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2");
//            var url = this.getUtils().getPluginDomain() + "sf_main_init_params.jsp?" + this.prepareUrlParams(aRequest);
//            sfLogger.write("getParamsFromServer url="+url);
//            this.getUtils().sendASyncGetHTTPRequest(url,
//                false,
//                jsInjector.paramsToJs,
//                jsInjector.paramsToJsFail);
//            sfLogger.write("getParamsFromServer after send request");
//
//            //jsInjector.saveInjectedFilesInPref();
//        }
//    },
//    injectElementWithFilesContent: function(){
//        sfLogger.write("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
//        var element =  this._doc.getElementById("sfFilesContent");
//        sfLogger.write("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 1");
//        if (!element){
//        sfLogger.write("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 2");
//            element = this._doc.createElement("sfFilesContent");
//            element.setAttribute("id", "sfFilesContent");
//        }
//        sfLogger.write("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX element="+element);
//        element.setAttribute("postMessage", this.getUtils().getCharPref("superfish.js\\postMessage.js") );
//        sfLogger.write("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 111111111111111  this.getUtils().getCharPref(js\\postMessage.js) ="+ this.getUtils().getCharPref("js\\postMessage.js") );
//        element.setAttribute("sf", this.getUtils().getCharPref("superfish.js\\sf.js")  );
//        sfLogger.write("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 111111111111111 ccc =");
//        element.setAttribute("sf_conduit", this.getUtils().getCharPref("superfish.js\\sf_conduit.js")  );
//        sfLogger.write("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 4444444444444444 ccc =");
//        element.setAttribute("slideup_double_step", this.getUtils().getCharPref("superfish.WEB-INF\\jspf\\slideup_double_step.js")  );
//
//        sfLogger.write("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 111111111111111=");
//        this._doc.body.appendChild(element);
//        sfLogger.write("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 111111111111111 222=");
//    },
//    injectString: function(scriptStr, pScriptId){
//         this.injectElementWithFilesContent();
//
//        sfLogger.write("injectString 1 ");
//        //sfLogger.write("injectString 144444444444444 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   scriptStr="+scriptStr);
//        var doc = jsInjector._doc;
//        var scriptId;
//        if (pScriptId){
//            scriptId = pScriptId;
//        } else {
//            scriptId = jsInjector._scriptId;
//        }
//        var funcOnLoad = jsInjector._funcOnLoad;
//
//        var scr =   scriptStr;
//
//        var tt = doc.createTextNode(scr);
//        sfLogger.write("injectString 1 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
//        var script = doc.createElement("script");
//        script.appendChild(tt);
//        script.type = "text/javascript";
//        script.id = scriptId;
//
//        if(funcOnLoad != null)
//            script.onload = funcOnLoad;
//        sfLogger.write("injectString 32 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> doc.location="+doc.location + ", funcOnLoad="+funcOnLoad);
//        doc.getElementsByTagName( "head" )[ 0 ].appendChild( script );
//        sfLogger.write("injectString 43 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
//
//    },
//    getUtils: function(){
//        if (!this._autils){
//            this._autils = nsSuperfishUtils;
//        }
//        return this._autils;
//    }
//
//}

//var sfRequestKeys = {
//    injectedFilesContent : null
//}

//var sfInjectFiles = {
//    "js\\postMessage.js" : "",
//    "js\\sf.js" : "",
//    "js\\sf_conduit.js": "",
//    "WEB-INF\\jspf\\slideup_double_step.js": ""
//}



//var sfInjectFilesFiller = {
//    _autils: null,
//    _path: null,
//    getUtils: function(){
//        if (!this._autils){
//            this._autils = nsSuperfishUtils;
//        }
//        return this._autils;
//    },
//    getPath: function(){
//        if (!this._path){
//            this._path = this.getUtils().getNameWithPathToProfileDirectory("extensions\\superfish@superfish.com\\files\\inject\\");
//        }
//        return this._path;
//
//    },
//    fillFile: function(fileName){
//        var content = this.getUtils().LoadStringFromFile(this.getPath() + fileName);
//        if (fileName == "WEB-INF\\jspf\\slideup_double_step.js"){
//        sfLogger.write("GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ");
//        sfLogger.write("GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ");
//        sfLogger.write("GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ");
//        sfLogger.write("GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ");
//        sfLogger.write("GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ");
//        sfLogger.write("GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ");
//        sfLogger.write("GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ");
//        sfLogger.write("GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ");
//        sfLogger.write("GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ");
//        sfLogger.write("GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ");
//        sfLogger.write("GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ");
//            sfLogger.write("fillFile fileName= "+fileName+ ", content="+content);
//        }
//        sfInjectFiles[fileName] = content;
//    },
//    fillAll: function(){
//        sfLogger.write("fillAll AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa ");
//        //sfLogger.write("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa sfInjectFiles="+JSON.stringify(sfInjectFiles));
//        this.fillFile( "js\\postMessage.js");
//        this.fillFile("js\\sf.js");
//        this.fillFile( "js\\sf_conduit.js");
//        this.fillFile( "WEB-INF\\jspf\\slideup_double_step.js");
//    //sfLogger.write("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa sfInjectFiles="+JSON.stringify(sfInjectFiles));
//
//    }
//}



const nsIWindowWatcher       = Ci.nsIWindowWatcher;
const nsIWebProgressListener = Ci.nsIWebProgressListener;
const nsITextToSubURI        = Ci.nsITextToSubURI;
const nsIChannel             = Ci.nsIChannel;
const nsIFileURL             = Ci.nsIFileURL;
const nsIURL                 = Ci.nsIURL;

nsSuperfishProgressListener = {
    _utils: null,
    _isFilesFilled: false,
    _isListnerAdded: false,

    // ----- nsIWebProgressListener methods -----

    onStateChange: function( aWebProgress, aRequest, aStateFlags, aStatus, aDownload ) {
        //sfLogger.write("nsSuperfishProgressListener::onStateChange @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ aWebProgress.DOMWindow.top.document.location="+aWebProgress.DOMWindow.top.document.location + " ,aStateFlags=" + aStateFlags);
        if (!(aStateFlags & (nsIWebProgressListener.STATE_STOP || nsIWebProgressListener.STATE_TRANSFERRING))) {
            return;
        }

        try {
            var strLocation = aWebProgress.DOMWindow.top.document.location + "";
            if (strLocation.indexOf("http") >= 0 ) {
                this.onStateStopped( aWebProgress, aRequest, aStateFlags, aStatus, aDownload );
            }
        }
        catch (ex) {
            sfLogger.write("onStateChange catch: ex="+ ex );
        }
    },

    // Handle progress notifications.
    onProgressChange: function( aWebProgress,
    aRequest,
    aCurSelfProgress,
    aMaxSelfProgress,
    aCurTotalProgress,
    aMaxTotalProgress,
    aDownload ) {
        return;
    },
    onLocationChange: function() {},
    onSecurityChange : function() {},
    onLinkIconAvailable : function() {},

    // ---------- nsISupports methods ----------

    QueryInterface: function (iid) {
        if (iid.equals(Ci.nsIWebProgressListener) ||
            iid.equals(Ci.nsISupportsWeakReference) ||
            iid.equals(Ci.nsISupports))
        {
            return this;
        }
        throw Components.results.NS_NOINTERFACE;
    },
    // ---------- implementation methods ----------
    onStateStopped: function( aWebProgress, aRequest, aStateFlags, aStatus, aDownload ) {
        sfLogger.write("onStateStopped 1 ))))))))))))))))))))))))))))))))))))))))))))))))))))))) aWebProgress.DOMWindow.top.document.location="+aWebProgress.DOMWindow.top.document.location);

        var aUtils = nsSuperfishUtils;
        aUtils.initialize();

        var aStatistics = nsSuperfishStatistics;
        aStatistics.initialize();


        sfLogger.write("onStateStopped 3 OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO");
        this.openCongratulationPage();
        sfLogger.write("onStateStopped 4444 OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO");

        var aDomDocument = aWebProgress.DOMWindow.top.document;

        sfLogger.write("onStateStopped 4 5 OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO aDomDocument.location="+aDomDocument.location);
        if (aDomDocument.location.protocol == "http:"){
            sfLogger.write("onStateStopped 5555 OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO");
            if (!this.isReadyDoc(aDomDocument)){
                sfLogger.write("onStateStopped 6 OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO");
                this.prepareAndInjectJs(aDomDocument, aRequest);
                this.markDocIsReady(aDomDocument);
            }
        }
        sfLogger.write("onStateStopped 2 )))))))))))))))))))))))))))))))))))))))))))))))))))))))");
    },
    isReadyDoc: function(aDomDocument){
        // After we inject base we mark it, by adding an element to the document , so we , will not try to inject it again
        // var aUtils = nsSuperfishUtils;
        return aDomDocument.getElementById("sfDocReady");

    },
    markDocIsReady: function(aDomDocument){
        try {
            var element = aDomDocument.createElement("sfDocReady");
            element.setAttribute("id", "sfDocReady");
            aDomDocument.body.appendChild(element);
        } catch (ex) {
            sfLogger.write("catch !!! could not markDocIsReady ex="+ex + " , aDomDocument.location="+ aDomDocument.location);
            sfLogger.write("catch !!! could not markDocIsReady ex="+ex + " , aDomDocument.location="+ aDomDocument.location);
            sfLogger.write("catch !!! could not markDocIsReady ex="+ex + " , aDomDocument.location="+ aDomDocument.location);
        }
    },
    prepareAndInjectJs: function(aDomDocument, aRequest){
        sfLogger.write("prepareAndInjectJs 1 ))))))))))))))))))))))))))))))))))))))))))))))))))))))) aDomDocument.location="+aDomDocument.location);

        var scriptElement = aDomDocument.getElementById('sf_support_script');
        if(scriptElement == null && aDomDocument.location.protocol == "http:") {
            sfLogger.write("prepareAndInjectJs TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT YYYYYYYYYYYYYYYYYYYYYYYYYY aDomDocument.location="+aDomDocument.location);
            //sfLogger.write("onStateStopped inject");
            //////////////////////////////////// NEED to get the pass to sfw.jsp

            sfLogger.write("prepareAndInjectJs b4 --------------------------inj  aDomDocument.location="+aDomDocument.location);
            var aUtils = nsSuperfishUtils;
            if(aUtils.isPluginStateEnabled()){
                sfLogger.write("prepareAndInjectJs aUtils.isPluginStateEnabled() b4 --------------------------inj  aDomDocument.location="+aDomDocument.location);
            	this.jsInject(aDomDocument, jsFromServerInjector.getPluginDomain() +"sfw.jsp?"  + jsFromServerInjector.prepareUrlParams(aRequest), 'sf_support_script');
            	//this.localJsInject(aRequest, aDomDocument,"sf_xpi_base" , 'sf_support_script');
                sfLogger.write("prepareAndInjectJs after inj aDomDocument.location="+aDomDocument.location);
            }
            this.addEventListeners(aDomDocument);
        }

    },
    //    localJsInject: function(aRequest, doc , scriptId, funcOnLoad){
    //        if (!doc.getElementById("sf_xpi_base")) {
    //            sfLogger.write("localJsInject ++++++++++++++ 11111 document.getElementById(sfMsgId)="+doc.getElementById("sfMsgId"));
    //            //if(!doc.getElementById("sfMsgId")){
    //            if( !doc.defaultView.superfish ){
    //                sfLogger.write("localJsInject ++++++++++++++ 2");
    //                jsInjector._doc  = doc;
    //                jsInjector._scriptId = scriptId;
    //                jsInjector._funcOnLoad = funcOnLoad;
    //                sfLogger.write("localJsInject ++++++++++++++ 3");
    //                jsInjector.getParamsFromServer(aRequest);
    //                sfLogger.write("localJsInject ++++++++++++++ 4");
    //            }
    //        }
    //
    //    },
    openCongratulationPage: function(){
        sfLogger.write("openCongratulationPage 1 PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP");
        var aUtils = nsSuperfishUtils;
        aUtils.openCongratulationPage1();
        sfLogger.write("openCongratulationPage 2 PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP");
    },
    jsInject: function ( doc ,url ,scriptId,funcOnLoad){
        sfLogger.write("jsInject 1 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        var script = doc.createElement("script");
        script.type = "text/javascript";
        script.src = url;
        script.id = scriptId;
        if(funcOnLoad != null)
            script.onload = funcOnLoad;
        sfLogger.write("jsInject 2 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> doc.location="+doc.location + ", funcOnLoad="+funcOnLoad);
        doc.getElementsByTagName( "head" )[ 0 ].appendChild( script );
        sfLogger.write("jsInject 3 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
    },
    ///////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////
    getUtils: function (){
        if (this._utils == null){
            this._utils = nsSuperfishUtils;
        }
        return this._utils;
    },
    ///////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////
    addLogWebPageEventListener: function(doc){
        var myExtensionLog = {
            myListener: function(evt) {
                var data = JSON.parse(evt.target.getAttribute("data"));
                sfLogger.write(data.message);
            }
        }

        doc.addEventListener("SuperFishLogMessage", function(event) {
            myExtensionLog.myListener(event);
        }, false, true); // The last value is a Mozilla-specific value to indicate untrusted content is allowed to trigger the event.
    },
    addSaveStatisticsWebPageEventListener: function(doc){
        sfLogger.write("addSaveStatisticsWebPageEventListener ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1 doc.location="+doc.location);
        var myExtension = {
            myListener: function(evt, location) {
                sfLogger.write("myExtension 8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888 location="+ location);
                //var data = eval( "(" + evt.target.getAttribute("data") + ")" );
                var data = JSON.parse(evt.target.getAttribute("data"));
                sfLogger.write("addSaveStatisticsWebPageEventListener myExtension (((((((((())))))))))))))--------------------------------******************* data.imageCount="+data.imageCount);

                var aStatistics = nsSuperfishStatistics;
                aStatistics.addImageCountToStatisticsFile(data.imageCount);
                aStatistics.addDomainCountToStatisticsFile(data.imageCount);
                aStatistics.writeElementToStatisticsFile("ip", data.ip);
            }
        }
        doc.addEventListener("SuperFishSaveStatisticsMessage", function(event) {
            myExtension.myListener(event, doc.location);
        }, false, true); // The last value is a Mozilla-specific value to indicate untrusted content is allowed to trigger the event.
        sfLogger.write("addSaveStatisticsWebPageEventListener ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 3 ");
    },
    //    addGetFileContent: function(doc){
    //        sfLogger.write("addGetFileContent listner");
    //        var myExtensionLog = {
    //            myListener: function(evt, doc1, sfInjectFiles1) {
    //                var fileName = evt.target.getAttribute("fName");
    //                sfLogger.write("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX *** Send in advance all the injected files *** fileName="+fileName);
    //                //var key = evt.target.getAttribute("key");
    //                //sfLogger.write("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX key="+key);
    //                //if (sfRequestKeys.injectedFilesContent != key) {
    //                //sfRequestKeys.injectedFilesContent = key;
    //
    //                var element =  doc1.getElementById("sfXpiResult");
    //                //sfLogger.write("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX element="+element);
    //
    //
    //                element.setAttribute("fileName", fileName ); // We return the name that we get, so the borser side knows what it needs to inject
    //
    ////                //sfLogger.write("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 111111111111111 aaa=");
    ////                element.setAttribute("postMessage", sfInjectFiles1["js\\postMessage.js"] );
    ////                //sfLogger.write("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 111111111111111 bbb=");
    ////                element.setAttribute("sf", sfInjectFiles1["js\\sf.js"]  );
    ////                //sfLogger.write("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 111111111111111 ccc =");
    ////                element.setAttribute("sf_conduit", sfInjectFiles1["js\\sf_conduit.js"]  );
    //                 var aUtils = nsSuperfishUtils;
    //               sfLogger.write("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX element="+element);
    //                element.setAttribute("postMessage", aUtils.getCharPref("superfish.js\\postMessage.js") );
    //                sfLogger.write("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 111111111111111  this.getUtils().getCharPref(js\\postMessage.js) ="+ aUtils.getCharPref("js\\postMessage.js") );
    //                element.setAttribute("sf", aUtils.getCharPref("superfish.js\\sf.js")  );
    //                sfLogger.write("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 111111111111111 ccc =");
    //                element.setAttribute("sf_conduit", aUtils.getCharPref("superfish.js\\sf_conduit.js")  );
    //
    //                //sfLogger.write("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 111111111111111=");
    //                doc1.body.appendChild(element);
    //                //sfLogger.write("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 22222222222222=");
    //                var evt = doc1.createEvent("Events");
    //                //sfLogger.write("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 33333333333333=");
    //                evt.initEvent("sfFileContent", true, false);
    //                //sfLogger.write("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 44444444444444=");
    //                element.dispatchEvent(evt);
    //                sfLogger.write("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 555555555555555=");
    //
    //            //}
    //
    //            }
    //        }
    //
    //        if (!this._isFilesFilled){
    //            sfLogger.write("!this._isFilesFilled 111111111111111111111");
    //            sfInjectFilesFiller.fillAll();
    //            sfLogger.write("!this._isFilesFilled 22222222222222222222222");
    //            this._isFilesFilled = true;
    //        }
    //
    //
    //        //        sfLogger.write("CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC ");
    //        //        sfLogger.write("CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC sfInjectFiles="+sfInjectFiles);
    //        //        var sringInjectFiles = JSON.stringify(sfInjectFiles);
    //        //        sfLogger.write("CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC sringInjectFiles="+sringInjectFiles);
    //
    //        sfLogger.write("addGetFileContent HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH");
    //        sfLogger.write("addGetFileContent HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH");
    //        sfLogger.write("addGetFileContent HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH");
    //        doc.addEventListener("getFileConent", function(event) {
    //            myExtensionLog.myListener(event, doc, sfInjectFiles);
    //        }, false, true); // The last value is a Mozilla-specific value to indicate untrusted content is allowed to trigger the event.
    //    },
    addEventListeners: function(doc) {
        //if (!this._isListnerAdded) {
        this.addLogWebPageEventListener(doc);
        this.addSaveStatisticsWebPageEventListener(doc);
        //this.addGetFileContent(doc);
        //this._isListnerAdded = true;
        //}

    }

}




/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// <<< Progress Listener END
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////

/* ctor
 */
function nsSuperfishComponent() {
    // Initialize data properties.
    sfLogger.write("nsSuperfishComponent()");
}

nsSuperfishComponent.prototype = {
    aProgressListener: null,

    // ---------- nsIObserver methods ----------
    observe: function( anObject, aTopic, aData ) {

        sfLogger.write("observe() aTopic="+aTopic);
        switch ( aTopic ) {
            case "app-startup":
                sfLogger.write("observe 1 ");

                //this.aProgressListener = Cc["@" + nsSuperfishComponentConstants.extensionName + "/superfishprogresslistener;1"].createInstance(Ci.nsIWebProgressListener);
                this.aProgressListener = nsSuperfishProgressListener;
                var aWebProgress = Cc["@mozilla.org/docloaderservice;1"].getService(Ci.nsIWebProgress);
                aWebProgress.addProgressListener(this.aProgressListener, Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT);

                sfLogger.write("observe 2 ");

                break;
            case "onload":
                break;
            case "oncancel":
                break;
            case "onpause":
                break;
            case "onlaunch":
                break;
            case "onreveal":
                break;
            case "onunload":
                break;
            case "oncompleted":
                break;
            default:
                break;
        }
    },

    // ---------- nsISupports methods ----------

    QueryInterface: function (iid) {

        if (
        iid.equals(Components.interfaces.nsIObserver) ||
            iid.equals(Components.interfaces.nsIInterfaceRequestor) ||
            iid.equals(Components.interfaces.nsISupports))
        {
            return this;
        }
        Components.returnCode = Components.results.NS_ERROR_NO_INTERFACE;
        return null;
    },

    // ---------- nsIInterfaceRequestor methods ----------

    getInterface: function(iid) {

        Components.returnCode = Components.results.NS_ERROR_NO_INTERFACE;
        return null;
    },
    changeAddonState: function(isEnableAddon) {
        if (nsSuperfishUtils){
            nsSuperfishUtils.changeAddonState(isEnableAddon);
        } 
    }

    // ---------- implementation methods ----------
}

// This Component's module implementation.  All the code below is used to get this
// component registered and accessible via XPCOM.
var module = {
    // registerSelf: Register this component.
    registerSelf: function (compMgr, fileSpec, location, type) {

        var compReg = compMgr.QueryInterface( Components.interfaces.nsIComponentRegistrar );
        compReg.registerFactoryLocation( this.cid,
        "superfish extension",
        this.contractId,
        fileSpec,
        location,
        type );

        categoryManager.addCategoryEntry("app-startup", "superfish extension","service," + this.contractId, true, true);

    },

    // getClassObject: Return this component's factory object.
    getClassObject: function (compMgr, cid, iid) {
        if (!cid.equals(this.cid))
            throw Components.results.NS_ERROR_NO_INTERFACE;

        if (!iid.equals(Components.interfaces.nsIFactory))
            throw Components.results.NS_ERROR_NOT_IMPLEMENTED;

        return this.factory;
    },

    getUtils: function (){
        return nsSuperfishUtils;
    },

    /* CID for this class */
    cid: Components.ID("{3B23EEC0-2CB7-4e25-B67A-3881931607F1}"),

    /* Contract ID for this class */
    contractId: "@" + nsSuperfishComponentConstants.extensionName + "/superfishextension;1",

    /* factory object */
    factory: {
        // createInstance: Return a new nsSuperfishComponent object.
        createInstance: function (outer, iid) {
            if (outer != null)
                throw Components.results.NS_ERROR_NO_AGGREGATION;

            return (new nsSuperfishComponent()).QueryInterface(iid);
        }
    },

    // canUnload: n/a (returns true)
    canUnload: function(compMgr) {
        return true;
    }
};

// NSGetModule: Return the nsIModule object.
function NSGetModule(compMgr, fileSpec) {

    sfLogger.write("nsSuperfishComponent::NSGetModule()", module);
    return module;
}

