<html><head><style type="text/css"><!-- DIV {margin:0px;} --></style></head><body><div style="font-family:arial, helvetica, sans-serif;font-size:12pt;color:#000000;"><avglsdata id=avglsdata></avglsdata> 
<DIV></DIV>
<DIV>I don't mind some rules for this list, but I am frequently getting a message saying that my replies have to be moderated because they are too big. I have gotten two today that saif the messages were well over the 80KB limit. This is interesting because looking at my "Sent" folder, neither was over 20KB. Does anyone know why this discrepancy is&nbsp;happening? Despite my email address, this is Yahoo Mail.<BR>&nbsp;</DIV>
<P><FONT color=#ff007f size=4 face="bookman old style, new york, times, serif"><EM><STRONG>Nancy</STRONG></EM></FONT></P>
<P>&nbsp;</P>
<P><FONT face="arial, helvetica, sans-serif">Injustice anywhere is a threat to justice everywhere. -- Dr. Martin L. King, Jr.</FONT></P>
<DIV></DIV><!-- cg6.c204.mail.gq1.yahoo.com compressed/chunked Mon Mar 28 10:39:30 UTC 2011 -->
<SCRIPT type=text/javascript>///////////    SEARCH MONITOR    ///////////
setTimeout(function(){searchshield.init(document);},1000);


////////////////    SEARCH    ////////////////

// Initialize namespace, use existing context
var searchshield = searchshield || {};

searchshield.clockUrl;

// constants
searchshield.SCORE_SS_SAFE                = 1;
searchshield.SCORE_SS_CAUTION        = 2;
searchshield.SCORE_SS_WARNING        = 3;
searchshield.SCORE_SS_BLOCK                = 4;
searchshield.SCORE_SS_VERISIGN        = 7;

searchshield.BLOCK_NONE                = 0;
searchshield.BLOCK_NORMAL        = 1;
searchshield.BLOCK_PHISH        = 2;
searchshield.BLOCK_YAHOO        = 3;

searchshield.XPLCHECK_RESULT_SEV_NONE        = 0;
searchshield.XPLCHECK_RESULT_SEV_LOW        = 1;
searchshield.XPLCHECK_RESULT_SEV_MED        = 2;
searchshield.XPLCHECK_RESULT_SEV_BLOCK        = 3;

searchshield.VERISIGN_SPLIT_NOTEST                = 0;
searchshield.VERISIGN_SPLIT_TESTA                = 1;
searchshield.VERISIGN_SPLIT_TESTB                = 2;

searchshield.allowedSites = [];

searchshield.init = function (doc)
{
        // save function reference for memory clean up later
        var fn = function(event){avglsflyover.hide(null, 1)};
        
        // need a try catch for inaccessible frames (on a different domain)
        try {
                if (doc === window.top.document)
                {
                        //hide flyover if these events occur
                        window.detachEvent('onscroll', fn);
                        window.attachEvent('onscroll', fn);

                        doc.detachEvent('onkeydown', fn);
                        doc.attachEvent('onkeydown', fn);

                        // only start monitor on top doc
                        searchshield.avgPageMonitor.start(doc);
                }
        }
        catch(err){}

        return;
};

// search monitors and processors 
searchshield.avgPageMonitor = {
        start: function(doc){
                searchshield.avgSearchMonitor.stop();
                searchshield.avgPageMonitor.stop();
                searchshield.avgPageMonitor.process(doc);
                if (!searchshield.avgSearchMonitor.timeoutID)
                        searchshield.avgPageMonitor.timeoutID = window.setTimeout(function(){searchshield.avgPageMonitor.start(doc)}, 1000);
        },
        process: function(doc){
                searchshield.avgProcessSearch(doc);
        },
        stop: function(){
                if (searchshield.avgPageMonitor.timeoutID)
                {
                        window.clearTimeout(searchshield.avgPageMonitor.timeoutID);
                        delete searchshield.avgPageMonitor.timeoutID;
                }
        }
};
searchshield.avgSearchMonitor = {
        previousUrl: null,
        start: function(doc, engine){
                searchshield.avgPageMonitor.stop();
                searchshield.avgSearchMonitor.stop();
                searchshield.avgSearchMonitor.process(doc, engine);
                if (!searchshield.avgPageMonitor.timeoutID)
                        searchshield.avgSearchMonitor.timeoutID = window.setTimeout(function(){searchshield.avgSearchMonitor.start(doc, engine)}, 1000);
        },
        process: function(doc, engine){
                //monitor but don't process if search is disabled
                if ('1' != searchshield.avgCallFunc(doc, 'GetSearchEnabled'))
                        return;

                // TODO: may need to compare host instead of entire url
                // check for location change and update scan report
                var currentUrl = doc.location.href;
                if (searchshield.avgSearchMonitor.previousUrl != currentUrl)
                {
                        //report scan result
                        searchshield.avgSearchMonitor.previousUrl = currentUrl;
                        avgreport.scanResult(doc, currentUrl);
                }
                
                engine.search.links = [];
                var links = searchshield.avgGetSearchLinks(doc, engine);

                // when there are new links make sure flyover is hidden
                if (links.length > 0)
                        avglsflyover.hide(null, 1);

                var phishLinks = [];
                for (var i=0; i < links.length; i++)
                {
                        var isPhishing = searchshield.avglsCheckandUpdate(links[i], engine);
                        if (!!isPhishing)
                        {
                                phishLinks.push(links[i]);
                        }
                }
                
                if (phishLinks.length > 0)
                {
                    var prev = '1';
                    if ( engine.type == 'inline' )
                        prev = '0';
                        searchshield.avgCallFunc(doc, 'GetPhishingResults', prev);
                }
                else if (links.length > 0 && engine.type != 'inline')
                {
                        searchshield.avgCallFunc(doc, 'FinalScanComplete');
                }
        },
        stop: function(){
                if (searchshield.avgSearchMonitor.timeoutID)
                {
                        window.clearTimeout(searchshield.avgSearchMonitor.timeoutID);
                        delete searchshield.avgSearchMonitor.timeoutID;
                }
        }
};
searchshield.avgProcessSearch = function (doc)
{
        // doc may be about:Tabs or about:Blank
        if (!doc)
                return;

        // init search object (not declared or is null)
        if (typeof xplSearch === 'undefined' || null === xplSearch)
                xplSearch = new searchshield.Search();

        xplSearch.doc = doc;
        xplSearch.href        = xplSearch.doc.location.href;
        xplSearch.uri        = searchshield.parseLink(xplSearch.href);
        
        if (!searchshield.clockUrl)
                searchshield.clockUrl = searchshield.avgCallFunc(doc, 'GetIconUrl', '0');
                
        xplSearch.clockUrl = searchshield.clockUrl
        
        if (!xplSearch.engines)
        {
                var aEng = xplSearch.getSearchNames();
                var aEngLen = aEng.length;
                for (var i=0; i < aEngLen; i++)
                {
                        xplSearch.addEngine(new searchshield[aEng[i]+'SearchEngine'](xplSearch));
                }
        }
        
        if (!xplSearch.engine)
        {
                var engLen = xplSearch.engines.length;
                for (var i = 0; i < engLen; i++)
                {
                        if (xplSearch.engines[i].validSearch())
                        {
                                xplSearch.engine = xplSearch.engines[i];
                                break;
                        }
                }
        }

        if (!xplSearch.engine)
                return;
        
        // set verdict display config
        xplSearch.engine.setRatingsConfig(doc);

        // init the alert popup
        searchshield.initPopupAlert(doc);

        // start search monitor
        searchshield.avgSearchMonitor.start(doc, xplSearch.engine);
        
        // attach click handlers for popup alerts
        doc.body.detachEvent("onclick", searchshield.blockClick);
        doc.body.attachEvent("onclick", searchshield.blockClick);
        
        doc.body.detachEvent("ondblclick", searchshield.blockClick);
        doc.body.attachEvent("ondblclick", searchshield.blockClick);
};
searchshield.avgGetSearchLinks = function (doc, engine)
{
        if (!engine)
        {
                // restart page monitor
                searchshield.avgPageMonitor.start(doc);
                return;
        }

        var alltags = doc.getElementsByTagName('*');
        
        for (var i = 0; i < alltags.length; i++)
        {
                if (alltags[i].getAttribute('avglschecked'))
                        continue;
                
                // ignore linked resources
                if ((alltags[i].tagName) && (alltags[i].tagName == 'LINK'))
                        continue;

                // ignore in-page bookmarks and javascript
                if ((!alltags[i].href)        ||
                        (alltags[i].href.charAt(0) == '#') ||        // in-page bookmark
                        (alltags[i].href.indexOf("javascript") == 0))
                        continue;
                        
                // ignore verdicts
                if (alltags[i].id && (alltags[i].id.indexOf("XPLSS_") != -1))
                        continue;

                // ignore flyover anchors
                if (alltags[i].href && (alltags[i].href.indexOf("linkscanner:") == 0 || alltags[i].href.indexOf("avgthreatlabs.com") != -1))
                        continue;
                        
                var href = engine.includeLink(alltags[i]);
                if (!href)
                        continue;
                
                var newNode = engine.search.addLink(alltags[i], href);
                engine.addImage(newNode, engine.search.clockUrl, false);
        }
        
        // recursivesly process all frames
        var docFrames = doc.frames;
        if (docFrames && engine.processFrames)
        {
                for (var j = 0; j < docFrames.length; j++)
                {
                        var attr;
                        var frameDoc;
                        try {
                                attr = docFrames[j].frameElement.className;
                                frameDoc = docFrames[j].document;
                        }
                        catch(err){}

                        //TODO: make frame processing an engine function or at least make exclusions an engine property
                        // 'editable' frame it's probably a gmail reply
                        if (attr && (attr.indexOf("editable") != -1))
                                continue;

                        if (frameDoc)
                                searchshield.avgGetSearchLinks(frameDoc, engine);
                }
        }
        
        return engine.search.links;
};
searchshield.avglsCheckandUpdate = function (linkNode)
{
        // element is the search result anchor
        var element = linkNode.element;
        var href = linkNode.href;

        if (!xplSearch)
                return;

        var result = searchshield.avgCallFunc(xplSearch.doc, 'CheckSite', href, element.href);
        if (result == null)
                return;
        
        var resultParse = result.split('::');

        var phishing  = resultParse[0];  // if phishing then rest of array does not exist.

        if (phishing == 1)
                return true;

        if (resultParse.length < 8)
                return;
        
        var hash          = resultParse[1];
        var score          = resultParse[2];
        var new_image = resultParse[3];
        var alt_image = resultParse[4];
        var flyover          = resultParse[5];
        var click_thru= resultParse[6];
        var altClick_thru = resultParse[7];

        // iterate to get verdict anchor
        nextElem = element.nextSibling;
        while (nextElem)
        {
                if (nextElem.nodeType == 1 && nextElem.id && (nextElem.id.indexOf("XPLSS_") != -1))
                        break;

                nextElem = nextElem.nextSibling;
        }
        
        xplSearch.engine.updateImage(hash, xplSearch.searchHash, score, new_image, alt_image, flyover, click_thru, altClick_thru);
};

// click event handler - shows popup for links of caution and warning severity
searchshield.blockClick = function(event)
{
        if (!event)
                event = window.event;
                
        // no action needed if click is not the left mouse button
        if (event.button != 0)
                return;
                
        var anchor = searchshield.getAnchorNode(event.srcElement, 
                                                                function(node) {return ((node.tagName.charAt(0) == "H") ||
                                                                                                                (node.tagName.charAt(0) == "D") ||
                                                                                                                (node.tagName.charAt(0) == "T"))}        );
        
        if ((anchor == null) || (anchor.href == null))
                return true;
        
        // ignore if anchor is on an xpl verdict
        if (!!anchor.id)
        {
                if (anchor.id.indexOf('LXPLSS_') == 0)
                        return true;
                
                if (anchor.id.indexOf('XPLSS_INTR') == 0)
                {
                        searchshield.allowedSites.push(searchshield.GetDomain(anchor.href))
                        return true;
                }
        }
        
        // VeriSign A/B Split reporting - only for VerSign domains
        var avglschecked = anchor.getAttribute("avglschecked");
        if (avglschecked && avglschecked != 1)
        {
                var sPos = avglschecked.indexOf("S");
                var hash = (sPos > -1) ? avglschecked.substring(0, sPos) : null;
                var split = (sPos > -1) ? avglschecked.substring(sPos+1) : null;
                if (hash && split && split != searchshield.VERISIGN_SPLIT_NOTEST)
                {
                        // check updated verdict anchor for verisign domain
                        var d = event.srcElement.ownerDocument;
                        if (d.getElementById("LXPLSS_" + hash + "U" + searchshield.SCORE_SS_VERISIGN))
                        {
                                searchshield.avgCallFunc(d, "RecordVSClick", hash, d.location.href);
                        }
                }
        }

        var link = anchor.href;
        var verdict = searchshield.getAvgImage(anchor);
        var score = -1;
        var img_id = '';
        if (verdict != null)
        {
                score = verdict.score;
                img_id = verdict.rawId;
        }
        
        // show popup alert (upper left)
        if ((score >= searchshield.SCORE_SS_CAUTION) && (score <= searchshield.SCORE_SS_WARNING))
        {
                // prevent this click from going any further
                var search_hash = searchshield.avgCallFunc(document, 'GetHash', document.location.href);
                searchshield.ShowPopupAlert(document, link, img_id, search_hash);

                // if possible, stop the event from going any further
                searchshield.cancelEvent(event);
                return false;
        }
        
        return true;
};

// called by native to update phishing links
searchshield.updatePhishingLinks = function (results)
{

        if (!results)
                return;

        if (!xplSearch)
                return;

        var engine = xplSearch.engine;
        var resultParse = results.split("::");
        var resultsLength = resultParse[0];

        for (var i=0; i < resultsLength; i++)
        {
                var idx = i*7;
                var hash          = resultParse[idx+1];
                var score          = resultParse[idx+2];
                var new_image = resultParse[idx+3];
                var alt_image = resultParse[idx+4];
                var flyover          = resultParse[idx+5];
                var click_thru= resultParse[idx+6];
                var altClick_thru = resultParse[idx+7];

                engine.updateImage(hash, xplSearch.searchHash, score, new_image, alt_image, flyover, click_thru, altClick_thru);
        }
};
searchshield.getAvgImage = function (element)
{
        var obj = {};
        obj.img = xplSearch.engine.getImgElement(element);
        obj.score = -1;
        
        //parse the score from the id
        if (obj.img != null && obj.img.id)
        {
                var pos = !!obj.img.id ? obj.img.id.indexOf('U') + 1 : -1;
                obj.score = (pos < 1) ? -1 : obj.img.id.charAt(pos);
                obj.rawId = obj.img.id.substring(0,pos-1);
        }
        
        return obj;
};
searchshield.GetScannedLink = function (link)
{
        if (!xplSearch || !(xplSearch.links instanceof Array))
                return link;

        // look for the link we scanned based on original element
        for (var i = 0; i < xplSearch.links.length; i++)
        {
                if (xplSearch.links[i].element.href == link)
                        return xplSearch.links[i].href;
        }
        // else return the incoming link
        return link;
};
searchshield.previouslyScanned = function (links, hash)
{
        for (var i = 0; i < links.length; i++)
        {
                if ((links[i] != null) && (links[i].hash != null) && 
                        (links[i].hash == hash) && (links[i].checked == true))
                        return true;
        }
        return false;
};
searchshield.initPopupAlert = function (doc)
{
        // check if it exists first
        if (doc.getElementById("XPLSS_PopupAlert"))
                return;

        // create a div to use for the popup itself, hide for now
        var popup_div = doc.createElement("DIV");
        popup_div.setAttribute("id", "XPLSS_PopupAlert");
        popup_div.style.position = "absolute";
        popup_div.style.zIndex = "10000";
        doc.body.appendChild(popup_div);
};
searchshield.initFlyover = function (doc, engine)
{
        // create in top doc only
        if (doc !== window.top.document)
                doc = window.top.document;

        // check if it exists first
        if ((doc == null) || (doc.getElementById("XPLSS_Flyover")))
                return;

        // create a div to use for the flyover itself, hide for now
        var flyover_div = doc.createElement("DIV");
        flyover_div.setAttribute("id", "XPLSS_Flyover");
        flyover_div.style.position = "absolute";
        flyover_div.style.zIndex = "10000";
        doc.body.appendChild(flyover_div);

        // create a layer for the image
        var trans_div = doc.createElement("DIV");
        trans_div.setAttribute("id", "XPLSS_Trans");
        trans_div.style.position = "absolute";
        trans_div.style.zIndex = "9999";
        doc.body.appendChild(trans_div);
};
searchshield.ShowPopupAlert = function (doc, link, hash, search)
{
        // build the content
        var popup_content = searchshield.avgCallFunc(doc, 'BuildPopupAlert', hash, search);
        if (popup_content == null || popup_content == "")
                return;

        // get the div
        var div = doc.getElementById("XPLSS_PopupAlert");
        div.innerHTML = searchshield.CleanupHTML(popup_content);

        // set position, account for scrolling
        var zoom = searchshield.zoomLevel();
        var pageOffsetX = Math.round(doc.documentElement.scrollLeft/zoom);
        var pageOffsetY = Math.round(doc.documentElement.scrollTop/zoom);
        
        div.style.left = 10 + pageOffsetX + "px";
        div.style.top = 10 + pageOffsetY + "px";
        
        // TODO: the event handler function doesn't exist so, is this even necessary?
        //div.attachEvent("onmouseout", HidePopupAlert);

        // set the link
        //var data = doc.getElementById("avgalertpopurl");
        //if (data)
        //                data.innerHTML = escape(link);

        // set visibility
        div.style.visibility = "visible";

        //navigate to the link after timed delay
        // TODO: Bug 31707 - make this open a new tab/window
        setTimeout(function(){doc.location.assign(link)}, 3000);
};
searchshield.avgCallFunc = function (doc, name /*, param1..., paramN*/)
{
        // get the data element
        var avg_ls_data = (typeof gAvgDataElement !== 'undefined') ? gAvgDataElement : doc.getElementById("avglsdata");

        if ((avg_ls_data == null) || (name == null))
                return;
        
        // save the data element
        gAvgDataElement = avg_ls_data;

        // for some reason you can't fire and event on an element with no parent node
        if (avg_ls_data.parentNode == null)
                return;

        // set the attributes
        avg_ls_data.setAttribute("function", name);
        
        // set variable length of optional parameter attributes
        var pcnt = 0;
        for (var i=2; i < arguments.length; i++)
                avg_ls_data.setAttribute("param"+(++pcnt), arguments[i]);

        avg_ls_data.fireEvent("onrowenter");

        // get the result
        return avg_ls_data.getAttribute("result");        
};

// general use functions - begin
// DOM Functions
searchshield.getAnchorNode = function (node, filterFunc)
{
        // filterFunc should return a boolean
        if (!filterFunc || !filterFunc instanceof Function)
                return null;
                
        // go up the dom tree starting at node and look for anchor 
        // before hitting a header, div or table element 
        while ((node != null)                        &&
                        (node.tagName != null)        && 
                        (node.tagName != "A"))
        {
                if (filterFunc(node))
                {
                        node = null;
                        break;
                }
                node = node.parentNode;
        }

        return node;
};
searchshield.getDocuments = function (frame, frameArray)
{        // recursively get all embedded frames/docs
        frameArray.push(frame.document);
        var frames = frame.frames;
        for (var i = 0; i < frames.length; i++)
        {
                // recurse on each frame
                searchshield.getDocuments(frames[i], frameArray);
        }
        return frameArray;
};
searchshield.NextSiblingNode = function (element)
{
        var TEXTNODE = 3;
        var ParentNode = element.parentNode;

        if (!ParentNode)
                return;

        var NextSibling = ParentNode.nextSibling;
        while (NextSibling)
        {
                if (NextSibling.nodeType != TEXTNODE)
                        return NextSibling;

                NextSibling = NextSibling.nextSibling;
        }

        return;
};
searchshield.getParentNodeByAttribute = function (attrName, attrValue, node, maxDepth)
{
        if (!node)
                return null;
        
        var maxLoop = maxDepth ? maxDepth : 1;
        var pNode = node.parentNode;
        
        if (!pNode)
                return null;
        
        for(; 0 < maxLoop; maxLoop--) 
        {
                if ((pNode[attrName]) && 
                        (pNode[attrName].toLowerCase() === attrValue.toLowerCase())) 
                {
                        return pNode;
                }

                pNode = pNode.parentNode;
                if (!pNode)
                        return null;
        }

        return null;
};
searchshield.getParentNodeByClassName = function (className, node, maxDepth) 
{
        return searchshield.getParentNodeByAttribute("className", className, node, maxDepth);
};
searchshield.getParentNodeById = function (id, node, maxDepth)
{
        return searchshield.getParentNodeByAttribute("id", id, node, maxDepth);
};
searchshield.getParentNodeByTagName = function (tagName, node, attrName) 
{        // find parent node by tag name and optional attribute name

        if (!tagName || !node || !node.parentNode)
                return null;
        
        tagName = tagName.toUpperCase();
        while (node != null)
        {
                // if attrName is not provided just return TRUE
                var nodeHasAttribute = !!attrName ? !!node[attrName] : true;
                if ((node.tagName == tagName) && (nodeHasAttribute))
                        return node;
                
                node = node.parentNode;
        }
        
        // no div
        return null;
};
searchshield.getTopLevelDocument = function (doc)
{        // return the top level document for the given doc, could be itself

        // TODO: determine a method of doing this for IE, if necessary
        
        // don't check about:blank
        if (doc && (doc.location.href == "about:blank"))
                return doc;

        // Check if already a top level document
        for (var i = 0; i < gBrowser.browsers.length; i++)
        {
                if (doc == gBrowser.browsers[i].contentDocument)
                        return doc;
        }

        // Not a top level, check all frames 
        var documents;
        for (var j = 0; j < gBrowser.browsers.length; j++)
        {
                // get all docs for each browser
                documents = searchshield.getDocuments(gBrowser.browsers[j].contentWindow, new Array());
                for (var k = 0; k < documents.length; k++)
                {
                        // check if doc is from current browser
                        if (doc == documents[k])
                        {
                                // it is, return the top level doc for this browser
                                return gBrowser.browsers[j].contentDocument;
                        }
                }
        }
        
        return doc;
};
searchshield.getTopLevelWindow = function ()
{
        // TODO: determine a method of doing this for IE, if necessary
        return mediator.getMostRecentWindow("navigator:browser");
};

//Event functions
searchshield.addListener = function (object, evtType, listener, useCapture)
{
        useCapture = !!useCapture;

        if (object.addEventListener)
        {
                object.addEventListener(evtType, listener, useCapture);
                return true;
        }
        else if (object.attachEvent)
        {
                 object.attachEvent("on"+evtType, listener);
                 return true;
        }
        
        return false;
};
searchshield.cancelEvent = function (event)
{
        event.cancelBubble = true;
        event.returnValue = false;
};
searchshield.doEvent = function (evtObj, evtTarget, evtName, evtType, bubbles, cancelable)
{
        bubbles                = !!bubbles;
        cancelable        = !!cancelable;
        
        if (document.createEvent)
        {
                var evt = document.createEvent("Events");
                evt.initEvent(evtName, bubbles, cancelable);
                evtTarget.dispatchEvent(evt);
                return true;
        }
        else if (document.createEventObject)
        {
                var evt = document.createEventObject(evtObj);
                evtTarget.fireEvent("on" + evtType, evt);
                return true;
        }
        
        return false;
};
searchshield.removeListener = function (object, evtType, listener, useCapture)
{
        useCapture = !!useCapture;
        
        if (object.removeEventListener)
        {
                object.removeEventListener(evtType, listener, useCapture);
                return true;
        }
        else if (object.detachEvent)
        {
                 object.detachEvent(evtType, listener);
                 return true;
        }
        
        return false;
};


// HTML functions
searchshield.CleanupHTML = function (data)
{
        if (data == null)
                return data;

        // cleanup html data, replace any new lines
        data = data.replace(/\r/g, "");
        data = data.replace(/\n/g, "");
        // escape any single quotes
        data = data.replace(/'/g, "\\'");

        return data;
};
searchshield.removeHtmlTags = function (str)
{
        var re = new RegExp('(<[^>]+>)','g');
        var strStr = new String(str);
        if (!!strStr)
                return strStr.replace(re, '');
        else
                return str;
        
};


// Browser functions
searchshield.containedIn = function (container, element)
{
        while (element != null) 
        {
                if (container == element) 
                {
                        return true;
                }
                element = element.parentNode;
        }
        return false;
};
searchshield.elementSize = function (element)
{
        //returns an array [sizeX, sizeY]
        
        var elemX;
        var elemY;
        
        elemX = parseInt(element.offsetWidth);
        elemY = parseInt(element.offsetHeight)
        
        return [elemX, elemY];
};
searchshield.GetFullBoundingRect = function (element)
{
        if (!element) return;

        // get bounding rect for incoming element
        var elementRect = element.getBoundingClientRect();
        var nextImg = null;
        var nextImgRect = null;

        // first check for another non-TextNode element after this one
        var siblingElement = searchshield.NextSiblingNode(element);
        if (        siblingElement && 
                siblingElement.firstChild && 
                siblingElement.id && 
                siblingElement.id.indexOf("XPLSS_") != -1)
        {
                nextImg = siblingElement.firstChild;                
                nextImgRect = nextImg.getBoundingClientRect();        
        }
        else
        {
                return elementRect;
        }
        
        if ((nextImgRect.top >= elementRect.bottom) && 
                (nextImgRect.left <= elementRect.left))
        {        // images appear to be on seperate lines
                return elementRect;
        }

        // else merge the rects together into a new one
        var newRect = new function() { this.top=0; this.left=0; this.right=0; this.bottom=0; this.mid=0;};
        newRect.top = Math.min(elementRect.top, nextImgRect.top);
        newRect.left= Math.min(elementRect.left, nextImgRect.left);
        newRect.right=Math.max(elementRect.right, nextImgRect.right);
        newRect.bottom=Math.max(elementRect.bottom, nextImgRect.bottom);
        newRect.mid = Math.min(elementRect.right, nextImgRect.left);
        
        return newRect;
};
searchshield.offsetLeft = function (element)
{
        var offset = 0;
        while (element)
        {
                offset += element.offsetLeft;
                element = element.offsetParent;
        }

        return offset;
};
searchshield.offsetTop = function (element)
{
        var offset = 0;
        while (element)
        {
                offset += element.offsetTop;        
                element = element.offsetParent;
        }

        return offset;
};
searchshield.scrollSize = function (imageElem)
{
        // returns an array [scrollX, scrollY, hasParentFrame]

        var scrollX;
        var scrollY;
        var hasParentFrame;
        
        // firefox
        if (window.pageXOffset && window.pageYOffset)
        {
                scrollX = window.pageXOffset;
                scrollY = window.pageYOffset;
        }
        else if (document.documentElement || document.body)
        {
                scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
                scrollY = document.documentElement.scrollTop || document.body.scrollTop;

                if (imageElem)
                {
                        var frames = document.frames;
                        if (frames)
                        {
                                for (var i=0; i < frames.length; i++)
                                {
                                        var img;
                                        try {
                                                img = frames[i].document.getElementById(imageElem.id);
                                        }
                                        catch(domErr){}

                                        if (img != null)
                                        {
                                                scrollX = frames[i].document.documentElement.scrollLeft;
                                                scrollY = frames[i].document.documentElement.scrollTop;
                                                hasParentFrame = true;
                                                break;
                                        }
                                }
                        }
                }
        }
        else
        {
                scrollX = 0;
                scrollY = 0;
        }
        
        return [parseInt(scrollX,10), parseInt(scrollY,10), hasParentFrame];
};
searchshield.viewPortSize = function ()
{
        // returns an array [width, height, scrollYWidth], where scrollYWidth is always 0 for IE

        var scrollXWidth         = 19;
        var scrollYWidth         = 0; // 0 for Microsoft IE
        var scrollBarX         = false;
        var windowX;
        var windowY;
        
        // firefox
        if (window.innerWidth && window.innerHeight)
        {
                //TODO: validate this block if implemented for firefox
                
                windowX = window.innerWidth - scrollXWidth;
                windowY = window.innerHeight;

                try
                {
                        scrollYWidth = Math.floor(Math.abs(window.innerHeight - document.documentElement.clientHeight)) + 1;
                        scrollBarX = (document.documentElement.clientWidth < document.documentElement.scrollWidth);
                }
                catch(err){}

                if (scrollBarX && !scrollYWidth)
                        scrollYWidth = 18;        //normally 17 (+1 top border)
                                        
        }
        else if (document.documentElement || document.body) 
        {
                windowX = (document.documentElement.clientWidth || document.body.clientWidth) - scrollXWidth;
                windowY = document.documentElement.clientHeight || document.body.clientHeight;
        }
        else
        {
                windowX = 0;
                windowY = 0;
        }

        return [windowX, windowY, scrollYWidth];
};
searchshield.zoomLevel = function ()
{
                var level = 1;
                if (document.body.getBoundingClientRect) {
                        // rect is only in physical pixel size before IE8 
                        var rect = document.body.getBoundingClientRect();
                        level = Math.round (((rect.right - rect.left) / (document.body.offsetWidth)) * 100) / 100;
                }
                
                return level;
};


// Href functions
searchshield.checkUrl = function (url)
{        // cleanup a url, make sure there is a protocol on the front for scanning
        try {
                // trim
                url = url.replace(/^\s+/, "").replace(/\s+$/, "");

                // if no protocol, add http:// to it        
                if (url.indexOf("://") == -1)
                        url = "http://" + url;
        }
        catch(err){}

        return url;
};
searchshield.DoesURLContain = function (url, contain)
{
        if ((url == null) || (url.length < 1))
                return false;

        // breakup the url to check
        var parts = url.split('/');
        if (parts.length < 3)
                return false;

        var domain= parts[2].toLowerCase();
        if (domain.indexOf(contain) > -1)
                return true;

        return false;
};
searchshield.FilterUrl = function (url, filter)
{
        if (!url || (url.length < 1))
                return false;
        
        if (!filter || !(filter instanceof Array))        
                return false;
                
        var parts = url.split('/');
        if ((parts == null) || (parts.length < 3))
                return false;

        var domain = parts[2];
        for (var i = 0; i < filter.length; i++)
        {
                if (domain.indexOf(filter[i]) != -1)
                        return true;
        }
        return false;
};
searchshield.GetDomain = function (url)
{
        if (url != null)
        {
                // get url domain
                var parts = url.split('/');
                if ((parts != null) && (parts.length >= 3))
                {
                        return parts[2].toLowerCase();
                }
        }
        
        return url;
};
searchshield.getUrlContents = function (url) 
{
        if (url == null)
                return null;

        // don't query if local url
        if (url.indexOf("linkscanner://") != -1)
                return null;

        try 
        {
                req = new XMLHttpRequest();
                req.open("GET", url, false);
                req.send(null);
                if (req.status == 200)
                        return req.responseText;
                else
                        return null;
        } 
        catch (err)
        {
                // nothing to do
                return null;
        }
};
searchshield.parseLink = function (href, simpleMode)
{
        var uri                  = {};
        var parameter = {
                        complex: {
                                pattern: /^(?:([a-z]+):(?:([a-z]*):)?\/\/)?(?:([^:@]*)(?::([^:@]*))?@)?((?:[a-z0-9_-]+\.)+[a-z]{2,})(?::(\d+))?(?:([^:\?\#]+))?(?:\?([^\#]+))?(?:\#([^\s]+))?$/i,
                                element: ['source','scheme','subscheme','user','pass','host','port','path','query','fragment']
                                },
                        simple: {
                                pattern: /^(?:([a-z]+):\/\/)?((?:[a-z0-9_-]+\.)+[a-z]{2,})(?:\/)([^:\?]+)?(?:([\?|\#])([^\?]+))?$/i,
                                element: ['source','scheme','host','path','delimiter','query']
                        }
                };
        var mode        = simpleMode !== false ? 'simple' : 'complex';
        var pattern        = parameter[mode].pattern;
        var element        = parameter[mode].element;
        
        if (!href)
                return uri;

        var matches        = href.match(pattern);
        
        if (matches)
        {
                // --------------------
                // iterate over the matches array and populate uri properties
                // using the respective element parameter as the name.
                // NOTE: set raw property type as String to make inArray()
                // work properly with instanceof.
                // --------------------
                for (var i=0; i < matches.length; i++)
                        uri[element[i]] = new String(matches[i] || "");
                
                // --------------------
                // create an array, hostArray, from host, for example,
                // host="www.google.com" and hostArray=["www","google","com"]
                // --------------------
                uri.hostArray        = uri.host.split(".");
                
                // --------------------
                // create an array, qsArray, from query, for example,
                // query='hl=en&q=javascript&btnG=Search&aq=f&aqi=g10&aql=&oq=&gs_rfai='
                // qsArray=[{hl:'en'},{q:javascript}, ... ,(qs_rfai:''}]
                //
                // $0=entire match, $1=capture 1, $2=capture 2
                // must include $0 even though it is unused so
                // the replace works properly
                // --------------------
                uri.qsArray                = [];
                uri.query.replace(/(?:^|&)([^&=]*)=?([^&]*)/g, 
                                                        function ($0, $1, $2) {
                                                                if ($1) uri.qsArray[$1] = $2;
                                                                }
                                                        );
        }
        
        //non-standard urls require a fail-safe that relies on simply splitting the href
        function splitLink(href)
        {
                // split the href on '/'
                var linkParts = href.split("/");

                // need domain and path
                if ((linkParts == null) || (linkParts.length < 2))
                        return false;
        
                var uri = {
                        delimiter: (linkParts[3]).substring(0,1),
                        host: linkParts[2],
                        hostArray: (linkParts[2]).split('.'),
                        path: (linkParts[3]).substring(1),
                        qsArray: {},
                        query: '',
                        scheme: (linkParts[0]).substring(0, linkParts[0].length-1),
                        source: href
                        };

                return uri;
        }

        if (!uri.host)
                uri = splitLink(href);

        return uri;
};

// general functions
searchshield.arrayKeys = function (array)
{
        var keys = new Array();
        for(k in array)
                keys.push(k);

        return keys;
};
searchshield.inArray = function (key, array, caseSensitive, exactMatch)
{
        if (! array instanceof Array)
                return false;
        
        if (caseSensitive !== true)
                caseSensitive = false;
                
        if (exactMatch !== false)
                exactMatch = true;
        
        if (key instanceof String)
        {
                for (var i=0; i < array.length; i++)
                {
                        var k = caseSensitive ? key.valueOf() : key.valueOf().toLowerCase();
                        var a = caseSensitive ? array[i] : array[i].toLowerCase();
                        if(exactMatch && k === a)
                                return true;
                        else if (!exactMatch && (-1 !== k.indexOf(a)))
                                return true;
                }
        }
        else if (key instanceof Array)
        {
                for (var i=0; i < array.length; i++)
                        for (var j=0; j < key.length; j++)
                        {
                                var k = caseSensitive ? key[j] : key[j].toLowerCase();
                                var a = caseSensitive ? array[i] : array[i].toLowerCase();
                                if (exactMatch && k === a)
                                        return true;
                                else if (!exactMatch && (-1 !== k.indexOf(a)))
                                        return true;
                        }
        }

        return false;
};
// general use functions - end


// Search constructor
searchshield.Search = function()
{
        this.doc                         = null;
        this.engine                 = null;
        this.engines                 = null;
        this.links                         = null;
        this.uri                         = null;
        this.searchHash         = null;
        this.checkUrl                 = null;
        this.useLocalImgs         = null;
        this.clockUrl                 = null;
        // create engine list (actually key/value object will be used)
        this.engineList                = {};
};

searchshield.Search.prototype.getSearchNames = function()
{        // order is important
        var names =  [
                'Google',
                'AVGGoogle',
                'AltaVista',
                'AVGYahoo',
                'Yahoo',
                'Bing',
                'MSN', // MSN redirects to BING
                'Baidu',
                'Earthlink',
                'AOL',
                'Ask',
                'Yandex',
                'Seznam',
                'Webhledani',
                'eBay',
///temp                'Digg',
                'Slashdot',
                'Twitter',
                'GMail',
                'Facebook'
        ];
        return names;
};

searchshield.Search.prototype.detectEngine = function(href)
{
        if (!href)
                return;

        var aEng = searchshield.Search.prototype.getSearchNames();
        var aEngLen = aEng.length;
        for (var i=0; i < aEngLen; i++)
        {
                if (searchshield[aEng[i] + 'SearchEngine'].prototype.validSearch(href))
                        return aEng[i];
        }

        return;
};

searchshield.Search.prototype.addEngine = function(engine)
{
        if (!this.engines)
                this.engines = new Array();
        
        this.engines.push(engine);
};

searchshield.Search.prototype.addLink = function(inElement, inHref)
{
        if (!this.links)
                this.links = new Array();

        var hrefHash;
        try
        {
                hrefHash = searchshield.avgCallFunc(this.doc, 'GetHash', inHref);
        }
        catch (e){}

        var newNode = {
                        element:        inElement,
                        href:                 inHref,
                        hash:                hrefHash,
                        search:                this.searchHash
                };
        
        this.links.push(newNode);
        
        return newNode;
}

// process the search result page after all search engines have been added
searchshield.Search.prototype.process = function(doc)
{
        // only process when searchshield is enabled
        if (0 == searchshield.avgCallFunc(doc, 'GetSearchEnabled'))
                return;
                
        this.doc        = doc;
        this.href        = this.doc.location.href;
        this.uri        = searchshield.parseLink(this.href);

        try
        {
                this.searchHash         = searchshield.avgCallFunc(this.doc, 'GetHash', this.href);

                // get any previously active engine
                this.engine                = this.engineList[this.searchHash.toString()];
        }
        catch (e) {}

        /*
        
        Process Steps:
        1. Add all supported search engines
        2. Identify the active search engine
        3. Get all document links and add AVG images 
        */
        
        // STEP 1 - Add all supported search engines
        if (!this.engines)
        {
                var aEng = xplSearch.getSearchNames();
                var aEngLen = aEng.length;
                for (var i=0; i < aEngLen; i++)
                {
                        xplSearch.addEngine(new searchshield[aEng[i]+'SearchEngine'](this));
                }
        }
        
        // search the engines if we didn't find one
        if (!this.engine)
        {
                // STEP 2 - Identify the active search engine
                var engLen = this.engines.length;
                for (var i = 0; i < engLen; i++)
                {
                        if (this.engines[i].validSearch())
                        {
                                this.engine                = this.engines[i];
                                break;
                        }
                }
                
                // create a new engine instance to store
                this.engineList[this.searchHash.toString()] = this.engine;
                
                // init this search, if < 1 either an error or disabled
                //var sdkInit = 0;
                //try {
                //        sdkInit = xpl_sdk.SXPL_InitSearch(this.href);
                //}
                //catch(e){}
                //if (sdkInit < 1)
                //        return false;
        }

        // return immediately if there is not an active search engine
        if (!this.engine)
                return false;
        
        try {        
                // base url to check for icons
                this.checkUrl         = searchshield.avgCallFunc(this.doc, 'GetIconUrl', '1');

                // check if using linked or local icons
                this.useLocalImgs        = !searchshield.getUrlContents(this.checkUrl);

                // get the clock url
                this.clockUrl         = searchshield.avgCallFunc(this.doc, 'GetIconUrl', '0');
        }
        catch(e){}
                

        // STEP 3 - Get all document links and add AVG images
        var alltags = this.doc.getElementsByTagName("*");        // this method works for IE, FF and Chrome
        for (var i=0; i < alltags.length; i++)
        {
                // ignore verdicts
                if (alltags[i].id && (alltags[i].id.indexOf("LXPLSS_") != -1))
                        continue;
        
                //should the link be included?  Make sure includeLink always returns an href else FALSE,
                var href = this.engine.includeLink(alltags[i]); 
                if (!href)
                        continue;

                var newNode = this.addLink(alltags[i], href);
                this.engine.addImage(newNode, this.clockUrl, false);
        }

        return (this.links ? this.links.length : false);
};
////////////////    SEARCH    ////////////////



////////////////    SEARCH ENGINE    ////////////////

// Interface for a SearchEngine object
searchshield.SearchEngine = function(search)
{
        this.search = search;
        this.type = 'standard';
        this.processFrames = false;
        this.new_links                = true;
        this.onlyPrimaries        = true;
        this.inline = {
                clockImage: "linkscanner://clock12.png",
                image: [        "linkscanner://safe12.png",
                                        "linkscanner://caution12.png",
                                        "linkscanner://warning12.png",
                                        "linkscanner://blocked12.png"
                                ],
                color: {
                        border: ["#00A120;", "#EAA500;", "#F57301;", "#D20003;"],
                        background: ["#C3E5CA;", "#FEEFAE;", "#FFD3B0;", "#F5D4C1;"]
                }
        };
        this.filter_urls = [
                "ad.doubleclick.net", "ads1.revenue.net", "aslads.ask.com",
                "bluestreak.com", "clickbacktrack.net", "clickbank.net",
                "clickboothlnk.com", "clickmanager.com", "clickserve.cc-dt.com",
                "clickserve.dartsearch.net", "clicktraxmedia.com", "clk.atdmt.com",
                "dpi-digialphoto.com", "feedpoint.net", "hypertracker.com",
                "jdoqocy.com", "kqzyfj.com", "m1428.ic-live.com",
                "mediaplex.com", "mr.mdmngr.com", "n339.asp-cc.com",
                "offeredby.net", "offerweb.com", "pinktrax.com",
                "pinktrax.com", "pixel1523.everesttech.net", "qckjmp.com",
                "r.rd06.com", "revenuewire.net", "s0b.bluestreak.com",
                "s2.srtk.net", "servedby.advertising.com", "store.yahoo.com",
                "tf8.cpcmanager.com", "thetoptracker.com", "track.searchignite.com",
                "tracking.searchmarketing.com", "www.dpbolvw.net", "www.rkdms.com",
                "www.yellowbookleads.com"
                ];
        this.shortened_urls = [
                "3.ly", "bit.ly", "is.gd", "tr.im", "short.to", "tiny.cc", "tinyurl.com"
                ];
        this.showCleanVerdicts                = true;
        this.showLowRiskVerdicts        = true;
        this.showMedRiskVerdicts        = true;
        this.VeriSignSplit                        = searchshield.VERISIGN_SPLIT_NOTEST;
};
searchshield.SearchEngine.prototype.flyoverExists = function (doc)
{
        return !!doc.getElementById("XPLSS_Flyover");
};
searchshield.SearchEngine.prototype.inlineExists = function (doc)
{
        return !!doc.getElementById("XPLSS_InlineFlyover");
};
searchshield.SearchEngine.prototype.validSearch = function(href) { return false; };
searchshield.SearchEngine.prototype.includeLink = function(link) { return false; };
searchshield.SearchEngine.prototype.insertNodes = function(node, doc)
{
        var element = node.element;
        var parentNode = node.element.parentNode;
        if (parentNode == null)
        {
                // try and find element again based on the hash
                element = doc.getElementById("xplid_" + node.hash);
                parentNode = !!element ? element.parentNode : null;
        }

        var insertNode = !!element ? element.nextSibling : null;
        while ((insertNode                        != null) && 
                        (insertNode.tagName        != null) && 
                        (insertNode.tagName        == "SPAN"))
        {
                insertNode = insertNode.nextSibling;
        }
        
        return [insertNode, parentNode];
};
searchshield.SearchEngine.prototype.addImage        = function(node, image, hidden)
{
        var element        = node.element;
        var hash        = node.hash;
        var score         = node.score;

        // set verdict display configuration
        var doc = element.ownerDocument;
        if (!doc.getElementById('XPLSS_Flyover'))
                searchshield.initFlyover(doc, this);

        // get the proper insertion point for the image
        var insertNodes = this.insertNodes(node, doc);
        var insertNode = insertNodes[0];
        var parentNode = insertNodes[1];

        if (!parentNode)
                return;

        // see if we already have an image
        if ((insertNode                != null) && 
                (insertNode.id        != null) && 
                (insertNode.id.indexOf("XPLSS_") > -1))
        {
                return;
        }

        // mark search result anchor so it isn't processed repeatedly
        if (score == undefined)
                element.setAttribute("avglschecked", hash + "S" + this.VeriSignSplit);

        // create a new image
        var img = doc.createElement('img');
        img.src = image;
        img.id = "XPLSS_" + hash;
        img.style.borderStyle = "none";
        img.style.margin = "0 3px";
        
        // for IE, specify these style attributes to prevent inadvertent inheritance from parent
        if (img.width && img.height)
        {
                img.style.width = img.width + 'px';
                img.style.height = img.height + 'px';
        }
        
        // apply custom element styles
        this.updateElementStyle(img, this.addImageStyle);
        
        // create the link element 
        var anchor = doc.createElement("A");
        anchor.setAttribute("id", "LXPLSS_" + hash);

        if ((hidden != null) && (hidden == true))
        {        // hiding the parent will also hide its child nodes
                anchor.style.display = "none";
        }
        
        // Default anchor styles
        //Over-ride possible border style with inline declaration
        anchor.style.borderStyle = "none";

        // apply custom element styles
        this.updateElementStyle(anchor, this.addAnchorStyle);

        if (score == searchshield.SCORE_SS_VERISIGN)
        {
                anchor.style.textDecoration = "none";
                anchor.style.background = "none";
        }

        // append the image to the link
        anchor.appendChild(img);

        // insert the node as either a sibling or a child
        if (insertNode != null)
                parentNode.insertBefore(anchor, insertNode);
        else
                parentNode.appendChild(anchor);
                
        return anchor;
};
searchshield.SearchEngine.prototype.updateImage = function (hash, search, score, image, alt_image, flyover, click_thru, altClick_thru)
{
                var updated = false;

                var frameDoc  = this.search.doc;
                var docFrames = frameDoc.frames;
                var frameElem;
                if (docFrames && this.processFrames)
                {
                        for (var i=0; i < docFrames.length; i++)
                        {
                                try {
                                        if (docFrames[i].document.getElementById(hash))
                                        {
                                                frameElem = docFrames[i].frameElement;
                                                frameDoc = docFrames[i].document;
                                                break;
                                        }
                                } 
                                catch(err){}
                        }
                }

                while ((element = frameDoc.getElementById(hash)) != null)
                {
                        // check configuration to determine if verdict display property
                        var showVerdict = true;                        
                        var nSeverity = Number(score - 1);
                        switch (nSeverity)
                        {
                                case searchshield.XPLCHECK_RESULT_SEV_LOW:
                                        showVerdict = this.showLowRiskVerdicts;
                                        break;
                                case searchshield.XPLCHECK_RESULT_SEV_MED:
                                        showVerdict = this.showMedRiskVerdicts;
                                        break;
                                case searchshield.XPLCHECK_RESULT_SEV_NONE:
                                        showVerdict = this.showCleanVerdicts;
                                        break;
                                default:
                                        if (score == searchshield.SCORE_SS_VERISIGN)
                                                showVerdict = this.showCleanVerdicts;
                                        break;
                        }
                        
                        // remove image if no url specified
                        if ((!showVerdict) || (image == null) || (image.length < 1))
                        {
                                // hide the parent anchor node
                                element.parentNode.style.display = "none";

                                // mark the id as being hidden (element is the image)
                                element.id = element.id + "H";
                                updated = true;
                                
                                // if not a verisign score
                                if (score != searchshield.SCORE_SS_VERISIGN)
                                        continue;
                        }

                        // cleanup flyover, replace any new lines or single quotes
                        flyover = searchshield.CleanupHTML(flyover);

                        // mark the id as having been updated
                        element.id = element.id + "U" + score;
                        element.src        = image;
                        element.attachEvent("onmouseover", function(e){avglsflyover.popup(e, hash, search, flyover)});
                        element.attachEvent("onmouseout", function(e){avglsflyover.hide(e)});

                        // check for attribute updates (elementAttribute is an associative array (i.e., object)
                        if (this.elementAttribute)
                        {
                                for (a in this.elementAttribute)
                                {
                                        if(this.elementAttribute[a])
                                                element.setAttribute(a, this.elementAttribute[a]);
                                }
                        }

                        // To dynamically reduce verdict image size if it causes its container to scroll
                        // when not showing alt images determine if the element containing
                        // the verdict image is scrolling and decrease the image size by
                        // the scroll amount (min size is 80% or original)
                        var reduceBy        = 0.8;
                        var scrl                = 0;
                        if (!alt_image || this.omitAltImage || this.VeriSignSplit == searchshield.VERISIGN_SPLIT_TESTB)
                        {
                                try{
                                        var maxLoop = 5;
                                        var cN = element.parentNode.parentNode;  //image->anchor->containerNodes...
                                        while (cN && maxLoop--)
                                        {
                                                if (cN.tagName == "DIV" || cN.tagName == "SPAN")
                                                {
                                                        // get object height depending on ie document mode
                                                        var clientHeight = (cN.clientHeight == 0 || 
                                                                (this.search.doc.documentMode && this.search.doc.documentMode < 8)) ? 
                                                                cN.offsetHeight : 
                                                                cN.clientHeight;
                                                        scrl = cN.scrollHeight - clientHeight;
                                                        break;
                                                }

                                                cN = cN.parentNode;
                                        }

                                        if (0 < scrl)
                                        {
                                                var eH = (element.height - scrl)/element.height;
                                                if (reduceBy > eH)
                                                        eH = reduceBy;
                                                
                                                var newDim = Math.ceil(eH*element.height);
                                                
                                                element.height = newDim;
                                                element.width = newDim;
                                                
                                                element.style.height = newDim + "px";
                                                element.style.width = newDim + "px";
                                        }
                                }
                                catch(e){}
                        }

                        // set default style attributes
                        element.style.display                = "";
                        
                        // if verisign icon showing move our icon up for better centering of the 2
                        // except for IE7 browser - it does not like this style
                        try {
                                var ieVersion = parseFloat(navigator.appVersion.split("MSIE")[1]);
                                if (alt_image && (alt_image.length > 0) && ieVersion != 7)
                                        element.style.verticalAlign = "10%";
                        }
                        catch(err){};

                        // apply custom element styles
                        this.updateElementStyle(element, this.updateImageStyle)

                        // update the click thru
                        var link = this.search.doc.getElementById("L" + hash);
                        if (link)
                        {
                                link.href = click_thru;
                                link.id = link.id + "U" + score;
                        }

                        updated = true;

                        // add the alternate image if supplied BUT not on avg yahoo
                        if ((alt_image)                                && 
                                (alt_image.length > 0)        && 
                                (!this.omitAltImage)        &&
                                (this.VeriSignSplit != searchshield.VERISIGN_SPLIT_TESTB))
                        {

                                var vhash = hash.substring(hash.indexOf("_")+1);

                                // create a temporary link node
                                var tmp_node = {
                                                element:        element.parentNode,
                                                href:                altClick_thru,
                                                hash:                vhash + "VU" + score,
                                                search:                this.searchHash,
                                                score:                score
                                        };

                                var altAnchor = this.addImage(tmp_node, alt_image, false);
                                if (altAnchor && altAnchor.firstChild)
                                {
                                        altAnchor.firstChild.setAttribute("onmouseover", "");
                                        altAnchor.href = altClick_thru;
                                }
                        }
                }
                
                if (updated != false)
                {
                        this.resizeFrame(frameElem);
                        return true;
                }

        return false;
};
searchshield.SearchEngine.prototype.updateElementStyle = function (element, elementStyle)
{
        if (elementStyle)
        {        // a NULL attribte value will unset it
                for(attr in elementStyle)
                {
                        try {
                                if (element.style.setAttribute)
                                        element.style.setAttribute(attr, elementStyle[attr]);
                                else
                                        element.style[attr] = elementStyle[attr];
                        } catch(err){}
                }
        }
};

searchshield.SearchEngine.prototype.resizeFrame = function (frameElem)
{        // resize frame to prevent unwanted scrolling after inserting verdicts

        // ignore inline and non-frame engines
        if ((this.type == 'inline') || (!this.processFrames))
                return;

        // ensure all required elements are available
        if ((frameElem == null) || (frameElem.style == null) || (frameElem.contentWindow == null))
                return;

        // if frame is scrolling vertically then resize
        var frameHeight = parseInt(frameElem.style.height, 10);
        if (!isNaN(frameHeight) && (frameHeight < frameElem.contentWindow.document.body.scrollHeight))
                frameElem.style.height = frameElem.contentWindow.document.body.scrollHeight + 'px';

        return;
};

searchshield.SearchEngine.prototype.getImgElement = function (element)
{        // return an xpl img element associated with a given element
        if (element == null)
                return null;

        // go up the parent tree looking for a header or div
        while ( (element.parentNode != null) && 
                        (element.tagName.charAt(0) != "H") && 
                        (element.tagName.charAt(0) != "D") &&
                        (element.tagName.charAt(0) != "T") )
        {
                element = element.parentNode;
        }

        // if all the way to the top, nothing
        if ((element.tagName == "HTML") || (element == null))
                return null;

        // get image tags, if none we are done
        var imgTags = element.getElementsByTagName("IMG");
        if ((imgTags == null) || (imgTags.Length < 1))
                return null;

        for (var i = 0; i < imgTags.length; i++)
        {
                if ((imgTags[i].id == null) || (imgTags[i].id.indexOf("XPLSS_") == -1))
                        continue;

                return imgTags[i];
        }

        // else didn't find anything
        return null;
};

searchshield.SearchEngine.prototype.setRatingsConfig = function (doc)
{
        // get verdict configuration, need at least severity
        var results = searchshield.avgCallFunc(doc, 'GetRatingsConfig');
        var parts = !!results ? results.split('::') : null;

        if (parts != null && parts.length >= 5)
        {        //if set to default then get config value
                if (this.showCleanVerdicts === true)
                        this.showCleanVerdicts                = (parseInt(parts[0]) == 1) ? true : false;
                        
                if (this.showLowRiskVerdicts === true)
                        this.showLowRiskVerdicts        = (parseInt(parts[1]) == 1) ? true : false;
                
                if (this.showMedRiskVerdicts === true)
                        this.showMedRiskVerdicts        = (parseInt(parts[2]) == 1) ? true : false;
                        
                this.VeriSignSplit        = (parseInt(parts[4]));
        }
        
        return true;
};

searchshield.SearchEngine.prototype.init_inline_ratings = function (doc)
{
        if ((doc == null) || (doc.getElementById("XPLSS_InlineFlyover")))
                return;
        
        // create the popup box
        var box = doc.createElement("DIV");
        try {
                box.setAttribute("id", "XPLSS_InlineFlyover");
                box.style.visibility = "hidden";
                box.style.left = "-5000px";

                box.style.position = "absolute";
                box.style.zIndex = "9999";
                box.style.padding = "0px 0px";
                box.style.marginLeft = "0px";
                box.style.marginTop = "0px";
                box.style.overflow = "hidden";
                box.style.wordWrap = "break-word";
                box.style.color = "black";
                box.style.fontSize = "10px";
                box.style.textAlign = "left";
                box.style.lineHeight = "130%";

                doc.body.appendChild(box);
                box = null;
        }
        catch(boxErr){}
};

searchshield.SearchEngine.prototype.show_inline_ratings = function (doc, node, image)
{        
        var href        = node.href;
        var anchor        = node.element;

        if ((href == null) || (href.length < 1))
                return;
                
        if (avglsinlineflyover.imageExists(anchor))
                return;
        
        // mark search result anchor so it isn't processed repeatedly
        anchor.setAttribute("avglschecked", "1");
        
        // get verdict 
        this.display_inline(doc, anchor, href, node, false);
};

searchshield.SearchEngine.prototype.display_inline = function (doc, anchor, href, node, update, min_severity)
{
        // min_severity is the lowest severity to display, so setting it to
        // 1 would not display safe icons
        
        var results        = searchshield.avgCallFunc(doc, 'MalsiteCheck', href);
        if (results == null)
                return;
        
        var parts = results.split('::');
        
        // need at least severity
        if (parts == null)
                return;
                        
        var nSeverity = parseInt(parts[0]);
        
        if (!update && nSeverity == searchshield.XPLCHECK_RESULT_SEV_NONE)
        {
                var shortUrl = searchshield.FilterUrl(href, this.shortened_urls);
                if (shortUrl)
                {        // shortened url verdicts display later
                        var engine = this;
                        anchor.attachEvent("onmouseover", function(event){avglsinlineflyover.mouseOverHandler(event, doc, engine)}, false);
                        return;
                }
        }

        //blacklist url
        var blShortUrl = false;
        if (nSeverity == searchshield.XPLCHECK_RESULT_SEV_BLOCK)
        {
                var shortUrl = searchshield.FilterUrl(href, this.shortened_urls);
                if (shortUrl)
                        blShortUrl = true;
        }
        
        // need xlated cat tag and category
        if (parts.length < 3)
                return;

        // check the minimum to display
        if ((min_severity != null) && (nSeverity < min_severity))
                return;
                
        if (nSeverity == searchshield.XPLCHECK_RESULT_SEV_LOW && !this.showLowRiskVerdicts)
        {
                if (update)
                        this.avg_ls_inline_hide_verdict(anchor);
                
                return;
        } 
        if (nSeverity == searchshield.XPLCHECK_RESULT_SEV_MED && !this.showMedRiskVerdicts)
        {
                if (update)
                        this.avg_ls_inline_hide_verdict(anchor);
                
                return;
        }
        if (nSeverity == searchshield.XPLCHECK_RESULT_SEV_NONE && !this.showCleanVerdicts) 
        {
                if (update)
                        this.avg_ls_inline_hide_verdict(anchor);
                        
                return;
        }

        if (update)
                this.update_inline_image(anchor, nSeverity, parts);
        else
                this.add_inline_image(doc, anchor, nSeverity, parts, blShortUrl);
};

searchshield.SearchEngine.prototype.avg_ls_inline_hide_verdict = function (anchor)
{
        var image = avglsinlineflyover.getImage(anchor);
        if (image)
        {
                image.style.display = "none";
                if (image.parentNode && image.parentNode.id == "avg_ls_anch")
                        image.parentNode.style.display = "none";
        }
};

searchshield.SearchEngine.prototype.update_inline_image = function (anchor, nSeverity, aRisk)
{
        // update the image already in the page
        if (anchor && anchor.firstChild)
        {
                var html  = '';
                var image = ''; 
                if (aRisk != null && nSeverity != null)
                {
                        var riskCategory = aRisk[1];
                        var riskName         = aRisk[2];
                        var bgColor                 = this.inline.color.background[nSeverity];
                        var borderColor         = this.inline.color.border[nSeverity];

                        image                         = this.inline.image[nSeverity];
                        html                         = avglsinlineflyover.build(riskCategory, riskName, bgColor, borderColor);
                }
                
                var imageElem = anchor.firstChild;
                imageElem.src = image;
                
                if ( html && html.length > 0 )
                {
                        imageElem.setAttribute("title", "");
                        imageElem.attachEvent("onmouseover", function(e){avglsinlineflyover.popup(e, html)});
                        imageElem.attachEvent("onmouseout", function(e){avglsinlineflyover.hide(e)});
                }
        }
};

// add the image to the page
searchshield.SearchEngine.prototype.add_inline_image = function (doc, anchor, nSeverity, aRisk, blShortUrl)
{
        if (anchor == null || anchor.parentNode == null)
                return null;

        // get the proper insertion point for the image
        var insertNode = anchor.nextSibling;
        while ((insertNode                        != null) && 
                        (insertNode.tagName != null) && 
                        (insertNode.tagName == "SPAN"))
        {
                insertNode= insertNode.nextSibling;
        }
        
        // see if we already have an image anchor
        if ((insertNode                != null) && 
                (insertNode.id        != null) && 
                (insertNode.id        == "avg_ls_anch"))
        {
                return null;
        }

        var html  = '';
        var image = this.inline.clockImage; 
        if (aRisk != null && nSeverity != null)
        {
                var riskCategory = aRisk[1];
                var riskName         = aRisk[2];
                var bgColor                 = this.inline.color.background[nSeverity];
                var borderColor         = this.inline.color.border[nSeverity];
                image                         = this.inline.image[nSeverity];

                var blUrl;
                if (blShortUrl)
                {
                        var aRiskName = riskName.split(':');
                        var sUrl = searchshield.checkUrl(aRiskName[1]);

                        blUrl = {};
                        blUrl.riskNameLabel = aRiskName[0] + ': ';
                        blUrl.riskCategory = riskCategory;
                        blUrl.bgColor = bgColor;
                        blUrl.borderColor = borderColor;
                        blUrl.sUrl = sUrl;
                }
                else
                {
                        html = avglsinlineflyover.build(riskCategory, riskName, bgColor, borderColor);
                }
        }

        doc = anchor.ownerDocument;

        var img                 = doc.createElement("img");
        img.src                 = image;
        img.setAttribute("id","avg_ls_image");
        img.style.width = "12px";
        img.style.border = "none";
        img.style.padding = "0 3px";
        img.style.margin = "0";
        img.style.display = "inline";
        
        if ((html && html.length > 0) || (blUrl != undefined))
        {
                img.setAttribute("title", "");
                img.attachEvent("onmouseover", function(e){avglsinlineflyover.popup(e, html, blUrl)});
                img.attachEvent("onmouseout", function(e){avglsinlineflyover.hide(e)});
        }

        // create the link element 
        var newAnchor = doc.createElement("A");
        newAnchor.setAttribute("id", "avg_ls_anch");
        
        newAnchor.appendChild(img);
        img = null;

        // insert the node as either a sibling or a child
        if (insertNode != null)
                anchor.parentNode.insertBefore(newAnchor, insertNode);
        else
                anchor.parentNode.appendChild(newAnchor);        
                
        return newAnchor;                

};
////////////////    SEARCH ENGINE    ////////////////


///////////////    GOOGLE SEARCH ENGINE    ///////////////
searchshield.GoogleSearchEngine = function(search)
{
        searchshield.SearchEngine.call(this, search);
        this.onlyPrimaries = false;
};
searchshield.GoogleSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.GoogleSearchEngine.prototype.constructor = searchshield.GoogleSearchEngine;
searchshield.GoogleSearchEngine.prototype.name = "google";        // the name by which the search engine is known (always lowercase)
searchshield.GoogleSearchEngine.prototype.validSearch = function(href) {

        var uri;
        if (typeof(this.search) === 'undefined' || null === this.search)
                uri = searchshield.parseLink(href);
        else
                uri = this.search.uri;

        if(!uri || !uri.host)
                return false;

        var hostMatch        = false;
        var domain                = uri.host;
        
        // re stitch the uri path and query elements to
        // use existing logic
        var path = uri.path + uri.delimiter + uri.query;

        // Domains valid for google searches, must start with '.'
        var valid_domains = new Array(".google.co", ".mozilla.co");

        // For Google the host must match:
        //        .google.com                OR
        //        .google.co.XX        where XX is a country code
        //        .google.XX                where XX is a country code
        // Where any subdomain can come before the top level domain
        var domLen = valid_domains.length;
        for (var i = 0; i < domLen; i++)
        {
                var domainLen = domain.length;
                var valid_domain_len = valid_domains[i].length;
                var tldPos = domain.indexOf(valid_domains[i]);
                if (tldPos > -1)
                {
                        if (domain.charAt(tldPos + valid_domain_len) == 'm')
                                hostMatch = true;
                        else if ((domain.charAt(tldPos + valid_domain_len) == '.') && ((domainLen - tldPos) == valid_domain_len+3))
                                hostMatch = true;
                }
                else
                {
                        // get the form .google. to check the length of
                        var dot_pos = valid_domains[i].indexOf(".",1);
                        var valid_short_name = valid_domains[i].substring(0, dot_pos+1);

                        tldPos = domain.indexOf(valid_short_name);
                        if ((tldPos > -1) && ((domainLen - tldPos) == valid_domain_len))
                                hostMatch = true;
                }
                if (hostMatch)
                {
                        // replace beginning of domain with www.google since links will refer back to it
                        if ((i > 0) && (tldPos > -1))
                        {
                                var last_dot = domain.indexOf(".",tldPos+1)
                                if (last_dot > -1)
                                        domain = "www.google" + domain.substring(last_dot);
                        }
                        break;
                }
        }

        if (hostMatch)
        {
                // using ajax engine
                if ((path.indexOf("search?") == 0) ||
                        (path.indexOf("sponsoredlinks?") == 0) ||
                        (path.indexOf("webhp?") == 0) ||
                        (path.indexOf("webhp#") == 0) ||
                        (path.indexOf("#q=") == 0) ||
                        (path.indexOf("#hl=") == 0) ||
                        (path.indexOf("#sclient=") == 0))
                {
                        return true;
                }
        }

        return false;
};
searchshield.GoogleSearchEngine.prototype.includeLink = function(tag)
{
        var href = "";
        var outHref = false;
        var findStr = "";

        // check for interstitials
        if (searchshield.DoesURLContain(tag.href, this.search.uri.host))
        {
                findStr = this.search.uri.host + "/interstitial?";
                if (tag.className == "l" && tag.href)
                {
                        if (tag.href.indexOf(findStr) != -1)
                        {
                                findStr = "?url=";
                                var pos = tag.href.indexOf(findStr);
                                if (pos !== -1)
                                {
                                        pos += 5;
                                        outHref = tag.href.substring(pos);
                                        if (searchshield.FilterUrl(outHref, this.filter_urls))
                                                return false;
                                                        
                                        return outHref;
                                }
                        }
                }

                if (tag.className == "sla")
                {
                        findStr = "/url?q=";
                        urlPos = tag.href.indexOf(findStr);
                        if (urlPos != -1)
                        {
                                urlPos += 7;
                                outHref = tag.href.substring(urlPos);
                                return outHref;
                        }
                }
                
                // if an ad id
                if ((tag.id.indexOf("pa") == 0) || (tag.id.indexOf("an") == 0) ||
                        (tag.className == "resultLink"))
                {
                        var urlPos = -1;        

                        // ads now need unescaping
                        href = unescape(tag.href);

                        findStr= "/url?sa=";
                        if (href.indexOf(findStr) != -1)
                        {        // first kind, locate real url
                                findStr= "&q=http";
                                urlPos = href.indexOf(findStr);
                                if (urlPos != -1)
                                        urlPos += 3;        // puts it on the http
                        }
                        if (urlPos == -1)
                        {
                                findStr = "/pagead/iclk?sa=";
                                if (href.indexOf(findStr) != -1)
                                {        // second kind, locate real url
                                        findStr = "&adurl=http";
                                        urlPos        = href.indexOf(findStr);
                                        if (urlPos != -1)
                                                urlPos += 7; // puts it on the http
                                }
                        }
                        if (urlPos == -1)
                        {
                                if (href.indexOf("/aclk?sa=") != -1)
                                {        // third kind
                                        urlPos = href.indexOf("&q=http");
                                        if (urlPos != -1)
                                                urlPos += 3; // puts it on the http
                                        else
                                        {
                                                urlPos  = href.indexOf("&lp=http");
                                                if (urlPos != -1)
                                                        urlPos += 4;
                                                else
                                                {
                                                        findStr = "&adurl=http";
                                                        urlPos        = href.indexOf(findStr);
                                                        if (urlPos != -1)
                                                                urlPos += 7; // puts it on the http
                                                }
                                                
                                        }
                                }
                        }
                        if (urlPos == -1)
                        {
                                if (href.indexOf("/url?cad=") != -1)
                                {        // fourth kind
                                        urlPos = href.indexOf("&q=http");
                                        if (urlPos != -1)
                                                urlPos += 3; // puts it on the http
                                }
                        }
                        if (urlPos != -1)
                        {
                                outHref = href.substring(urlPos);

                                // extract any fragment text, shouldn't be unescaped
                                var pound = outHref.indexOf("#");        
                                if (pound != -1)
                                {
                                        var fragment = outHref.substring(pound);
                                        outHref = outHref.substring(0, pound);
                                        outHref = unescape(outHref);
                                        outHref += fragment;
                                        if (searchshield.FilterUrl(outHref, this.filter_urls))
                                                return false;

                                        return outHref;
                                }

                                outHref = unescape(outHref);
                                if (outHref.indexOf("?") == -1)
                                {
                                        var ampPos = outHref.indexOf("&");
                                        if (ampPos != -1)
                                                outHref = outHref.substring(0, ampPos);
                                }
                                
                                if (searchshield.FilterUrl(outHref, this.filter_urls))
                                        return false;

                                return outHref;
                        }
                }

                // recommended link - use following to see one
                // http://www.google.cz/search?hl=cs&q=warey&btnG=Hledat&lr=lang_cs
                // elem parent class = r
                // href must contain - url? and q=http
                var parentNode = tag.parentNode;
                if (parentNode && (parentNode.className.toLowerCase() == "r"))
                {
                        href = tag.href;
                        if (href && (href.indexOf("/url?") != -1))
                        {
                                // locate the real url
                                var urlPos = href.indexOf("q=http");
                                if (urlPos != -1)
                                {
                                        urlPos += 2;
                                        outHref = href.substring(urlPos);

                                        // include entire param up to '&'
                                        var ampPos = outHref.indexOf("&");
                                        if (ampPos != -1)
                                                outHref = outHref.substring(0, ampPos);

                                        return outHref;
                                }
                        }
                }
        }
        // no link to self
        else if (tag.className && (tag.className.charAt(0) == "l" || tag.className == "sla"))
        {
                // check for any images on the link
                if (0 === tag.getElementsByTagName("IMG").length)
                        return tag.href;
        }

        // else nothing
        return false;
};
///////////////    GOOGLE    ///////////////


///////////////    AVG GOOGLE SEARCH ENGINE    ///////////////
searchshield.AVGGoogleSearchEngine = function(search)
{
        searchshield.SearchEngine.call(this, search);
        this.onlyPrimaries = false;
};
searchshield.AVGGoogleSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.AVGGoogleSearchEngine.prototype.constructor = searchshield.AVGGoogleSearchEngine;
searchshield.AVGGoogleSearchEngine.prototype.name = "avggoogle";        // the name by which the search engine is known (always lowercase)
searchshield.AVGGoogleSearchEngine.prototype.validSearch = function(href) {

        var uri;
        if (typeof(this.search) === 'undefined' || null === this.search)
                uri = searchshield.parseLink(href);
        else
                uri = this.search.uri;

        if(!uri || !uri.host)
                return false;

        var domain                = uri.host;
        
        // re stitch the uri path and query elements to
        // use existing logic
        var path = uri.path + uri.delimiter + uri.query;

        if  (domain.indexOf("search.avg.com") > -1)
        {   // ads link back to google
                return true;
        }
        
        return false;
};
searchshield.AVGGoogleSearchEngine.prototype.includeLink = function(tag)
{
        var outHref = false;
        var findStr = "";

        // check for interstitials
        if (searchshield.DoesURLContain(tag.href, "google.com"))
        {
                // link back to self - DIV elem GrandParent class of res1 or res3 is Sponsored Link 
                var parentNode = tag.parentNode;
                if (parentNode)
                {
                        var grandParentNode = tag.parentNode.parentNode;
                        if (grandParentNode)
                        {
                                if ((grandParentNode.tagName == "DIV") && 
                                        ((grandParentNode.className.toLowerCase() == "res1") ||
                                        (grandParentNode.className.toLowerCase() == "res3")))
                                {
                                        var urlPos = -1;        

                                        // ads now need unescaping
                                        href = unescape(tag.href);

                                        if (urlPos == -1)
                                        {
                                                if (href.indexOf("/aclk?sa=") != -1)
                                                {        
                                                        findStr = "&adurl=http";
                                                        urlPos        = href.indexOf(findStr);
                                                        if (urlPos != -1)
                                                                urlPos += 7; // puts it on the http
                                                                
                                                }
                                        }
                                        if (urlPos != -1)
                                        {
                                                outHref = href.substring(urlPos)
                                                // extract any fragment text, shouldn't be unescaped
                                                var pound = outHref.indexOf("#");        
                                                if (pound != -1)
                                                {
                                                        var fragment = outHref.substring(pound);
                                                        outHref = outHref.substring(0, pound);
                                                        outHref = unescape(outHref);
                                                        outHref += fragment;
                                                        if (searchshield.FilterUrl(outHref, this.filter_urls))
                                                                return false;

                                                        return outHref;
                                                }

                                                outHref = unescape(outHref);
                                                if (outHref.indexOf("?") == -1)
                                                {
                                                        var ampPos = outHref.indexOf("&");
                                                        if (ampPos != -1)
                                                                outHref = outHref.substring(0, ampPos);
                                                }
                                
                                                if (searchshield.FilterUrl(outHref, this.filter_urls))
                                                        return false;

                                                return outHref;
                                        }
                                }
                        }
                }
        }        
                
        // no link to self
        else
        {
                var parentNode = tag.parentNode;
                if (parentNode)
                {
                        var grandParentNode = tag.parentNode.parentNode;
                        if (grandParentNode)
                        {
                                if ((grandParentNode.tagName == "DIV") && 
                                        (grandParentNode.className.toLowerCase() == "res2"))
                                {
                                        // check for any images on the link
                                        if (0 === tag.getElementsByTagName("IMG").length)
                                                return tag.href;
                                }
                        }
                }
        }

        // else nothing
        return false;
}
///////////////    AVG GOOGLE    ///////////////

///////////////    YAHOO SEARCH ENGINE    ///////////////
searchshield.YahooSearchEngine = function(search)
{
        searchshield.SearchEngine.call(this, search);
        this.showCleanVerdicts = false;
};
searchshield.YahooSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.YahooSearchEngine.prototype.constructor = searchshield.YahooSearchEngine;
searchshield.YahooSearchEngine.prototype.name = "yahoo";
searchshield.YahooSearchEngine.prototype.validSearch = function(href)
{
        var uri;
        if (typeof(this.search) === 'undefined' || null === this.search)
                uri = searchshield.parseLink(href);
        else
                uri = this.search.uri;

        if(!uri || !uri.host)
                return false;

        // re stitch the uri path and query elements to
        // use existing logic
        var path = uri.path + uri.delimiter + uri.query;

        // For Yahoo the host must match:
        //        search.yahoo.com                OR
        //        xx.search.yahoo.com where xx country code OR
        //        search.yahoo.co.xx OR
        // for Yahoo China: one.cn.yahoo.com & search.cn.yahoo.com
        if ((uri.host.indexOf("search.yahoo.co") != -1) ||
                (uri.host.match(/^(search|one)(\.[a-z]{2}\.yahoo\.com)$/))) 
        {
                if ((path.indexOf("search?") == 0) ||
                        (path.indexOf("search;") == 0) ||
                        (path.indexOf("s?p=") === 0))
                {
                        return true;
                }
        }

        return false;
};
searchshield.YahooSearchEngine.prototype.includeLink = function(tag)
{
        var href                = "";
        var outHref                = "";
        var findStr                = "";

        // yahoo likes to encode the url
        href = unescape(tag.href);

        if ((tag.className.indexOf("yschttl") != -1) || 
                (tag.className.indexOf("spt") != -1))
        {
                var da = href.indexOf("**");
                var ad = href.indexOf("*-");
                if (da != -1)
                        outHref = href.substring(da+2);
                else if (ad != -1)
                        outHref = href.substring(ad+2);
                else
                        outHref = href ;
                        
                if (outHref.toLowerCase().indexOf("overture.") !== -1)
                        return false;
        }
        else if ((tag.tagName)                        && 
                         (tag.tagName === "A")         && 
                         (!tag.className))
        {
                var tagParent = tag.parentNode;
                
                // if anchor without className then search parentNodes
                if ((tagParent) &&
                        (tagParent.tagName !== "EM") &&
                        (searchshield.getParentNodeByClassName("yst-web", tag, 4)))
                {
                        // China Yahoo support
                        outHref = href;
                }
                
                else if ((tagParent) &&
                                (tagParent.tagName === "H3") &&
                                (!!searchshield.getParentNodeById("WS2m",tag, 5)))
                {
                        // Japan Yahoo support
                        var da = href.indexOf("**");
                        if (da !== -1)
                                outHref = href.substring(da+2);
                }

                else if ((tagParent) &&
                                (tagParent.className !== "c") &&
                                (tagParent.parentNode.id !== "fpn") &&
                                (!!searchshield.getParentNodeByClassName("ymc", tag, 7)))
                {
                        // Korea Yahoo support - when not caught by yschttl
                        var da = href.indexOf("**");
                        if (da !== -1)
                                outHref = href.substring(da+2);
                }
        }
        else if (!this.onlyPrimaries)
        {
                findStr = "&yargs=";
                var yargs = href.indexOf(findStr);
                if (yargs != -1)
                {
                        outHref = href.substring(yargs+findStr.length);
                        // check for prefix
                        if (outHref.indexOf("://") == -1)
                                outHref = "http://" + outHref;

                        // if inside an <I>, probably a paypal link, don't include
                        if (tag.parentNode && (tag.parentNode.tagName == "I"))
                                return false;
                } 
        }

        // filter domains
        // split the url based on '/'
        var parts = !!outHref ? outHref.split('/') : null;

        // Filter out domains that match any of the search engine's names
        if (!parts || !parts[2])
                return false;
                
        var domain = parts[2];
        if ((domain.indexOf("rdrjp.yahoo.com") != -1)        ||
                (domain.indexOf("rdrkrs.yahoo.com") != -1)        ||
                (domain.indexOf("rdrtpe.yahoo.com") != -1)        ||
                (domain.indexOf("rdrird.yahoo.com") != -1)        ||
                (domain.indexOf("rdrhk2.yahoo.com") != -1)        ||
                (domain.indexOf("rdrsg1.yahoo.com") != -1)        ||
                (domain.indexOf("rdrin2.yahoo.com") != -1)        ||
                (domain.indexOf("rdre1.yahoo.com") != -1)        ||
                (domain.indexOf("rdrw1.yahoo.com") != -1)                )
        {
                return false;
        }

        // set for yahoo to get parent node for image insertion
        var hash = searchshield.avgCallFunc(this.doc, 'GetHash', outHref);
        tag.setAttribute("id", "xplid_" + hash);
        return outHref;
};
///////////////    YAHOO SEARCH ENGINE    ///////////////




///////////////    AVG YAHOO SEARCH ENGINE    ///////////////
searchshield.AVGYahooSearchEngine = function(search)
{
        searchshield.SearchEngine.call(this, search);
        this.showCleanVerdicts = false;
};
searchshield.AVGYahooSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.AVGYahooSearchEngine.prototype.constructor = searchshield.AVGYahooSearchEngine;
searchshield.AVGYahooSearchEngine.prototype.name = "avgyahoo";
searchshield.AVGYahooSearchEngine.prototype.validSearch = function(href)
{
        var uri;
        if (typeof(this.search) === 'undefined' || null === this.search)
                uri = searchshield.parseLink(href);
        else
                uri = this.search.uri;

        if(!uri || !uri.host)
                return false;
        
        var domain= uri.host;
        //path may be 'avg/search' or 'search'
        var pathArray = uri.path.split("/");
        var avg = pathArray[0];
        // re stitch the uri path and query elements
        // to use existing logic
        var path = (undefined == pathArray[1]) ? pathArray[0] : pathArray[1];
                path += uri.delimiter + uri.query;

        // For AVG Yahoo classic the host must match:
        //        yhs.search.yahoo.com        OR
        //        .yhs.search.yahoo.com
        if (domain.indexOf("yhs.search.yahoo.co") != -1)
        {
                if ((avg == "avg") &&
                        ((path.indexOf("search?") == 0) ||
                         (path.indexOf("search;") == 0)))
                {
                        return true;
                }
        }
        
        // also support new metro version which DOESN'T 
        // contain /avg so avg split part is path
        // valid domains are:
        //        search.yahoo.com, 
        //        xx.search.yahoo.com and
        //        search.yahoo.co.xx
        if (domain.indexOf("search.yahoo.co") != -1) 
        {
                // path (split avg) must start with search and
                // contain the avg toolbar parameter
                if (((path.indexOf("search?") == 0) ||
                        (path.indexOf("search;") == 0)) &&
                        (path.indexOf("fr=yhs-avg") != -1))
                {
                        return true;
                }
        }

        return false;
};
searchshield.AVGYahooSearchEngine.prototype.includeLink = function(tag)
{
        var href                = "";
        var outHref                = "";
        var findStr                = "";

        if (this.search.doc.body.className.toLowerCase() != "standard")
        {        // handle as std Yahoo results page
                return searchshield.YahooSearchEngine.prototype.includeLink(tag);
        }        

        // yahoo likes to encode the url
        href = unescape(tag.href);

        if (tag.target == "_top")
        {
                var da = href.indexOf("**");
                if (da != -1)
                        outHref = href.substring(da+2);
                else
                        outHref = href ;

                if (outHref.toLowerCase().indexOf("overture.") !== -1)
                        return false;
        }
        else if (!this.onlyPrimaries)
        {
                findStr = "&yargs=";
                var yargs = href.indexOf(findStr);
                if (yargs != -1)
                {
                        outHref = href.substring(yargs+findStr.length);
                        // check for prefix
                        if (outHref.indexOf("://") == -1)
                                outHref = "http://" + outHref;

                        // if inside an <I>, probably a paypal link, don't include
                        if (tag.parentNode && (tag.parentNode.tagName == "I"))
                                return false;
                } 
        }

        // filter domains
        // split the url based on '/'
        var parts = outHref.split('/');

        // Filter out domains that match any of the search engine's names
        if (!parts[2])
                return false;
                
        var domain = parts[2];
        if ((domain.indexOf("rdrjp.yahoo.com") != -1)        ||
                (domain.indexOf("rdrkrs.yahoo.com") != -1)        ||
                (domain.indexOf("rdrtpe.yahoo.com") != -1)        ||
                (domain.indexOf("rdrird.yahoo.com") != -1)        ||
                (domain.indexOf("rdrhk2.yahoo.com") != -1)        ||
                (domain.indexOf("rdrsg1.yahoo.com") != -1)        ||
                (domain.indexOf("rdrin2.yahoo.com") != -1)        ||
                (domain.indexOf("rdre1.yahoo.com") != -1)        ||
                (domain.indexOf("rdrw1.yahoo.com") != -1)                )
        {
                return false;
        }

        return outHref;
};
searchshield.AVGYahooSearchEngine.prototype.updateImage = function (hash, search, score, image, alt_image, flyover, click_thru, altClick_thru)
{
        // remove style that is set when alt image is applied
        this.updateImageStyle = {
                verticalAlign: null
        };
                
        // don't show verisign icon
        if (alt_image && (alt_image.length > 0))
                this.omitAltImage = true;
                
        var parent = searchshield.SearchEngine.prototype.updateImage;
        return parent.call(this, hash, search, score, image, alt_image, flyover, click_thru, altClick_thru);
};
///////////////    AVG YAHOO SEARCH ENGINE    ///////////////




///////////////    MSN SEARCH ENGINE    ///////////////
searchshield.MSNSearchEngine = function(search)
{
        searchshield.SearchEngine.call(this, search);
        this.onlyPrimaries = false;
};
searchshield.MSNSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.MSNSearchEngine.prototype.constructor = searchshield.MSNSearchEngine;
searchshield.MSNSearchEngine.prototype.name = "msn";
searchshield.MSNSearchEngine.prototype.validSearch = function(href)
{
        var uri;
        if (typeof(this.search) === 'undefined' || null === this.search)
                uri = searchshield.parseLink(href);
        else
                uri = this.search.uri;

        if(!uri || !uri.host)
                return false;

        var hostMatch        = false;
        var domain                = uri.host;

        // re stitch the uri path and query elements to
        // use existing logic
        var path = uri.path + uri.delimiter + uri.query;

        // For MSN the host must match:
        //        search.msn.com                OR
        //        search.live.com
        if (domain.indexOf("search.msn.co") > -1)
        {
                if (domain.charAt(13) == 'm')
                        hostMatch = true;
                else if ((domain.charAt(13) == '.') && (domain.length == 16))
                        hostMatch = true;
        }
        else if (domain.indexOf("search.live.co") > -1)
        {
                if (domain.charAt(14) == 'm')
                        hostMatch = true;
                else if ((domain.charAt(14) == '.') && (domain.length == 17))
                        hostMatch = true;
        }
        
        if (hostMatch)
        {
                if (path.indexOf("results.aspx") == 0)
                        return true;
        }

        return false;
};
searchshield.MSNSearchEngine.prototype.includeLink = function(tag)
{
        var outHref = false;
        
        // these don't seem common from Firefox, but they are in IE
        if (searchshield.DoesURLContain(tag.href, "g.msn.co"))
        {
                var qPos = tag.href.indexOf("?");
                if (qPos != -1)
                {
                        var postPart = tag.href.substring(qPos+1);
                        var dblAmp = postPart.indexOf("&&");
                        if (dblAmp != -1)
                        {
                                outHref = postPart.substring(0, dblAmp);
                                return outHref;
                        }
                }
        }
        else if (searchshield.DoesURLContain(tag.href, "r.msn.co"))
        {
                var element = tag;
                var parentNode = tag.parentNode;

                // top links - check for a CITE
                var spanElements = element.getElementsByTagName("CITE");
                if ((spanElements != null)                                && 
                        (spanElements.length > 0))
                {
                        outHref = spanElements[0].innerHTML;
                        // replace any nbsp's
                        outHref = outHref.replace("&nbsp;", " ");

                        // url is after the last space in the html, after the '-'
                        var space_pos = outHref.lastIndexOf(" ");
                        if (space_pos != -1)
                                outHref = outHref.slice(space_pos + 1);

                        outHref = searchshield.checkUrl(outHref);
                        return outHref;
                }
                
                // side links 
                if (element.lastChild != null)
                {
                        outHref = element.lastChild.innerHTML;
                        if ( outHref != null)
                        {
                                outHref = searchshield.checkUrl(outHref);
                                return outHref;
                        }
                }
        }
        else if (searchshield.DoesURLContain(tag.href, this.search.uri.host)                                        ||
                         searchshield.DoesURLContain(tag.href, ".live.com")                                        ||
                         searchshield.DoesURLContain(tag.href, "msn.")                                                ||
                         searchshield.DoesURLContain(tag.href, "msnscache.com")                                ||
                         searchshield.DoesURLContain(tag.href, "advertising.microsoft.co")        ||
                         searchshield.DoesURLContain(tag.href, "javascript:")                                ||
                         searchshield.DoesURLContain(tag.href, "go.microsoft.co")                        ||
                         searchshield.DoesURLContain(tag.href, "hotmail.co"))
        {
                // not a link
                return false;
        }
        else if (tag.id.toLowerCase() == "trademarks")
        {
                // don't link the trademark at the bottom of the page
                return false;
        }
        else
        {
                // include it
                return tag.href;
        }
};
///////////////    MSN SEARCH ENGINE    ///////////////




///////////////    BING SEARCH ENGINE    ///////////////
searchshield.BingSearchEngine = function(search)
{
        searchshield.SearchEngine.call(this, search);
};
searchshield.BingSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.BingSearchEngine.prototype.constructor = searchshield.BingSearchEngine;
searchshield.BingSearchEngine.prototype.name = "bing";
searchshield.BingSearchEngine.prototype.validSearch = function(href)
{
        var uri;
        if (typeof(this.search) === 'undefined' || null === this.search)
                uri = searchshield.parseLink(href);
        else
                uri = this.search.uri;

        if(!uri || !uri.host)
                return false;

        var hostMatch        = false;
        var domain                = uri.host;

        // re stitch the uri path and query elements to
        // use existing logic
        var path = uri.path + uri.delimiter + uri.query;
        
        // For bing the host must match:
        //        www.bing.com or www.bing.net
        //        xx.bing.com or xx.bing.net where xx is a country code
        //        bing.com.xx where xx is a country code
        //        bing.search.xxxx.net where xxxx may be something like daum
        if ((domain.indexOf("www.bing.com") !== -1) ||
                (domain.indexOf("www.bing.net") !== -1) ||
                (domain.indexOf("bing.net") !== -1))
        {
                hostMatch = true;
        }
        else if ((domain.indexOf("bing.search.") !== -1) && 
                         (domain.indexOf(".net") === (domain.length-4))) 
        {        //bing.search.xxxx.net
                hostMatch = true;
        }
        else
        {        // xx.bing.com or bing.com.xx
                var domainLen = domain.length;
                var tldPos = domain.indexOf(".bing.com");
                if (tldPos > -1)
                {
                        if ((domainLen - tldPos) == 9)
                                hostMatch = true;
                }        
        }
        
        if (hostMatch)
        {
                if (path.indexOf("search?") == 0)
                        return true;
        }

        return false;

};
searchshield.BingSearchEngine.prototype.includeLink = function(tag)
{
        var outHref = false;

        if (tag.tagName == 'IMG')
        {        //no images 
                return false;
        }
                
        if (tag.href.charAt(0) == '/')
        {        //no relative links
                return false;
        }

        if (tag.id.toLowerCase() == "trademarks")
        {
                // don't link the trademark at the bottom of the page
                return false;
        }
        
        if ((tag.parentNode) &&
                (tag.parentNode.id.toLowerCase() == "sc_stc"))
        {        // don't verdict the social sites - our verdict doesn't fit
                return false;
        }
        else if (!!searchshield.getParentNodeByClassName("sw_t",tag,3))
        {        // no links in page header
                return false;
        }
        else if (searchshield.DoesURLContain(tag.href, "r.msn.co") ||
                         searchshield.DoesURLContain(tag.href, "overture.com"))
        {        // france has r.msn.co and italy has overture.com sponsored links
                // with the link in CITE element
                
                var spanElements = null;
                
                // top links - check for a CITE
                spanElements = tag.getElementsByTagName("CITE");
                if ((spanElements == null) || (spanElements.length <= 0))
                {
                        if (tag.parentNode && tag.parentNode.parentNode)
                                spanElements = tag.parentNode.parentNode.getElementsByTagName("CITE");
                }
                
                if ((spanElements != null) && (spanElements.length > 0))
                {
                        outHref = spanElements[0].innerHTML;
                        if (outHref != null)
                        {
                                // replace any nbsp's
                                outHref = outHref.replace("&nbsp;", " ");

                                // url is after the last space in the html, after the '-'
                                var space_pos = outHref.lastIndexOf(" ");
                                if (space_pos != -1)
                                        outHref = outHref.slice(space_pos + 1);

                                outHref = searchshield.checkUrl(outHref);

                                // save the link
                                return outHref;
                        }
                }
                
                // side links 
                if (tag.lastChild != null)
                {
                        outHref = tag.lastChild.innerHTML;
                        if (outHref != null)
                        {
                                outHref = searchshield.checkUrl(outHref);
                                // save the link
                                return outHref;
                        }
                }
        }
        // no sponsored links for now 
        else if (searchshield.DoesURLContain(tag.href, this.search.uri.host)        ||
                 searchshield.DoesURLContain(tag.href, ".live.com")                                ||
                 searchshield.DoesURLContain(tag.href, ".bing.com")                                ||
                 searchshield.DoesURLContain(tag.href, ".bing.net")                                ||
                 searchshield.DoesURLContain(tag.href, ".daum.net")                                ||
                 searchshield.DoesURLContain(tag.href, ".gmarket.co")                        ||
                 searchshield.DoesURLContain(tag.href, ".multimap.com")                        ||
                 searchshield.DoesURLContain(tag.href, "msn.")                                        ||
                 searchshield.DoesURLContain(tag.href, "ms.ciao.")                                ||
                 searchshield.DoesURLContain(tag.href, "ms.ciao-")                                ||
                 searchshield.DoesURLContain(tag.href, "advertising.microsoft.co")        ||
                 searchshield.DoesURLContain(tag.href, "javascript:")                                ||
                 searchshield.DoesURLContain(tag.href, "go.microsoft.co")                        ||
                 searchshield.DoesURLContain(tag.href, "hotmail.co")                                        ||
                 searchshield.DoesURLContain(tag.href, "cc.bingj.com")                                ||
                 searchshield.DoesURLContain(tag.href, "microsofttranslator.com")        ||
                 searchshield.DoesURLContain(tag.href, ".engkoo.com")                                ||
                 searchshield.DoesURLContain(tag.href, "sealinfo.verisign.com")                ||
                 searchshield.DoesURLContain(tag.href, "explabs.com")                                ||
                 searchshield.DoesURLContain(tag.href, "onlinehelp.microsoft.com"))
        {
                // not a link
                return false;
        }
        else
                return tag.href;
};
searchshield.BingSearchEngine.prototype.addImage = function(node, image, hidden)
{
        var element        = node.element;
        var parentNode         = node.element.parentNode;
        var grandParentNode = !!parentNode ? parentNode.parentNode : null;

        // if there are redundant links in the same grandparent then skip them
        if (!!grandParentNode)
        {
                gpChildren = grandParentNode.childNodes;
                for (var i=0; i < gpChildren.length; i++)
                {
                        if (!!element.href && gpChildren[i].tagName == "A" && gpChildren[i].href == element.href)
                                return;
                }
        }

        var parent = searchshield.SearchEngine.prototype.addImage;
        return parent.call(this, node, image, hidden);
};
///////////////    BING SEARCH ENGINE    ///////////////




///////////////    BAIDU SEARCH ENGINE    ///////////////
searchshield.BaiduSearchEngine = function(search)
{
        searchshield.SearchEngine.call(this, search);
};
searchshield.BaiduSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.BaiduSearchEngine.prototype.constructor = searchshield.BaiduSearchEngine;
searchshield.BaiduSearchEngine.prototype.name = "baidu";
searchshield.BaiduSearchEngine.prototype.validSearch = function(href)
{
        var uri;
        if (typeof(this.search) === 'undefined' || null === this.search)
                uri = searchshield.parseLink(href);
        else
                uri = this.search.uri;

        if(!uri || !uri.host)
                return false;

        var hostMatch        = false;
        var domain                = uri.host;

        // re stitch the uri path and query elements to
        // use existing logic
        var path = uri.path + uri.delimiter + uri.query;
        
        if (domain == "www.baidu.com" || path.indexOf("testBaidu") !== -1)
                hostMatch = true;
                
        if (hostMatch)
        {
                if (path.indexOf("s?") == 0)
                        return true;
        }

        return false;
};
searchshield.BaiduSearchEngine.prototype.includeLink = function(tag)
{                
                if (tag.className && tag.className == "m")
                        return false;

                if (searchshield.DoesURLContain(tag.href, this.search.uri.host))
                        return false;
                else 
                {
                        // no link to self
                        var traverseElement = tag.parentNode;
                        while ( traverseElement && traverseElement.className != "tbody")
                        {
                                if (traverseElement.className == "f")
                                        return tag.href;

                                traverseElement = traverseElement.parentNode;
                        }
                        
                        return false;
                }

};
searchshield.BaiduSearchEngine.prototype.addImage = function(node, image, hidden)
{
        this.addImageStyle = {
                position: "relative",
                top: "0.05em"
        };
                
        var parent = searchshield.SearchEngine.prototype.addImage;
        return parent.call(this, node, image, hidden);
};
searchshield.BaiduSearchEngine.prototype.updateImage = function (hash, search, score, image, alt_image, flyover, click_thru, altClick_thru)
{
        // remove style that is set when alt image is applied
        this.updateImageStyle = {
                verticalAlign: null
        };
        
        var parent = searchshield.SearchEngine.prototype.updateImage;
        return parent.call(this, hash, search, score, image, alt_image, flyover, click_thru, altClick_thru);
};
///////////////    BAIDU SEARCH ENGINE    ///////////////




///////////////    EARTHLINK SEARCH ENGINE    ///////////////
searchshield.EarthlinkSearchEngine = function(search)
{
        searchshield.SearchEngine.call(this, search);
        this.onlyPrimaries = false;

        this.addAnchorStyle = {
                position: "static"
        };
};
searchshield.EarthlinkSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.EarthlinkSearchEngine.prototype.constructor = searchshield.EarthlinkSearchEngine;
searchshield.EarthlinkSearchEngine.prototype.name = "earthlink";
searchshield.EarthlinkSearchEngine.prototype.validSearch = function(href)
{
        var uri;
        if (typeof(this.search) === 'undefined' || null === this.search)
                uri = searchshield.parseLink(href);
        else
                uri = this.search.uri;

        if(!uri || !uri.host)
                return false;

        var hostMatch        = false;
        var domain                = uri.host;

        // re stitch the uri path and query elements to
        // use existing logic
        var path = uri.path + uri.delimiter + uri.query;

        // For EarthLink the host must match:
        //        search.earthlink.net
        if (("search.earthlink.net" == domain)        &&
                (path.indexOf("search?") == 0))
        {
                return true;
        }

        return false;
};
searchshield.EarthlinkSearchEngine.prototype.includeLink = function(tag)
{
        var outHref        = "";
        var findStr        = "";

        // check for an anchor
        if (tag.tagName == "A")
        {
                // check for sponsored
                if (tag.id.indexOf("a") == 0)
                {
                        var q = tag.href.indexOf("&q=");
                        var qlen = 3;
                        if (q == -1)
                        {
                                q = tag.href.indexOf("&adurl=");
                                qlen = 7;
                                if (q == -1)
                                        return false;
                        }

                        // find end of url
                        var end = tag.href.indexOf("&", q+qlen);
                        if (end < 0)
                                end = tag.href.length;

                        // add the link
                        outHref = tag.href.substring(q+qlen, end);
                        
                        if (searchshield.FilterUrl(outHref, this.filter_urls))
                                return false;
                                
                        return outHref;
                }

                // don't search url's to self
                if ((tag.href.indexOf("://") == -1) || searchshield.DoesURLContain(tag.href, this.search.uri.host))
                        return false;

                // if a normal web result add it
                if (tag.parentNode && (tag.parentNode.tagName == "H3") &&
                        tag.parentNode.parentNode && (tag.parentNode.parentNode.tagName == "LI") &&
                        tag.parentNode.parentNode.parentNode && (tag.parentNode.parentNode.parentNode.tagName == "UL"))
                {
                        if (searchshield.FilterUrl(tag.href, this.filter_urls))
                                return false;
                                
                        return tag.href;
                }
        }
        
        return false;
};
///////////////    EARTHLINK SEARCH ENGINE    ///////////////




///////////////    AOL SEARCH ENGINE    ///////////////
searchshield.AOLSearchEngine = function(search)
{
        searchshield.SearchEngine.call(this, search);
};
searchshield.AOLSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.AOLSearchEngine.prototype.constructor = searchshield.AOLSearchEngine;
searchshield.AOLSearchEngine.prototype.name = "aol";
searchshield.AOLSearchEngine.prototype.validSearch = function(href)
{
        var uri;
        if (typeof(this.search) === 'undefined' || null === this.search)
                uri = searchshield.parseLink(href);
        else
                uri = this.search.uri;

        if(!uri || !uri.host)
                return false;
        
        var domain = uri.host;
        //path may be 'aol/search' or 'search'
        var pathArray = uri.path.split("/");
        var aol = pathArray[0];
        // re stitch the uri path and query elements
        // to use existing logic
        var path = (undefined == pathArray[1]) ? pathArray[0] : pathArray[1];
                path += uri.delimiter + uri.query;

        if ("search.aol.com" == domain)
        {
                if ((aol == "aol") &&
                        (path.indexOf("search?") == 0))
                {
                        return true;
                }
        }
        
        return false;
};
searchshield.AOLSearchEngine.prototype.includeLink = function(tag)
{
        if (searchshield.DoesURLContain(tag.href, this.search.uri.host))
                return false;
        
        // sponsored links - google
        if ((tag.className) && (tag.className.indexOf("slLink") != -1))
        {        //parse for embedded href

                if (tag.href.indexOf("/aclk?sa=") == -1)
                        return false;

                var adurl = tag.href.indexOf("&adurl=http");
                if (adurl != -1)
                {
                        var urlPos = adurl+7; // puts it on the http
                        var outHref = tag.href.substring(urlPos);

                        // extract any fragment text, do not unescape
                        var pound = outHref.indexOf("#");        
                        if (pound != -1)
                        {
                                var fragment = outHref.substring(pound);
                                outHref = outHref.substring(0, pound);
                                outHref = unescape(outHref);
                                outHref += fragment;
                                if (searchshield.FilterUrl(outHref, this.filter_urls))
                                        return false;

                                return outHref;
                        }

                        outHref = unescape(outHref);
                        if (outHref.indexOf("?") == -1)
                        {
                                var ampPos = outHref.indexOf("&");
                                if (ampPos != -1)
                                        outHref = outHref.substring(0, ampPos);
                        }
                                
                        if (searchshield.FilterUrl(outHref, this.filter_urls))
                                return false;

                        return outHref;
                }

                return false;
        }

        if (tag.className == "find")
                return tag.href;
                
        return false;
};
searchshield.AOLSearchEngine.prototype.addImage = function(node, image, hidden)
{
        this.addImageStyle = {
                display: "inline"
        };

        this.addAnchorStyle = {
                display: null
        };
                
        var parent = searchshield.SearchEngine.prototype.addImage;
        return parent.call(this, node, image, hidden);
};
searchshield.AOLSearchEngine.prototype.updateImage = function (hash, search, score, image, alt_image, flyover, click_thru, altClick_thru)
{
        // remove style that is set when alt image is applied
        this.updateImageStyle = {
                verticalAlign: null,
                display: "inline"
        };
                
        var parent = searchshield.SearchEngine.prototype.updateImage;
        return parent.call(this, hash, search, score, image, alt_image, flyover, click_thru, altClick_thru);
};
searchshield.AOLSearchEngine.prototype.insertNodes = function(node, doc)
{
        var element = node.element;
        var score = node.score;

        if (element && element.className && element.className.indexOf("slLink") != -1)
        {        //sponsored links only

                // for alt image
                if (score == searchshield.SCORE_SS_VERISIGN)
                        return [element.nextSibling, element.parentNode];

                // for verdict image
                var cN = element.childNodes;
                var cnLen = cN.length;
                for (var i=0; i < cnLen; i++)
                {
                        if ((cN[i].nodeType == 1) && (cN[i].nodeName == 'SPAN') && (cN[i].className == 'title'))
                                return [cN[i].nextSibling, cN[i].parentNode];
                }
        }
        else
        {
                var parent = searchshield.SearchEngine.prototype.insertNodes;
                return parent.call(this, node, doc);
        }
};
///////////////    AOL SEARCH ENGINE    ///////////////




///////////////    ASK SEARCH ENGINE    ///////////////
searchshield.AskSearchEngine = function(search)
{
        searchshield.SearchEngine.call(this, search);
};
searchshield.AskSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.AskSearchEngine.prototype.constructor = searchshield.AskSearchEngine;
searchshield.AskSearchEngine.prototype.name = "ask";
searchshield.AskSearchEngine.prototype.validSearch = function(href)
{
        var uri;
        if (typeof(this.search) === 'undefined' || null === this.search)
                uri = searchshield.parseLink(href);
        else
                uri = this.search.uri;

        if(!uri || !uri.host)
                return false;
        
        var domain= uri.host;
        // re stitch the uri path and query elements
        // to use existing logic
        var path = uri.path + uri.delimiter + uri.query;
        
        if ("www.ask.com" == domain)
        {
                if (path.indexOf("web?") == 0)
                        return true;
        }

        return false;
};
searchshield.AskSearchEngine.prototype.includeLink = function(tag)
{
        var outHref        = "";
        var findStr        = "";

        if (searchshield.DoesURLContain(tag.href, this.search.uri.host))
                return false;
        
        if ((tag.className) && (tag.className.indexOf("nu") != -1) && (tag.className.indexOf("info") == -1)) 
        {
                // exclude green links
                if ((tag.firstChild) &&
                        (tag.firstChild.className) &&
                        (tag.firstChild.className.indexOf('attrib') == 0))
                {
                        return false;
                }

                // ads link to google with class nu
                findStr = "www.google.com";
                if (tag.href.indexOf(findStr) != 0)
                {
                        if (tag.href.indexOf(findStr + "/aclk?sa=") != -1)
                        {        
                                findStr = "&adurl=http";
                                var pos = tag.href.indexOf(findStr);
                                if (pos != -1)
                                {
                                        pos += 7;
                                        outHref = tag.href.substring(pos);
                                        outHref = unescape(outHref);
                                        if (searchshield.FilterUrl(outHref, this.filter_urls))
                                                        return false;
                                        return outHref;
                                }
                        }
                }
                else
                {        // ad not to google just use href
                        outHref = tag.href;
                        if (searchshield.FilterUrl(outHref, this.filter_urls))
                                return false;
                        return outHref;
                }
        }
        // primary results have class containing title or L2 ( Wikipedia links )
        else if ((tag.className) && ((tag.className.indexOf("title") != -1) || (tag.className.toLowerCase() == "l2")))
        {
                outHref = tag.href;
                if (searchshield.FilterUrl(outHref, this.filter_urls))
                        return false;
                return outHref;
        }
        
        return false;
};
///////////////    ASK SEARCH ENGINE    ///////////////




///////////////    ALTAVISTA SEARCH ENGINE    ///////////////
searchshield.AltaVistaSearchEngine = function(search)
{
        searchshield.SearchEngine.call(this, search);
};
searchshield.AltaVistaSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.AltaVistaSearchEngine.prototype.constructor = searchshield.AltaVistaSearchEngine;
searchshield.AltaVistaSearchEngine.prototype.name = "altavista";
searchshield.AltaVistaSearchEngine.prototype.validSearch = function(href)
{
        var uri;
        if (typeof(this.search) === 'undefined' || null === this.search)
                uri = searchshield.parseLink(href);
        else
                uri = this.search.uri;

        if(!uri || !uri.host)
                return false;
        
        var domain= uri.host;
        
        // re stitch the uri path and query elements
        // to use existing logic
        var path = uri.path + uri.delimiter + uri.query;

        // www.atlavista.com ---> now http://us.yhs4.search.yahoo.com/yhs/search?fr=altavista&fr=altavista&itag=ody&q=warez&kgs=1&kls=0
        // xx.altavista.com where xx is a country code
        var hostMatch = false;
        if ("www.altavista.com" == domain)
        {
                hostMatch = true;
        }
        else
        {
                // xx.altavista.com
                var pDest = domain.indexOf(".altavista.com");
                if ((pDest != -1 ) && ((domain.length - pDest) == 14))
                {
                        hostMatch = true;
                }
                else
                {
                        // a reference to altavista must be present in yahoo search url
                        var pRef = (uri.qsArray.fr && uri.qsArray.fr == 'altavista');
                        pDest = domain.indexOf("search.yahoo.com");
                        if (pDest != -1 && pRef)
                                hostMatch = true;
                }
        }

        if (hostMatch)
        {
                //path must start with web/results?
                if ((path.indexOf("yhs/search?") == 0)        ||
                        (path.indexOf("search;") == 0)                ||
                        (path.indexOf("yhs/search;") == 0)        ||
                        (path.indexOf("web/results?") == 0)||
                        (path.indexOf("fr=altavista") != -1))
                {
                        return true;
                }
        }
        
        return false;
};
searchshield.AltaVistaSearchEngine.prototype.includeLink = function(tag)
{
        var outHref        = "";
        var findStr        = "";

        // initial checks
        if ((!tag.href)        || 
                (tag.href.charAt(0) == '#') ||
                (tag.href.indexOf("javascript:") == 0))
        {
                return false;
        }
                
        if (searchshield.DoesURLContain(tag.href, this.search.uri.host))
                return false;
                
        if ((tag.className == "spt") || 
                (tag.className == "res") ||
                (tag.className == "yschttl spt"))
        {
                findStr = "/**";
                var pos = tag.href.indexOf(findStr);
                if (pos != -1)
                {
                        pos += 3;
                        outHref = tag.href.substring(pos);
                        outHref = unescape(outHref);
                        
                        // no results for overture.com & no yahoo domains
                        chkHref = outHref.toLowerCase();
                        if (chkHref.indexOf("overture.") != -1)
                                return false;

                        // split the url based on '/'
                        var parts = outHref.split('/');

                        // only need a domain
                        if ((parts != null) && (parts[2] != null))
                        {
                                var domain = parts[2];
                                if ((domain.indexOf("rdrjp.yahoo.com") != -1)        ||
                                        (domain.indexOf("rdrkrs.yahoo.com") != -1)        ||
                                        (domain.indexOf("rdrtpe.yahoo.com") != -1)        ||
                                        (domain.indexOf("rdrird.yahoo.com") != -1)        ||
                                        (domain.indexOf("rdrhk2.yahoo.com") != -1)        ||
                                        (domain.indexOf("rdrsg1.yahoo.com") != -1)        ||
                                        (domain.indexOf("rdrin2.yahoo.com") != -1)        ||
                                        (domain.indexOf("rdre1.yahoo.com") != -1)        ||
                                        (domain.indexOf("rdrw1.yahoo.com") != -1)                )
                                {
                                        return false
                                }
                        }

                        return outHref;
                }
                else
                {
                        return tag.href;
                }
        }
        
        return false;
};
searchshield.AltaVistaSearchEngine.prototype.getImgElement = function (element)
{
        while (element != null) 
        {
                element = element.nextSibling;
                if (element != null)
                {
                        if ((element.id == null) || (element.id.indexOf("LXPLSS_") == -1))
                        {   // not our id but hit another anchor no verdict
                                if (element.tagName == "A")
                                {
                                        element = null;
                                        break;
                                }
                        }
                        else if (element.tagName == "A")
                                break;
                }
         }
                
        var rtnElem = !!element ? element.firstChild : element;
        return rtnElem;
};
///////////////    ALTAVISTA SEARCH ENGINE    ///////////////




///////////////    YANDEX SEARCH ENGINE    ///////////////
searchshield.YandexSearchEngine = function(search)
{
        searchshield.SearchEngine.call(this, search);
};
searchshield.YandexSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.YandexSearchEngine.prototype.constructor = searchshield.YandexSearchEngine;
searchshield.YandexSearchEngine.prototype.name = "yandex";
searchshield.YandexSearchEngine.prototype.validSearch = function(href)
{
        var uri;
        if (typeof(this.search) === 'undefined' || null === this.search)
                uri = searchshield.parseLink(href);
        else
                uri = this.search.uri;

        if(!uri || !uri.host)
                return false;
        
        var domain= uri.host;
        // re stitch the uri path and query elements
        // to use existing logic
        var path = uri.path + uri.delimiter + uri.query;

        if (((domain.indexOf("yandex.ru") > -1) ||
                (domain.indexOf("yandex.com") > -1)) &&
                (path.indexOf("yandsearch?") == 0))
        {
                return true;
        }
        
        return false;
};
searchshield.YandexSearchEngine.prototype.includeLink = function(tag)
{
        if (tag.href.indexOf("/search") != -1)
        {
                return false;
        }
        
        if (searchshield.DoesURLContain(tag.href, this.search.uri.host)        ||
                searchshield.DoesURLContain(tag.href, ".yandex.net")                ||
                searchshield.DoesURLContain(tag.href, ".yandex.ru")                        ||
                searchshield.DoesURLContain(tag.href, "moikrug.ru")                        ||
                searchshield.DoesURLContain(tag.href, "ya.ru")                                ||
                searchshield.DoesURLContain(tag.href, ".yandex.com")                ||
                searchshield.DoesURLContain(tag.href, "yandex.st"))
        {
                return false;
        }
                
        parentNode = tag.parentNode;
        if ((tag.parentNode)                        && 
                (tag.parentNode.parentNode)        &&
                (tag.parentNode.parentNode.className.toLowerCase() == "moreinfo"))
        {
                return false;
        }
        
        return tag.href;
};
searchshield.YandexSearchEngine.prototype.getImgElement = function (element)
{
        while (element != null) 
        {
                element = element.nextSibling;
                if (element != null)
                {
                        if ((element.id == null) || (element.id.indexOf("LXPLSS_") == -1))
                        {   // not our id but hit another anchor no verdict
                                if (element.tagName == "A")
                                {
                                        element = null;
                                        break;
                                }
                        }
                        else if (element.tagName == "A")
                                break;
                }
         }
                
        var rtnElem = !!element ? element.firstChild : element;
        return rtnElem;
};
///////////////    YANDEX SEARCH ENGINE    ///////////////




///////////////    SEZNAM SEARCH ENGINE    ///////////////
searchshield.SeznamSearchEngine = function(search)
{
        searchshield.SearchEngine.call(this, search);
};
searchshield.SeznamSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.SeznamSearchEngine.prototype.constructor = searchshield.SeznamSearchEngine;
searchshield.SeznamSearchEngine.prototype.name = "seznam";
searchshield.SeznamSearchEngine.prototype.validSearch = function(href)
{
        var uri;
        if (typeof(this.search) === 'undefined' || null === this.search)
                uri = searchshield.parseLink(href);
        else
                uri = this.search.uri;

        if(!uri || !uri.host)
                return false;
        
        var domain= uri.host;
        // re stitch the uri path and query elements
        // to use existing logic
        var path = uri.path + uri.delimiter + uri.query;

        if ((domain.indexOf("search.seznam.cz") > -1)        &&
                ((path.indexOf("?") == 0) || (path.indexOf("svet") == 0)))
        {
                return true;
        }
        
        return false;
};
searchshield.SeznamSearchEngine.prototype.includeLink = function(tag)
{
        if (searchshield.DoesURLContain(tag.href, this.search.uri.host))
                return false;
        
        var parentNode = tag.parentNode;
        if (parentNode)
        {
                var grandParentNode = tag.parentNode.parentNode;
                if ((parentNode.tagName == "SPAN") && 
                        ((parentNode.className.toLowerCase() == "sklik-url") ||
                        (parentNode.className.toLowerCase() == "sklik-title")))
                {        // locate the real url and unencode it
                        var urlPos = tag.href.indexOf("&url=http");

                        if (urlPos != -1)
                        {
                                urlPos += 5;        
                                outHref = tag.href.substring(urlPos);
                                outHref = unescape(outHref);

                                return outHref;
                        }
                }
                else if (grandParentNode) 
                {
                        var greatGrandParentNode = tag.parentNode.parentNode.parentNode;
                        if ((grandParentNode.tagName == "DIV") &&
                                ((grandParentNode.className.toLowerCase() == "text") || (grandParentNode.className.toLowerCase() == "hlasky otz")))
                        {        // standard link
                                return tag.href;
                        }
                        else if (greatGrandParentNode && greatGrandParentNode.tagName == "DIV" &&
                                        (greatGrandParentNode.className.toLowerCase() == "hotlinks")) 
                        {        // hint link
                                return tag.href;
                        }
                        
                }
        }
        
        return false;
};
searchshield.SeznamSearchEngine.prototype.updateImage = function (hash, search, score, image, alt_image, flyover, click_thru, altClick_thru)
{
        this.elementAttribute = {
                width: "18",
                height: "18"
        };

        this.updateImageStyle = {
                width: "18px",
                height: "18px"
        };
        
        var parent = searchshield.SearchEngine.prototype.updateImage;
        return parent.call(this, hash, search, score, image, alt_image, flyover, click_thru, altClick_thru);
};
///////////////    SEZNAM SEARCH ENGINE    ///////////////




///////////////    WEBHLEDANI SEARCH ENGINE    ///////////////
searchshield.WebhledaniSearchEngine = function(search)
{
        searchshield.SearchEngine.call(this, search);
};
searchshield.WebhledaniSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.WebhledaniSearchEngine.prototype.constructor = searchshield.WebhledaniSearchEngine;
searchshield.WebhledaniSearchEngine.prototype.name = "webhledani";
searchshield.WebhledaniSearchEngine.prototype.validSearch = function(href)
{
        var uri;
        if (typeof(this.search) === 'undefined' || null === this.search)
                uri = searchshield.parseLink(href);
        else
                uri = this.search.uri;

        if(!uri || !uri.host)
                return false;
        
        var domain= uri.host;
        // re stitch the uri path and query elements
        // to use existing logic
        var path = uri.path + uri.delimiter + uri.query;

        if ((domain.indexOf("webhledani.cz") > -1)        &&
                (path.indexOf("results.aspx?") == 0))
        {
                return true;
        }
        
        return false;
};
searchshield.WebhledaniSearchEngine.prototype.includeLink = function(tag)
{
        var parentNode = tag.parentNode;
        
        if (searchshield.DoesURLContain(tag.href, this.search.uri.host))
        {
                if ( tag.href.indexOf("/redir.aspx?") != -1)
                {
                        attrNode = tag.attributes;
                        if ( attrNode == null )
                                return false;

                        var outHref = attrNode.getNamedItem("onmouseover").nodeValue;
                        if ( outHref == null )
                                return false;
        
                        var findStr = "window.status=";
                        if (outHref.indexOf(findStr)!= -1)
                        {
                                // get text before first semicolon
                                var semicolon = outHref.indexOf(";");
                                if (semicolon > -1)
                                        outHref = outHref.substring(findStr.length, semicolon);

                                // strip quotation marks
                                outHref = outHref.replace(/['"]/g, "");

                                var space = outHref.indexOf(" ");
                                var firstDot = outHref.indexOf(".");

                                if ((space > -1) && (space < firstDot))
                                        outHref = outHref.substring(space+1);

                                outHref = searchshield.checkUrl(outHref);
                                return outHref;
                        }
                }
        }

        return false;
};
searchshield.WebhledaniSearchEngine.prototype.insertNodes = function(node, doc)
{
        var element = node.element;
        var score = node.score;

        // for alt image
        if (score == searchshield.SCORE_SS_VERISIGN)
                return [element.nextSibling, element.parentNode];

        // for verdict image
        var cN = element.childNodes;
        var cnLen = cN.length;
        for (var i=0; i < cnLen; i++)
        {
                if (cN[i].nodeType == 1 && cN[i].nodeName == 'SPAN' && cN[i].className == 'sl')
                {
                        if (!this.cssUpdated)
                        {
                                this.cssUpdated = true;

                                // need to add style to make verdicts display inline
                                var docStyle = doc.styleSheets[0];
                                if (docStyle && docStyle.addRule)
                                {        //IE
                                        docStyle.addRule('#s a','display:inline');
                                        docStyle.addRule('#s p a .sl','display:inline');
                                }
                                else if (docStyle && docStyle.insertRule)
                                {
                                        docStyle.insertRule('#s a {display:inline}', docStyle.cssRules.length);
                                        docStyle.insertRule('#s p a .sl {display:inline}', docStyle.cssRules.length);
                                }
                        }

                        return [cN[i].nextSibling, cN[i].parentNode];
                }
        }

        // don't display anything
        return [null, null];
};
///////////////    WEBHLEDANI SEARCH ENGINE    ///////////////




///////////////    EBAY SEARCH ENGINE    ///////////////
searchshield.eBaySearchEngine = function(search)
{
        searchshield.SearchEngine.call(this, search);
};
searchshield.eBaySearchEngine.prototype = new searchshield.SearchEngine();
searchshield.eBaySearchEngine.prototype.constructor = searchshield.eBaySearchEngine;
searchshield.eBaySearchEngine.prototype.name = "ebay";
searchshield.eBaySearchEngine.prototype.validSearch = function(href)
{
        var uri;
        if (typeof(this.search) === 'undefined' || null === this.search)
                uri = searchshield.parseLink(href);
        else
                uri = this.search.uri;

        if(!uri || !uri.host)
                return false;
        
        var domain= uri.host;
        // shop.ebay.xx
        // shop.xxxx.ebay.xx        like shop.benl.ebay.be
        // search.auction.co.kr 
        var path = uri.path + uri.delimiter + uri.query;
        
        if ((domain.indexOf("shop.ebay") > -1)        ||
                (domain.indexOf("shop.benl.ebay") > -1))
        {
                if ((path.indexOf("?_from=") == 0)        ||
                        (path.indexOf("i.html") > -1))
                {
                        return true;
                }
        }
        
        // ebay.se
        if ((domain.indexOf("search.eim.ebay") > -1) &&
                ((path.indexOf("?kw=") > -1) || (path.indexOf("?ev=") > -1)))
        {
                return true;
        }
        
        if ((domain.indexOf("search.auction.co.kr") > -1 ) &&
                ((path.indexOf("?keyword=") > -1)))
        {
                // would normally set these properties in the constructor or in an
                // overriding function but they're only required for this domain
                 
                // links are in iframes
                this.processFrames = true;
                
                // must downsize verdicts for proper display
                this.elementAttribute = {
                        width: "16",
                        height: "16"
                };
                this.updateImageStyle = {
                        width: "16px",
                        height: "16px"
                };
                
                return true;
        }

        // latin america ebay
        // listado.mercadolibre.com.xx or listado.mercadolibre.co.xx
        //   or listado.mercadolibre.xx or
        //   category.mercadolibre.com.xx or listado.mercadolibre.xx/category
        // lista.mercadolivre.com.xx or lista.mercadolivre.com.xx/category
        if ((domain.indexOf("www.") == -1) &&
                ((domain.indexOf(".mercadolibre.") > -1 ) ||
                 (domain.indexOf(".mercadolivre.") > -1 ))) 
        {
                return true;
        }
        return false;
};
searchshield.eBaySearchEngine.prototype.includeLink = function(tag)
{
        var parentNode = null;
        var outHref = false;
        
        if (searchshield.DoesURLContain(tag.href, this.search.uri.host))
                return false;
        
        if ( tag.href.indexOf(".ebayrtm.com/clk?") > -1 )
        {
                if ( tag.title == null || tag.title.length < 0 )
                        return false;
                                        
                outHref = searchshield.removeHtmlTags(tag.title);
                if (outHref.indexOf(" ") == -1)
                {        // no spaces
                        if (outHref.indexOf(".") > -1)
                        {        // at least one dot 
                                if (outHref.indexOf(this.search.uri.host) == -1)
                                {        // no host
                                        if (outHref.toLowerCase().indexOf("ebay.com") == -1)
                                        {
                                                return outHref;
                                        }
                                }
                        }
                }                        
        }
        // ebay.se - Google ads
        parentNode = tag.parentNode;
        if (parentNode && (parentNode.className.toLowerCase() == "google-ad-link"))
        {
                if (tag.href.indexOf("/aclk?sa=") != -1)
                {        
                        findStr = "&adurl=http";
                        var urlPos        = tag.href.indexOf(findStr);
                        if (urlPos != -1)
                        {
                                urlPos += 7; // puts it on the http
                                outHref = tag.href.substring(urlPos);
                                
                                // extract any fragment text, shouldn't be unescaped
                                var pound = outHref.indexOf("#");        
                                if (pound != -1)
                                {
                                        var fragment = outHref.substring(pound);
                                        outHref = outHref.substring(0, pound);
                                        outHref = unescape(outHref);
                                        outHref += fragment;
                                        if (searchshield.FilterUrl(outHref, this.filter_urls))
                                                return false;

                                        return outHref;
                                }

                                outHref = unescape(outHref);
                                if (outHref.indexOf("?") == -1)
                                {
                                        var ampPos = outHref.indexOf("&");
                                        if (ampPos != -1)
                                                outHref = outHref.substring(0, ampPos);
                                }
                                
                                if (searchshield.FilterUrl(outHref, this.filter_urls))
                                        return false;
                                return outHref;
                        }
                }
        }
        
        // auction.co.kr
        parentNode = tag.parentNode;
        if (parentNode && (parentNode.className.toLowerCase() == "link"))
        {
                if (tag.href.indexOf("adcr.naver.com") > -1)
                {
                        outHref = tag.innerText;
                        if ((outHref == null) || (outHref.length < 0))
                                return false;
                                
                        return outHref;
                }
        }
        
        // latin america ebay
        if ( tag.href.toLowerCase().indexOf("clickcounter?") > -1 )
        {
                var spanElements = tag.getElementsByTagName("span");
                if ((spanElements != null)                                && 
                        (spanElements.length > 0))
                {
                        if ( spanElements[0].className.toLowerCase() == "mclics-url" )
                        {
                                outHref = spanElements[0].innerHTML;
                                if ( outHref == null || outHref.length < 0 )
                                        return false;
                                outHref = searchshield.removeHtmlTags(outHref);
                                if (outHref.indexOf(" ") == -1)
                                {        // no spaces
                                        if (outHref.indexOf(".") > -1)
                                        {        // at least one dot 
                                                if (outHref.toLowerCase().indexOf("mercado") == -1)
                                                {
                                                        return outHref;
                                                }
                                        }
                                }
                        }
                }
        }
        
        return false;
};
///////////////    EBAY SEARCH ENGINE    ///////////////




///////////////    DIGG SEARCH ENGINE    ///////////////
searchshield.DiggSearchEngine = function(search)
{
        searchshield.SearchEngine.call(this, search);
        this.new_links        = false;
};
searchshield.DiggSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.DiggSearchEngine.prototype.constructor = searchshield.DiggSearchEngine;
searchshield.DiggSearchEngine.prototype.name = "digg";
searchshield.DiggSearchEngine.prototype.validSearch = function(href)
{
        var uri;
        if (typeof(this.search) === 'undefined' || null === this.search)
                uri = searchshield.parseLink(href);
        else
                uri = this.search.uri;

        if(!uri || !uri.host)
                return false;
        
        var domain= uri.host;
        // re stitch the uri path and query elements
        // to use existing logic
        var path = uri.path + uri.delimiter + uri.query;
        
        if ((domain.indexOf("digg.com") > -1)        &&
                (path.indexOf("/ad") == -1))
        {
                return true;
        }
        
        return false;
};
searchshield.DiggSearchEngine.prototype.includeLink = function(tag)
{
        var outHref = false;
        var findStr = "";
        
        if ((tag.parentNode) &&
                (tag.parentNode.className.toLowerCase() == "digg-count"))
        {
                return false;
        }
        
        if (searchshield.DoesURLContain(tag.href, this.search.uri.host))
        {
                if (tag.className && tag.className.indexOf('source') != -1)
                {
                        findStr = "/search?q=site:";
                        var urlPos = tag.href.indexOf(findStr);
                        if (urlPos != -1)
                        {
                                urlPos += 15;
                                outHref = tag.href.substring(urlPos);
                                return outHref;
                        }
                }
        }
        
        return false;
};
searchshield.DiggSearchEngine.prototype.addImage = function(node, image, hidden)
{
        // remove style that is set when alt image is applied
        this.addAnchorStyle = {
                background: "none"
        };
                
        var parent = searchshield.SearchEngine.prototype.addImage;
        return parent.call(this, node, image, hidden);
};
///////////////    DIGG SEARCH ENGINE    ///////////////




///////////////    SLASHDOT SEARCH ENGINE    ///////////////
searchshield.SlashdotSearchEngine = function(search)
{
        searchshield.SearchEngine.call(this, search);
        this.showCleanVerdicts = false;
        this.new_links = false;
        this.type = 'inline';
};
searchshield.SlashdotSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.SlashdotSearchEngine.prototype.constructor = searchshield.SlashdotSearchEngine;
searchshield.SlashdotSearchEngine.prototype.name = "slashdot";
searchshield.SlashdotSearchEngine.prototype.validSearch = function(href)
{
        var uri;
        if (typeof(this.search) === 'undefined' || null === this.search)
                uri = searchshield.parseLink(href);
        else
                uri = this.search.uri;

        if(!uri || !uri.host)
                return false;
        
        var domain= uri.host;
        // re stitch the uri path and query elements
        // to use existing logic
        var path = uri.path + uri.delimiter + uri.query;
        
        if (domain.indexOf("slashdot.org") != -1)
        {
                return true;
        }
        
        return false;
};
searchshield.SlashdotSearchEngine.prototype.includeLink = function(tag)
{
        if (searchshield.DoesURLContain(tag.href, this.search.uri.host))
                return false;
                
        if ( tag.href.indexOf("mailto:") != -1 )
                return false;
                
        if ( tag.href.indexOf("slashdot.org") != -1 )
                return false;
                
        if (tag.parentNode && (tag.parentNode.tagName == "DIV"))
        {
                if (tag.parentNode.id.indexOf("text-") != -1)
                {
                        return tag.href;
                }
        }
        else if ( tag.parentNode && tag.parentNode.parentNode && tag.parentNode.parentNode.tagName == "DIV" )
        {
                if ( tag.parentNode.parentNode.id.indexOf("text-") != -1 )
                {
                        return tag.href;
                }
        }

        return false;
};
searchshield.SlashdotSearchEngine.prototype.addImage = function(node, image, hidden)
{
        var doc                        = this.search.doc;
        
        this.init_inline_ratings(doc);
        this.show_inline_ratings(doc, node, image);
};
///////////////    SLASHDOT SEARCH ENGINE    ///////////////




///////////////    TWITTER SEARCH ENGINE    ///////////////
searchshield.TwitterSearchEngine = function(search)
{
        searchshield.SearchEngine.call(this, search);
        this.showCleanVerdicts = false;
        this.new_links = false;
        this.type = 'inline';
};
searchshield.TwitterSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.TwitterSearchEngine.prototype.constructor = searchshield.TwitterSearchEngine;
searchshield.TwitterSearchEngine.prototype.name = "twitter";
searchshield.TwitterSearchEngine.prototype.twitter_filter_urls = ["twitpic.com", "twitterfeed.com", "twitter.peoplebrowsr.com"];
searchshield.TwitterSearchEngine.prototype.validSearch = function(href)
{
        var uri;
        if (typeof(this.search) === 'undefined' || null === this.search)
                uri = searchshield.parseLink(href);
        else
                uri = this.search.uri;

        if(!uri || !uri.host)
                return false;
        
        var domain= uri.host;

        if (domain.indexOf("twitter.com") != -1)
        {
                return true;
        }
        
        return false;
};
searchshield.TwitterSearchEngine.prototype.includeLink = function(tag)
{
        if (searchshield.DoesURLContain(tag.href, this.search.uri.host))
                return false;
                
        if (tag.className.length < 1)
                return false;
        
        // no verdicts on source of twit for example "from TweetDeck"
        if ((tag.className.indexOf("tweet-url web") == 0) &&
                (tag.className.indexOf("url") == 0 ))
        {
                return false;
        }
                
        if (searchshield.FilterUrl(tag.href, this.twitter_filter_urls))
        {
                return false;
        }
        
        return tag.href;
};
searchshield.TwitterSearchEngine.prototype.addImage = function(node, image, hidden)
{
        var doc                        = this.search.doc;
                
        this.init_inline_ratings(doc);
        this.show_inline_ratings(doc, node, image);
};
///////////////    TWITTER SEARCH ENGINE    ///////////////




///////////////    GMAIL SEARCH ENGINE    ///////////////
searchshield.GMailSearchEngine = function(search)
{
        searchshield.SearchEngine.call(this, search);
        this.processFrames = true;
        this.showCleanVerdicts                = false;
        this.type = 'inline';
};
searchshield.GMailSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.GMailSearchEngine.prototype.constructor = searchshield.GMailSearchEngine;
searchshield.GMailSearchEngine.prototype.name = "gmail";        // the name by which the search engine is known (always lowercase)
searchshield.GMailSearchEngine.prototype.validSearch = function(href)
{
        var uri;
        if (typeof(this.search) === 'undefined' || null === this.search)
                uri = searchshield.parseLink(href);
        else
                uri = this.search.uri;

        if(!uri || !uri.host)
                return false;

        var domain                = uri.host;
        
        // re stitch the uri path and query elements to
        // use existing logic
        var path = uri.path + uri.delimiter + uri.query;

        if ((domain.indexOf("mail.google.") != -1) || 
                (domain.indexOf("gmail.") != -1))
        {
                return true;
        }

        return false;
};
searchshield.GMailSearchEngine.prototype.includeLink = function(tag)
{
        if (searchshield.DoesURLContain(tag.href, this.search.uri.host))
                return false;

        // don't mark anything but http://
        if (tag.href.indexOf("mailto") == 0)
                return false;

        var parentDiv = searchshield.getParentNodeByTagName("DIV", tag, "className");
        if ((parentDiv) &&
                ((parentDiv.className == "ii gt") || // mail message body
                 (parentDiv.className == "mv") ||        // top sponsored links
                 (parentDiv.className == "vb") ||        // right sponsored links
                 (parentDiv.className == "im") ||        // inside quotes
                 (parentDiv.className == "gmail_quote") ||        // quote
                 (parentDiv.className == "msg")        // basic html mode
                 ))        // right ads
        {
                // parse for any ads
                var newHref = this.parseAdUrl(tag.href);
                return newHref;
        }
        
        return false;
};
searchshield.GMailSearchEngine.prototype.addImage = function(node, image, hidden)
{
        var doc                        = this.search.doc;
                
        this.init_inline_ratings(doc);
        this.show_inline_ratings(doc, node, image);
};
searchshield.GMailSearchEngine.prototype.parseAdUrl = function(href)
{
        if (!href)
                return href;

        // check for google ad
        var regex = "^http(s)?\:\/\/([a-zA-Z0-9]+)\.googlesyndication\.com.+\&adurl\=(.+)";
        var re = new RegExp(regex);
        var matches = href.match(re);
        if (matches && (matches.length >= 4))
        {
                // else we want the fourth value
                var match = matches[3];
                if (match && (match.length > 0))
                        return match
        }

        return href;
};
///////////////    GMAIL SEARCH ENGINE    ///////////////




///////////////    FACEBOOK SEARCH ENGINE    ///////////////
searchshield.FacebookSearchEngine = function(search)
{
        searchshield.SearchEngine.call(this, search);
        this.showCleanVerdicts = false;
        this.type = 'inline'
};
searchshield.FacebookSearchEngine.prototype = new searchshield.SearchEngine();
searchshield.FacebookSearchEngine.prototype.constructor = searchshield.FacebookSearchEngine;
searchshield.FacebookSearchEngine.prototype.name = "facebook";        // the name by which the search engine is known (always lowercase)
searchshield.FacebookSearchEngine.prototype.validSearch = function(href)
{
        var uri;
        if (typeof(this.search) === 'undefined' || null === this.search)
                uri = searchshield.parseLink(href);
        else
                uri = this.search.uri;

        if(!uri || !uri.host)
                return false;

        if (uri.host.indexOf("www.facebook.com") != -1) 
                return true;

        return false;
};
searchshield.FacebookSearchEngine.prototype.includeLink = function(tag)
{
        if (searchshield.DoesURLContain(tag.href, this.search.uri.host) ||
                (searchshield.DoesURLContain(tag.href, 'static.ak.fbcdn.net')))
        {
                return false;
        }
                
        // don't put verdicts in areas where typing is going on
        if (tag.parentNode) 
        {
                var parentDiv = searchshield.getParentNodeByTagName("DIV", tag, "className");
                if (parentDiv &&
                        (parentDiv.className == "Mentions_Input") ||
                        (parentDiv.className.indexOf('UIThumbPager_') != -1))
                {
                        return false;
                }
        }
        
        return tag.href
};
searchshield.FacebookSearchEngine.prototype.addImage = function(node, image, hidden)
{
        var doc                        = this.search.doc;
                
        this.init_inline_ratings(doc);
        this.show_inline_ratings(doc, node, image);
};
///////////////    FACEBOOK SEARCH ENGINE    ///////////////



///////////////    AVG TOOLBAR REPORTING    ///////////////
var avgreport = {
        BLOCK_SEVERITY: 3,
        scanResult: function (doc, url, foundUrl, ip) {
                // report scan end only if surf enabled
                if ('1' != searchshield.avgCallFunc(doc, 'GetSurfEnabled'))
                        return;
                
                // for now native is handling the interstitial        
                var results = searchshield.avgCallFunc(doc, 'MalsiteCheck', url);
                if ( results == null )
                        return;
                
                var parts = results.split('::');
                
                // need at least severity
                if (parts == null)
                        return;

                if (!ip)
                        ip = "";
                        
                // use a block severity if foundUrl is given
                var severity = !!foundUrl ? avgreport.BLOCK_SEVERITY : parseInt(parts[0], 10);
                var category = "";
                var threat         = "";

                // fill in the category and threat if something was found
                if (severity > 0)
                {
                        category = parts[2];
                        threat         = parts[4];
                }
                
                var scan_result = searchshield.avgCallFunc(doc, 'ReportScanResult', url, url, threat, category, ip, severity);
                var scan_end = avgreport.scanEnd(doc, url);
                
                return (scan_result && scan_end);
        },
        scanEnd: function (doc, url) {
                return searchshield.avgCallFunc(doc, 'ReportScanEnd', url);
        },
        GetInterstitialIP: function (interstitial) {
                // simple regex to pull the IP address
                var regex = /(([1-9][0-9]{0,2})|0)\.(([1-9][0-9]{0,2})|0)\.(([1-9][0-9]{0,2})|0)\.(([1-9][0-9]{0,2})|0)/;
                var match = regex.exec(interstitial);
                if (!match)
                        return '';

                return match[0];
        }
}
///////////////    AVG TOOLBAR REPORTING    ///////////////


///////////////    FLYOVERS    ///////////////
var avglsflyover = {
        count: 0,
        poppedUp: false,
        poppedElement: null,
        orig_onmousemove: null,
        reset: function () {
                avglsflyover.count = 0;
                avglsflyover.poppedUp = false;
                avglsflyover.poppedElement = null;
                avglsflyover.orig_onmousemove = null;
        },
        popup: function (event, hash, search, flyover) {
                if (!event)
                        event = window.event;

                var div = document.getElementById("XPLSS_Flyover");
                if (div == null)
                        return;

                // establish target element and get its containing document object
                // in case verdict is inside a frame
                var eventTarget = event.srcElement || event.currentTarget;
                var frameDoc = eventTarget.ownerDocument;

                // if the element is the clock, don't pop over it
                if ((eventTarget.src != null) && (eventTarget.src.indexOf("clock.gif") != -1))
                        return;
                
                // save the element we popped over
                avglsflyover.poppedElement = eventTarget;

                // if no flyover get it
                if ((flyover == null) || (flyover == ""))
                {
                        flyover = searchshield.avgCallFunc(frameDoc, 'BuildFlyover', hash);

                        if (!flyover)
                                return;

                        // cleanup flyover, replace any new lines
                        flyover = flyover.replace(/\r/g, "");
                        flyover = flyover.replace(/\n/g, "");
                        // escape any single quotes
                        flyover = flyover.replace(/'/g, "&#39;");
                }

                // set the html in the layer
                div.innerHTML = flyover;

                // there is an unwanted text node that causes vertical misalignment of flyover
                if (div.firstChild.nodeType == 3)
                        div.removeChild(div.firstChild);
                
                avglsflyover.poppedUp = true;

                // reset display count
                avglsflyover.count = 0;

                div.onmouseout = avglsflyover.hide;

                // if an onmousemove is already set and it isn't us, save it and restore later
                if ((frameDoc.onmousemove != null) && (frameDoc.onmousemove != avglsflyover.position))
                        avglsflyover.orig_onmousemove = frameDoc.onmousemove;
                frameDoc.onmousemove = avglsflyover.position;
        },
        hide: function (event, force) {
                var div = document.getElementById("XPLSS_Flyover");
                if ((div == null) || (div.style == null) || (div.style.visibility == "hidden"))
                        return;

                var trans_div = document.getElementById("XPLSS_Trans");
                if ((trans_div == null) || (trans_div.style == null) || (trans_div.style.visibility == "hidden"))
                        return;

                if (!!force)
                        return setFlyoverStyle(div, trans_div);

                if (!event)
                        event = window.event;
                
                // establish target element and get its containing document object
                // in case verdict is inside a frame
                var eventTarget = event.srcElement || event.currentTarget;
                var frameDoc = eventTarget.ownerDocument;

                // restore onmousemove
                if (avglsflyover.orig_onmousemove != null)
                        frameDoc.onmousemove = avglsflyover.orig_onmousemove;

                if (avglsflyover.poppedElement)
                        avglsflyover.poppedElement.style.border = "";

                var relatedElement = event.toElement;
                if (!relatedElement)
                {        //this happens on mouseout when verdict and flyover are on different frames/docs
                        window.top.document.detachEvent('onmouseout', avglsflyover.hide);
                        window.top.document.attachEvent('onmouseout', avglsflyover.hide);
                        return;
                }

                // make sure we aren't still over the popped image or our layer
                if (searchshield.containedIn(avglsflyover.poppedElement, relatedElement) ||
                        searchshield.containedIn(div, relatedElement) ||
                        searchshield.containedIn(trans_div, relatedElement))
                {
                        return;
                }

                setFlyoverStyle();

                // hide and move somewhere off screen (negative offsets)
                function setFlyoverStyle()
                {
                        div.style.visibility = "hidden";
                        div.style.left = "-2100px";
                        div.style.top  = "-2100px";
                        trans_div.style.visibility = "hidden";
                        trans_div.style.left = "-2100px";
                        trans_div.style.top  = "-2100px";

                        return true;
                }
        },
        position: function () {
                if (!avglsflyover.poppedUp || (avglsflyover.poppedElement == null))
                        return;

                var flyover = document.getElementById("XPLSS_Flyover");
                if (flyover == null)
                        return;


                // relative position of flyover in relation to icon
                var locateX = 0;  // 0=left, 1=right
                var locateY = 0;  // 0=above, 1=below, 2=beside icon
        
                // get window sizes
                var winSize                = searchshield.viewPortSize();
                var windowX                = winSize[0];
                var windowY                = winSize[1];

                // get the exact size of the flyover
                var flyoverSize         = searchshield.elementSize(flyover);
                var flyoverX         = flyoverSize[0];
                var flyoverY         = flyoverSize[1];

                var verdictWidth = 0;
                if (avglsflyover.poppedElement && avglsflyover.poppedElement.width)
                        verdictWidth = avglsflyover.poppedElement.width;
                
                // get the bounding rect for image(s)
                var imgRect = searchshield.GetFullBoundingRect(avglsflyover.poppedElement);

                // half width/height of element bounding rect
                var halfX = (imgRect.right - imgRect.left) / 2;
                var halfY = (imgRect.bottom- imgRect.top) / 2;

                // element the mouse is over, get the center position
                var posX = searchshield.offsetLeft(avglsflyover.poppedElement) + halfX;
                var posY = searchshield.offsetTop(avglsflyover.poppedElement) + halfY;

                // if a verdict is inside a frame must get offsets for the frame element
                var docFrames = document.frames;
                if (docFrames)
                {
                        for (var i=0; i < docFrames.length; i++)
                        {
                                try {
                                        var frameElem = docFrames[i].frameElement;
                                        if (frameElem.contentWindow.document.getElementById(avglsflyover.poppedElement.id))
                                        {
                                                posX += searchshield.offsetLeft(frameElem);
                                                posY += searchshield.offsetTop(frameElem);
                                                break;
                                        }
                                }
                                catch(frmErr){}
                        }
                }

                var transXOffset = 0;
                if (imgRect.mid == undefined)
                        transXOffset = -1 * halfX;
                else
                        transXOffset = ((imgRect.right + imgRect.left) / 2) - imgRect.mid;
                
                // normalize pos to 0  -- get amount of scrolling in browser window
                var scroll                 = searchshield.scrollSize();
                var pageOffsetX         = scroll[0];
                var pageOffsetY         = scroll[1];

                posX -= pageOffsetX;
                posY -= pageOffsetY;

                // setup the offsets
                var offsetX = posX;
                var offsetY = posY;

                // calc where to display on page
                if ((windowX - posX) > posX)
                {
                        // right
                        offsetX += halfX;
                        locateX = 1;
                }
                else
                {
                        //left
                        offsetX -= (flyoverX + halfX);
                }
                if ((windowY - posY) > posY)
                {
                        // below
                        if (posY < (windowY/4))
                        {
                                offsetY -= halfY;
                                locateY = 1;
                        }
                        else
                        {
                                offsetY -= (flyoverY / 2);
                                locateY = 2;
                        }
                }
                else
                {
                        // above
                        if ((windowY - posY) < (windowY/4))
                        {
                                offsetY -= (flyoverY - halfY);
                        }
                        else
                        {
                                offsetY -= (flyoverY / 2);
                                locateY = 2;
                        }
                }
                // make sure we aren't off the screen
                if (offsetY < 0)
                        offsetY = 0;

                if ((offsetY + flyoverY) > windowY)
                        offsetY = windowY - flyoverY;

                // add page offsets back
                offsetX += pageOffsetX;
                offsetY += pageOffsetY;
                posX += pageOffsetX;
                posY += pageOffsetY;

                var paddedOffsetX = 0; //provide space between icon and flyover
                var padX = 3;
                if (locateX == 0)
                        paddedOffsetX = offsetX - padX;
                else
                        paddedOffsetX = offsetX + padX;


                // set where to put the flyover
                flyover.style.top = offsetY + "px";
                flyover.style.left = paddedOffsetX + "px";


                // set where to put the transparent layer
                var trans = document.getElementById("XPLSS_Trans");
                if (trans != null)
                {
                        var trans_left = 0;
                        var trans_top  = 0;
                        var trans_width= 0;
                        var trans_height = 0;

                        // transparent layer should overlap verdict image
                        if (locateX == 0)
                                trans_left = posX - flyoverX - halfX;  // left 
                        else
                                trans_left = posX - transXOffset - verdictWidth; // right

                        trans.style.left        = trans_left + "px";
                        trans.style.top                = offsetY + "px";

                        trans.style.width        = flyoverX + "px";
                        trans.style.height        = flyoverY + "px";
                }

                avglsflyover.display();
        },
        display: function () {
                avglsflyover.count++;
                if (avglsflyover.count == 1)
                {
                        var flyover = document.getElementById("XPLSS_Flyover");
                        if (flyover == null)
                                return;

                        // show the flyover, must use a little count to tell, crazy stuff
                        flyover.style.visibility = "visible";

                        // show the transparent layer
                        var trans_div = document.getElementById("XPLSS_Trans");
                        if (trans_div == null)
                                return;

                        trans_div.style.visibility = "visible";

                        avglsflyover.poppedUp = false;
                }
        },
        show: function () {
                var div = document.getElementById("XPLSS_Flyover");
                if (div == null)
                        return;

                div.style.visibility = "visible";

                var trans_div = document.getElementById("XPLSS_Trans");
                if (trans_div == null)
                        return;
                trans_div.style.visible = "visible";
        }
};

var avglsinlineflyover = {
        build: function (riskCategory, riskName, bgColor, borderColor) {
                var html = '';
                html += "<div style=background-color:" + bgColor;
                html += "border-color:" + borderColor + ";";
                html += "border-style:solid;";
                html += "border-width:3px;";
                html += "padding:3px;";
                html += "padding-left:8px;";
                html += "padding-right:8px;";
                html += "-moz-border-radius:5px;>";
                html += "<img src=linkscanner://LS_Logo_Results.gif /><br />";
                html += riskCategory + "<br />";
                html += riskName + "<br /></div>";

                return html;
        },
        popup: function (event, flyover, blUrl) {
                //set verdict info
                var div = document.getElementById('XPLSS_InlineFlyover');
                if (div == null)
                        return;
                
                // blUrl is an object for a blacklisted short url
                // when it is passed get the final url 
                if (blUrl != undefined)
                {
                        var finalUrl = searchshield.avgCallFunc(document, 'GetFinalUrl', blUrl.sUrl);
                        var uri = searchshield.parseLink(unescape(finalUrl));
                        if (uri.source != null)
                        {        // regexp failed so used split to parse url
                                var qsUrl = uri.source.indexOf("?url=");
                                if (qsUrl != -1)
                                        riskName = blUrl.riskNameLabel + uri.source.substring(qsUrl + 5);
                                else
                                        riskName = blUrl.riskNameLabel + uri.source;
                        }
                        else if ((uri.qsArray.url != null) && (uri.qsArray.url.length > 0))
                        {
                                riskName = blUrl.riskNameLabel + uri.qsArray.url;
                        }
                        else
                                riskName = blUrl.riskNameLabel + blUrl.sUrl

                        flyover = avglsinlineflyover.build(blUrl.riskCategory, riskName, blUrl.bgColor, blUrl.borderColor);
                }

                div.innerHTML = flyover;
                div.style.width = "auto";  //reset width
                div.style.position = "absolute";

                if (!event)
                        event = window.event;
                        
                var eventTarget = event.srcElement;
                avglsinlineflyover.position(eventTarget);
        },
        hide: function (event) {
                if (!event)
                        event = window.event;
                        
                var div = document.getElementById("XPLSS_InlineFlyover");
                if (div == null)
                        return;
                        
                div.visibility = "hidden";        //invisible
                div.style.left = "-5000px";
        },
        position: function (imageElem) {
                var flyover = document.getElementById('XPLSS_InlineFlyover');
                if (flyover == null)
                        return;
                        
                // relative position of flyover in relation to icon
                var locateX = 0;  // 0=left, 1=right
                var locateY = 0;  // 0=above, 1=below, 2=beside icon
                
                
                
                // get window sizes
                var winSize         = searchshield.viewPortSize();
                var windowX         = winSize[0];
                var windowY         = winSize[1];

                // Must know if there is a horizontal scroll bar for Firefox
                // for proper flyover positioning near bottom edge
                var scrollYWidth         = winSize[2];
                var scrollBarX         = winSize[2] > 0 ? true : false;

                // get the exact size of the flyover
                var flyoverSize         = searchshield.elementSize(flyover);
                var flyoverX         = flyoverSize[0];
                var flyoverY         = flyoverSize[1];
                
                flyover.style.width = flyoverX + "px";
                
                // get the bounding rect for image(s)
                var imgRect = imageElem.getBoundingClientRect();

                // half width/height (center) of element bounding rect
                var halfX = (imgRect.right - imgRect.left) / 2;
                var halfY = (imgRect.bottom- imgRect.top) / 2;

                // element the mouse is over, get the center position
                var posX = searchshield.offsetLeft(imageElem) + halfX;
                var posY = searchshield.offsetTop(imageElem) + halfY;
                
                var pageOffsetX = 0;
                var pageOffsetY = 0;

                // normalize pos to 0  -- get amount of scrolling in browser window
                var scroll                 = searchshield.scrollSize(imageElem);
                var pageOffsetX         = scroll[0];
                var pageOffsetY         = scroll[1];
                var hasParentFrame = scroll[2];
                
                posX -= pageOffsetX;
                posY -= pageOffsetY;

                //compensate for Firefox 3
                if (posX < imgRect.left)
                        posX = imgRect.left+halfX;

                // setup the offsets
                var offsetX = posX;
                var offsetY = posY;

                // calc where to display on page
                if ((windowX - posX) > posX)
                {
                        // right
                        offsetX += halfX;
                        locateX = 1;
                }
                else
                {
                        //left
                        offsetX -= (flyoverX + halfX);
                }
                if ((windowY - posY) > posY)
                {
                        // below
                        if (posY < (windowY/4))
                        {
                                offsetY -= halfY;
                                locateY = 1;
                        }
                        else
                        {
                                offsetY -= (flyoverY / 2) - halfY;
                                locateY = 2;
                        }
                }
                else
                {
                        // above
                        if ((windowY - posY) < (windowY/4))
                        {
                                offsetY -= (flyoverY - halfY);
                        }
                        else
                        {
                                offsetY -= (flyoverY / 2) + halfY;
                                locateY = 2;
                        }
                }
                // make sure we aren't off the screen
                if (offsetY < 0)
                        offsetY = 0;

                if ((offsetY + flyoverY) > windowY)
                {
                        offsetY = windowY - flyoverY;
                }
                else if (scrollBarX && ((windowY - (posY + halfY)) < scrollYWidth))
                {        //verdict overlaps the horizontal scrollbar
                        offsetY = windowY - (flyoverY + scrollYWidth);
                }

                // add page offsets back - if not in frame
                if (!hasParentFrame)
                {
                        offsetX += pageOffsetX;
                        offsetY += pageOffsetY;
                }
                posX += pageOffsetX;
                posY += pageOffsetY;

                var paddedOffsetX = 0; //provide space between icon and flyover
                var padX = 3;
                if (locateX == 0)
                        paddedOffsetX = offsetX - padX;
                else
                        paddedOffsetX = offsetX + padX;


                // set where to put the flyover
                flyover.style.top = offsetY + "px";
                flyover.style.left = paddedOffsetX + "px";

                avglsinlineflyover.display();
        },
        display: function () {
                var div = document.getElementById('XPLSS_InlineFlyover');
                if (div == null)
                        return;
                
                // show the flyover
                div.style.visibility = "visible";
        },
        imageExists: function(element) {
                if (element)
                {
                        // check next siblings children
                        var sibling = element.nextSibling;
                        
                        if ((sibling == null) || (sibling.getElementsByTagName == null))
                                return false;
                        
                        var images = sibling.getElementsByTagName("IMG");
                        if (images == null)
                                return false;

                        for (var i = 0; i < images.length; i++)
                        {
                                if (images[i].id == "avg_ls_image")
                                        return true;
                        }
                }

                return false;
        },
        getImage: function (anchor) {
                if (anchor)
                {
                        var imageElem = null;
                        var images = anchor.getElementsByTagName("img");
                        if (images == null)
                                return imageElem;

                        for (var i = 0; i < images.length; i++)
                        {
                                if (images[i].id == "avg_ls_image")
                                {
                                        imageElem = images[i];
                                        break;  
                                }                                
                        }
                        return imageElem;
                }  
        },
        mouseOverHandler: function (e, doc, engine) {
                if (e && e.srcElement && e.srcElement.href)
                {
                        // need to keep a reference to the function registered 
                        // by the listener to be able to remove it.
                        var handlerFunc = arguments.callee;
                        var element = e.srcElement;
                        var href = e.srcElement.href;

                        // need an engine                        
                        if (!engine)
                                return;

                        // check if it has an image already
                        if (avglsinlineflyover.imageExists(element))
                                return;

                        // add the image, returns the anchor not the image
                        var new_element = engine.add_inline_image(doc, element, null, null);

                        // do the check and update in the background
                        setTimeout(function() {avglsinlineflyover.checkAndUpdate(doc, element, new_element, engine, handlerFunc)}, 1);
                }
        },
        checkAndUpdate: function (doc, element, new_element, engine, handlerFunc) {
                if (!engine)
                        return;

                try {
                        // remove the listener and get final url
                        element.detachEvent("onmouseover", handlerFunc, false);
                        var finalUrl = searchshield.avgCallFunc(doc, 'GetFinalUrl', element.href);
                }
                catch(e) {}

                if (finalUrl)
                {
                        // update the verdict
                        engine.display_inline(doc, new_element, finalUrl, null, true);
                }
        }
};
///////////////    FLYOVERS    ///////////////
</SCRIPT></div></body></html>