function URL(){
    if (!window.URLListeners)window.URLListeners = [];
    var nID = window.URLListeners.length;
    
    var _URLListener = window.URLListeners[nID] = {
        onHrefChange:function (sHref){},
        onPathnameChange:function (sPath){},
        onSearchChange:function (sSearch){},
        onHashChange:function (sHash){},
        _id:nID,
        _href:"",
        _pathname:"",
        _search:"",
        _hash:"",
        _timer:10,
        _listenerID:0,
        _listener:function (){
            if (this._listenerID) clearInterval(this._listenerID);
            if (this._href != location.href) this.onHrefChange(this._href = location.href);
            if (this._pathname != location.pathname) this.onPathnameChange(this._pathname = location.pathname);
            if (this._search != location.search) this.onSearchChange(this._search = location.search);
            if (this._hash != location.hash) this.onHashChange(this._hash = location.hash);
            this._listenerID = setTimeout("window.URLListeners[" + nID + "]._listener()", _URLListener._timer);
        }
    }
    _URLListener._listenerID = setTimeout("window.URLListeners[" + nID + "]._listener()", 0);
    return _URLListener;
}
if (!this.url) this.url = URL();

function Service(){
    return {
        onLoad:function (sContent){
            // alert("Service Content: " + oContent); 
        },
        onStateChange:function (nPhase){ 
            // alert("Service Phase: " + nPhase); 
        },
        onError:function (nError){ 
            // alert("Service Error: " + nError); 
        },
        load:function (sURL, sMethod){
            if (!sURL) return;
            if (sMethod.toUpperCase() != "POST") sMethod = "GET";
            //
            if (window.XMLHttpRequest) this._oConnector = new XMLHttpRequest();
            else this._oConnector = new ActiveXObject("Microsoft.XMLHTTP");
            this._nState = 0;
            this._oConnector.caller = this;
            this._oConnector.onreadystatechange = this._listenState;
            this._oConnector.open(sMethod, sURL, true);
            this._oConnector.send(null);
            // alert(this._oConnector)
        },
        _oConnector:null,
        _nState:0,
        _listenState:function (){
            if (this.caller._nState != this.readyState) {
                this.caller.onStateChange(this.caller._nState = this.readyState);
                if ( this.caller._nState == 4 ) {
                    if (this.status != 200){ this.caller.onError(this.status); return; }
                    this.caller.onLoad(this.responseText);
                }
            }
        }
    }
}
if (!this.service) this.service = Service();

function Bookmark(SiteName){
    var isFF = (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length);
    var isOP = (window.opera && window.print);
    //
    if( isOP ) { return true; }    
    else if( isFF ) { window.sidebar.addPanel(SiteName, location.href, ""); } 
    else {  window.external.AddFavorite(location.href, SiteName); } 
}
