/**
 * @author http://www.ganchiku.com/2007/09/domx_js.html
 */
document.getElementsByClassNameAndTagName = function(className, parentElement, tagName) {
  if (Prototype.BrowserFeatures.XPath) {
     return $(parentElement || document.body).getElementsByClassName(className);
  } else {
    var children = $(parentElement || document.body).getElementsByTagName(tagName || '*');
    var elements = [], child;
    for (var i = 0, length = children.length; i < length; i++) {
      child = children[i];
      if (Element.hasClassName(child, className))
        elements.push(Element.extend(child));
    }
    return elements;
  }
}

Element.addMethods({
  getElementsByClassNameAndTagName: function(element, className, tagName) {
    return document.getElementsByClassNameAndTagName(className, element, tagName);
  },

  nextElement: function(element) {
    do {
      element = element.nextSibling;
    } while (element && element.nodeType != 1);
    return $(element);
  },

  previousElement: function(element) {
    do {
      element = element.previousSibling;
    } while (element && element.nodeType != 1);
    return $(element);
  },

  firstChildElement: function(element) {
    var child = element.firstChild;
    while (child && child.nodeType != 1) {
      child = child.nextSibling;
    }
    return $(child);
  },

  lastChildElement: function(element) {
    var child = element.lastChild;
    while (child && child.nodeType != 1) {
      child = child.previousSibling;
    }
    return $(child);
  },

  childElements: function(element) {
    var children = [];
    var child = element.firstChild;
    while (child) {
      if (child.nodeType == 1) {
        children.push($(child));
      }
      child = child.nextSibling;
    }
    return children;
  },

  childElement: function(element, index) {
    var nodeIndex = 0;
    var child = element.firstChild;
    while (child) {
      if (child.nodeType == 1 && index == nodeIndex++) {
          return $(child);
      }
      child = child.nextSibling;
    }
    return null;
  },

  cleanWhitespaceRecursive: function(element) {
    var f = function(element) {
      var child = $(element).cleanWhitespace().firstChild;
      while (child) {
        if (child.nodeType == 1) {
          f(child);
        }
        child = child.nextSibling;
      }
    };
    f(element);
    return element;
  }
});