var nodes = null;

function getElementsByClassName(className,tagNames,oParent) {
  // grab elements by class, restricting search to certain tags or a parent element
  var doc = (oParent||document);
  var matches = [];
  var i,j;

  writeDebug('getEBCN('+className+',['+tagNames+'],'+(oParent?oParent.nodeName:'null')+')');

  // nodes - globally declared array (var nodes = [])
  if (!nodes) nodes = []; // required to keep Opera happy
  if (tagNames && typeof(tagNames)!='string') {
    for (i=0; i<tagNames.length; i++) {
      if (!nodes || !nodes[tagNames[i]]) {
        nodes[tagNames[i]] = doc.getElementsByTagName(tagNames[i]);
      }
    }
  } else if (tagNames) {
    nodes = doc.getElementsByTagName(tagNames);
  } else {
    nodes = doc.all||doc.getElementsByTagName('*');
  }
  if (typeof(tagNames)!='string') {
    for (i=0; i<tagNames.length; i++) {
      for (j=0; j<nodes[tagNames[i]].length; j++) {
        if (nodes[tagNames[i]][j].className && nodes[tagNames[i]][j].className.indexOf(className)+1 && (nodes[tagNames[i]][j].className == className || nodes[tagNames[i]][j].className.indexOf(className+' ')+1 || nodes[tagNames[i]][j].className.indexOf(' '+className)+1)) {
          matches[matches.length] = nodes[tagNames[i]][j];
        }
      }
    }
  } else {
    for (i=0; i<nodes.length; i++) {
      if (nodes[i].className && nodes[i].className.indexOf(className)+1 && (nodes[i].className == className || nodes[i].className.indexOf(className+' ')+1 || nodes[i].className.indexOf(' '+className)+1)) {
        matches[matches.length] = nodes[i];
      }
    }
  }

  writeDebug('getEBCN(): returning '+matches.length+' matches');

  return matches; // kids, don't play with fire. ;)
}
