docs: function JavascriptXPathEngine() {
  // private
      var engineDoc = document;
  
  // public
      // Override
      this.isAvailable = function() { return true; };
  
      // Override
      this.selectNodes = function(xpath, contextNode, namespaceResolver) {
          if (contextNode != this.doc) {
              // Regarding use of the second argument to document.evaluate():
              // http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/a59ce20639c74ba1/a9d9f53e88e5ebb5
              xpath = '.' + xpath;
          }
  
          var nodes = [];
  
          try {
              // When using the new and faster javascript-xpath library, we'll
              // use the TestRunner's document object, not the App-Under-Test's
              // document. The new library only modifies the TestRunner document
              // with the new functionality.
              var xpathResult = engineDoc.evaluate(xpath, contextNode,
                  namespaceResolver, 0, null);
          }
          catch (e) {
              var msg = extractExceptionMessage(e);
              throw new SeleniumError("Invalid xpath [1]: " + msg);
          }
          finally {
              if (xpathResult == null) {
                  // If the result is null, we should still throw an Error.
                  throw new SeleniumError("Invalid xpath [2]: " + xpath);
              }
          }
  
          var node = xpathResult.iterateNext();
  
          while (node) {
              nodes.push(node);
              node = xpathResult.iterateNext();
          }
  
          return nodes;
      };
  }