function replaceInElement(element, find, replace) {
  // iterate over child nodes in reverse, as replacement may increase
  // length of child node list.
  for (var i= element.childNodes.length; i-->0;) {
    var child= element.childNodes[i];
    if (child.nodeType==1) { // ELEMENT_NODE
      var tag= child.nodeName.toLowerCase();
      if (tag!='style' && tag!='script' && tag!='a' && tag!='h4') { // special case, don't touch CDATA elements
        replaceInElement(child, find, replace);
      }
    } else if (child.nodeType==3) { // TEXT_NODE
        replaceInText(child, find, replace);
    }
      
  }
}
function replaceInText(text, find, replace) {
  var match;
  var matches= [];
  while (match= find.exec(text.data))
    matches.push(match);
  for (var i= matches.length; i-->0;) {
    match= matches[i];
    text.splitText(match.index);
    text.nextSibling.splitText(match[0].length);
    text.parentNode.replaceChild(replace(match), text.nextSibling);
  }
}

function crsExecute(section,terms) {
  // keywords to match. This *must* be a 'g'lobal regexp or it'll fail bad
  jQuery.each(terms, function(i, val) {
      var re = new RegExp(i, "gi");
      var find= re;
      // replace matched strings with wiki links
      replaceInElement(section, find, function(match) {
        var link= document.createElement('a');
        link.href= val['url'];
        link.target= val['target'];
        link.appendChild(document.createTextNode(match[0]));
        return link;
        });
        });
}

