function highlightWord(node,word,numOfWords) {
	// Recursivley iterate into this node's childNodes
	if (node.hasChildNodes) {
		var hi_cn;
		for ( hi_cn = 0; hi_cn < node.childNodes.length; hi_cn++ ) {
			highlightWord(node.childNodes[hi_cn],word,numOfWords);
		}
	}
	
	// And do this node itself
	if (node.nodeType == 3) { // text node
		tempNodeVal = node.nodeValue.toLowerCase();
		tempWordVal = word.toLowerCase();
		if (tempNodeVal.indexOf(tempWordVal) != -1) {
			pn = node.parentNode;
			
			// Only highlight nodes that have NOT been previously highlighted
			if (pn.className != "hilite" && pn.className != "hilite2") {
				nv = node.nodeValue;
				ni = tempNodeVal.indexOf(tempWordVal);

				// Create a load of replacement nodes
				before = document.createTextNode(nv.substr(0,ni));
				docWordVal = nv.substr(ni,word.length);
				after = document.createTextNode(nv.substr(ni+word.length));
				hiwordtext = document.createTextNode(docWordVal);
				hiword = document.createElement("span");
				if (numOfWords > 1) {
					hiword.className = "hilite2";
				} else {
					hiword.className = "hilite";
				}
				hiword.appendChild(hiwordtext);
				pn.insertBefore(before,node);
				pn.insertBefore(hiword,node);
				pn.insertBefore(after,node);
				pn.removeChild(node);
			}
		}
	}
}

function SearchHighlight() {
	if (!document.createElement) return;

	var tmp = readCookie('keywords');
	if (!tmp) return;
	tmp = tmp.replace(/\+/g,' ');
	tmp = _from_utf8(unescape(tmp));
	var keyword_list_tmp = tmp.split('&');

	// Prepare the keyword list AND get largest number of combined words
	// (this is used to get a more accurate higlighting when we have words in exact phrases)
	var max_combination = 0
	var keyword_list = new Array();
	for ( var i = 0; i < keyword_list_tmp.length; i++ ) {
		keyword_list[i] = unescape(keyword_list_tmp[i])
		var numOfWords = (keyword_list[i].split(/\s+/)).length;
		if ( numOfWords > max_combination ) {
			max_combination = numOfWords;
		}		
	}

	// Now to go through all the words starting with the largest combination
	for (; max_combination > 0; max_combination--) {
		for ( var i = 0; i < keyword_list.length; i++ ) {
			var words = keyword_list[i];
			if (words == '0' || words.length < 2) continue;
			var numOfWords = (words.split(/\s+/)).length;
			if ( numOfWords == max_combination ) {
				keyword_list[i] = '0';
			    // if an element is provided, only it's content will
			    // be highlighted, else the body document will be highlighted
				if (arguments.length ==0)
					highlightWord(document.getElementsByTagName("body")[0],words,numOfWords);
				else
					highlightWord(document.getElementById(arguments[0]),words,numOfWords);
			}
		}
	}
}

function _from_utf8(s) {
  var c, d = "", flag = 0, tmp;
  for (var i = 0; i < s.length; i++) {
    c = s.charCodeAt(i);
    if (flag == 0) {
      if ((c & 0xe0) == 0xe0) {
        flag = 2;
        tmp = (c & 0x0f) << 12;
      } else if ((c & 0xc0) == 0xc0) {
        flag = 1;
        tmp = (c & 0x1f) << 6;
      } else if ((c & 0x80) == 0) {
        d += s.charAt(i);
      } else {
        flag = 0;
      }
    } else if (flag == 1) {
      flag = 0;
      d += String.fromCharCode(tmp | (c & 0x3f));
    } else if (flag == 2) {
      flag = 3;
      tmp |= (c & 0x3f) << 6;
    } else if (flag == 3) {
      flag = 0;
      d += String.fromCharCode(tmp | (c & 0x3f));
    } else {
      flag = 0;
    }
  }
  return d;
}