text: var JSUNIT_UNDEFINED_VALUE;
  var JSUNIT_VERSION = 2.2;
  var isTestPageLoaded = false;
  
  //hack for NS62 bug
  (function () {
      if (typeof top === 'undefined') { return; }
      var tempTop = top;
      if (!tempTop) {
          tempTop = window;
          while (tempTop.parent && tempTop.parent !== tempTop) {
              tempTop = tempTop.parent;
              if (tempTop.top && tempTop.top.jsUnitTestSuite) {
                  tempTop = tempTop.top;
                  break;
              }
          }
      }
      try {
          window.top = tempTop;
      } catch (e) {
      }
  })();
  
  
  /**
   * A more functional typeof
   * @param Object o
   * @return String
   */
  function _trueTypeOf(something) {
      var result = typeof something;
      try {
          switch (result) {
              case 'string':
              case 'boolean':
              case 'number':
                  break;
              case 'object':
              case 'function':
                  switch (something.constructor) {
                      case new String().constructor:
                          result = 'String';
                          break;
                      case new Boolean().constructor:
                          result = 'Boolean';
                          break;
                      case new Number().constructor:
                          result = 'Number';
                          break;
                      case new Array().constructor:
                          result = 'Array';
                          break;
                      case new RegExp().constructor:
                          result = 'RegExp';
                          break;
                      case new Date().constructor:
                          result = 'Date';
                          break;
                      case Function:
                          result = 'Function';
                          break;
                      default:
                          var m = something.constructor.toString().match(/function\s*([^( ]+)\(/);
                          if (m)
                              result = m[1];
                          else
                              break;
                  }
                  break;
          }
      }
      finally {
          result = result.substr(0, 1).toUpperCase() + result.substr(1);
          return result;
      }
  }
  
  function _displayStringForValue(aVar) {
      var result;
      try {
          result = '<' + JSON.stringify(aVar) + '>';
      } catch (ex) {
          // When aVar is cyclic or otherwise not reducable to JSON.
          result = '<' + aVar + '>';
      }
      if (!(aVar === null || aVar === void 0)) {
          result += ' (' + _trueTypeOf(aVar) + ')';
      }
      return result;
  }
  
  // TODO(kpreid): It is no longer _necessary_ to do a special escaping exception,
  // because the RhinoTestBedWrapper actually checks jsunit.js's output, but it
  // still makes the failure more specific. Still probably a better idea to get
  // rid of this and replace it with better outside plumbing.
  
  function fail(failureMessage) {
    if ('undefined' !== typeof _junit_) {
      // If run inside Rhino in the presence of junit, throw an error which will
      // escape any exception trapping around the Rhino embedding.
      _junit_.fail(failureMessage);
    } else {
      throw new JsUnitException("Call to fail()", failureMessage);
    }
  }
  
  function error(errorMessage) {
    if ('undefined' !== typeof _junit_) {
      // If run inside Rhino in the presence of junit, throw an error which will
      // escape any exception trapping around the Rhino embedding.
      _junit_.fail(errorMessage);
    } else {
      var errorObject = new Object();
      errorObject.description = errorMessage;
      errorObject.stackTrace = getStackTrace();
      throw errorObject;
    }
  }
  
  function argumentsIncludeComments(expectedNumberOfNonCommentArgs, args) {
      return args.length == expectedNumberOfNonCommentArgs + 1;
  }
  
  function commentArg(expectedNumberOfNonCommentArgs, args) {
      if (argumentsIncludeComments(expectedNumberOfNonCommentArgs, args))
          return args[0];
  
      return null;
  }
  
  function nonCommentArg(desiredNonCommentArgIndex, expectedNumberOfNonCommentArgs, args) {
      return argumentsIncludeComments(expectedNumberOfNonCommentArgs, args) ?
             args[desiredNonCommentArgIndex] :
             args[desiredNonCommentArgIndex - 1];
  }
  
  function _validateArguments(expectedNumberOfNonCommentArgs, args) {
      if (!( args.length == expectedNumberOfNonCommentArgs ||
             (args.length == expectedNumberOfNonCommentArgs + 1 && typeof(args[0]) == 'string') ))
          error('Incorrect arguments passed to assert function');
  }
  
  function _assert(comment, booleanValue, failureMessage) {
    if (!booleanValue) {
      if ('undefined' !== typeof _junit_) {
        var message = comment
            ? (failureMessage ? comment + ': ' + failureMessage : comment)
            : failureMessage;
        // If run inside Rhino in the presence of junit, throw an error which will
        // escape any exception trapping around the Rhino embedding.
        _junit_.fail(message);
      }
      throw new JsUnitException(comment, failureMessage);
    }
  }
  
  function assert() {
      _validateArguments(1, arguments);
      var booleanValue = nonCommentArg(1, 1, arguments);
  
      if (typeof(booleanValue) != 'boolean')
          error(commentArg(1, arguments) + ': Bad argument to assert(boolean)');
  
      _assert(commentArg(1, arguments), booleanValue === true, 'Call to assert(boolean) with false');
  }
  
  function assertTrue() {
      _validateArguments(1, arguments);
      var booleanValue = nonCommentArg(1, 1, arguments);
  
      if (typeof(booleanValue) != 'boolean')
          error(commentArg(1, arguments) + ': Bad argument to assertTrue(boolean)');
  
      _assert(commentArg(1, arguments), booleanValue === true, 'Call to assertTrue(boolean) with false');
  }
  
  function assertFalse() {
      _validateArguments(1, arguments);
      var booleanValue = nonCommentArg(1, 1, arguments);
  
      if (typeof(booleanValue) != 'boolean')
          error(commentArg(1, arguments) + ': Bad argument to assertFalse(boolean)');
  
      _assert(commentArg(1, arguments), booleanValue === false, 'Call to assertFalse(boolean) with true');
  }
  
  function assertEquals() {
      _validateArguments(2, arguments);
      var var1 = nonCommentArg(1, 2, arguments);
      var var2 = nonCommentArg(2, 2, arguments);
      var comment = commentArg(2, arguments);
      if ("string" === typeof var1 && "string" === typeof var2 && var1 !== var2) {
        // Come up with a minimal diff by finding any common prefix and suffix and
        // replacing those with ... and make control characters obvious.
        var commonPrefix = 0;
        var len1 = var1.length, len2 = var2.length;
        var maxPrefixLen = Math.min(len1, len2);
        for (; commonPrefix < maxPrefixLen; ++commonPrefix) {
          if (var1.charCodeAt(commonPrefix) !== var2.charCodeAt(commonPrefix)) {
            break;
          }
        }
        var commonSuffix = 0;
        var maxSuffixLen = maxPrefixLen - commonPrefix;
        for (; commonSuffix < maxSuffixLen; ++commonSuffix) {
          if (var1.charCodeAt(len1 - commonSuffix - 1) !== var2.charCodeAt(
                len2 - commonSuffix - 1)) {
            break;
          }
        }
        // TODO: Maybe adjust common{Pre,Suf}fix if they end up pointing into a
        // surrogate pair.
  
        function context(s) {
          return '"'
              + (commonPrefix ? "..." : "")
              + s.substring(commonPrefix, s.length - commonSuffix)
                  .replace(/[\\\"]/g, "\\$&")
                  .replace(/\n/g, "\\n")
                  .replace(/\r/g, "\\r")
              + (commonSuffix ? "..." : "")
              + '"';
        }
        var minimalDiff = context(var1) + " != " + context(var2);
        if (comment) {
          comment += ' : ' + minimalDiff;
        } else {
          comment = minimalDiff;
        }
      }
      _assert(comment, var1 === var2,
              'Expected ' + _displayStringForValue(var1) + ' but was '
              + _displayStringForValue(var2));
  }
  
  function assertNotEquals() {
      _validateArguments(2, arguments);
      var var1 = nonCommentArg(1, 2, arguments);
      var var2 = nonCommentArg(2, 2, arguments);
      _assert(commentArg(2, arguments), var1 !== var2, 'Expected not to be ' + _displayStringForValue(var2));
  }
  
  function assertNull() {
      _validateArguments(1, arguments);
      var aVar = nonCommentArg(1, 1, arguments);
      _assert(commentArg(1, arguments), aVar === null, 'Expected ' + _displayStringForValue(null) + ' but was ' + _displayStringForValue(aVar));
  }
  
  function assertNotNull() {
      _validateArguments(1, arguments);
      var aVar = nonCommentArg(1, 1, arguments);
      _assert(commentArg(1, arguments), aVar !== null, 'Expected not to be ' + _displayStringForValue(null));
  }
  
  function assertUndefined() {
      _validateArguments(1, arguments);
      var aVar = nonCommentArg(1, 1, arguments);
      _assert(commentArg(1, arguments), aVar === void 0, 'Expected ' + _displayStringForValue(void 0) + ' but was ' + _displayStringForValue(aVar));
  }
  
  function assertNotUndefined() {
      _validateArguments(1, arguments);
      var aVar = nonCommentArg(1, 1, arguments);
      _assert(commentArg(1, arguments), aVar !== void 0, 'Expected not to be ' + _displayStringForValue(void 0));
  }
  
  function assertNaN() {
      _validateArguments(1, arguments);
      var aVar = nonCommentArg(1, 1, arguments);
      _assert(commentArg(1, arguments), isNaN(aVar), 'Expected NaN');
  }
  
  function assertNotNaN() {
      _validateArguments(1, arguments);
      var aVar = nonCommentArg(1, 1, arguments);
      _assert(commentArg(1, arguments), !isNaN(aVar), 'Expected not NaN');
  }
  
  function assertObjectEquals() {
      _validateArguments(2, arguments);
      var var1 = nonCommentArg(1, 2, arguments);
      var var2 = nonCommentArg(2, 2, arguments);
      var type;
      var msg = commentArg(2, arguments)?commentArg(2, arguments):'';
      var isSame = (var1 === var2);
      //shortpath for references to same object
      var isEqual = ( (type = _trueTypeOf(var1)) == _trueTypeOf(var2) );
      if (isEqual && !isSame) {
          switch (type) {
              case 'String':
              case 'Number':
                  isEqual = (var1 == var2);
                  break;
              case 'Boolean':
              case 'Date':
                  isEqual = isSame;
                  break;
              case 'RegExp':
              case 'Function':
                  isEqual = (var1.toString() === var2.toString());
                  break;
              default: //Object | Array
                  isEqual = var1.constructor === var2.constructor;
                  var i;
                  for (i in var1) {
                      assertObjectEquals(msg + ' found nested ' + type + '@' + i + '\n', var1[i], var2[i]);
                  }
                  for (i in var2) {
                      if (!(i in var1)) {
                          isEqual = false;
                      }
                  }
          }
      }
      var ds1 = _displayStringForValue(var1);
      var ds2 = _displayStringForValue(var2);
      var sep = Math.max(ds1.length, ds2.length) < 40 ? ' ' : '\n';
      _assert(msg, isEqual, 'Expected' + sep + ds1 + sep + 'but was' + sep + ds2);
  }
  
  assertArrayEquals = assertObjectEquals;
  
  function assertEvaluatesToTrue() {
      _validateArguments(1, arguments);
      var value = nonCommentArg(1, 1, arguments);
      if (!value)
          fail(commentArg(1, arguments));
  }
  
  function assertEvaluatesToFalse() {
      _validateArguments(1, arguments);
      var value = nonCommentArg(1, 1, arguments);
      if (value)
          fail(commentArg(1, arguments));
  }
  
  function assertHTMLEquals() {
      _validateArguments(2, arguments);
      var var1 = nonCommentArg(1, 2, arguments);
      var var2 = nonCommentArg(2, 2, arguments);
      var var1Standardized = standardizeHTML(var1);
      var var2Standardized = standardizeHTML(var2);
  
      _assert(commentArg(2, arguments), var1Standardized === var2Standardized, 'Expected ' + _displayStringForValue(var1Standardized) + ' but was ' + _displayStringForValue(var2Standardized));
  }
  
  function assertHashEquals() {
      _validateArguments(2, arguments);
      var var1 = nonCommentArg(1, 2, arguments);
      var var2 = nonCommentArg(2, 2, arguments);
      for (var key in var1) {
          assertNotUndefined("Expected hash had key " + key + " that was not found", var2[key]);
          assertEquals(
                  "Value for key " + key + " mismatch - expected = " + var1[key] + ", actual = " + var2[key],
                  var1[key], var2[key]
                  );
      }
      for (var key in var2) {
          assertNotUndefined("Actual hash had key " + key + " that was not expected", var1[key]);
      }
  }
  
  function assertRoughlyEquals() {
      _validateArguments(3, arguments);
      var comment = commentArg(3, arguments);
      var expected = nonCommentArg(1, 3, arguments);
      var actual = nonCommentArg(2, 3, arguments);
      var tolerance = nonCommentArg(3, 3, arguments);
      _assert(commentArg(3, arguments),
              Math.abs(expected - actual) < tolerance,
              "Expected " + expected + ", but got " + actual + " which was more than " + tolerance + " away"
              );
  }
  
  function assertContains() {
      _validateArguments(2, arguments);
      var contained = nonCommentArg(1, 2, arguments);
      var container = nonCommentArg(2, 2, arguments);
      _assert(commentArg(2, arguments),
              container.indexOf(contained) != -1,
              "Expected '" + container + "' to contain '" + contained + "'"
              );
  }
  
  function assertLessThan(value, exclusiveUpperBound) {
      _validateArguments(2, arguments);
      var value = nonCommentArg(1, 2, arguments);
      var exclusiveUpperBound = nonCommentArg(2, 2, arguments);
      if (!(exclusiveUpperBound > value)) {
          var comment = commentArg(2, arguments);
          error((comment ? comment + ' : ' : '')
                + value + ' >= ' + exclusiveUpperBound);
      }
  }
  
  function assertThrows(func, opt_msg) {
      var nil = {};
      var thrown = nil;
      try {
          func();
      } catch (ex) {
          thrown = ex;
      }
      if (thrown !== nil) {
          if (opt_msg) { assertEquals(opt_msg, thrown); }
      } else {
          fail('Did not throw ' + (opt_msg ? opt_msg : 'an exception'));
      }
  }
  
  function standardizeHTML(html) {
      var translator = document.createElement("DIV");
      translator.innerHTML = html;
      return translator.innerHTML;
  }
  
  function isLoaded() {
      return isTestPageLoaded;
  }
  
  function setUp() {
  }
  
  function tearDown() {
  }
  
  function getFunctionName(aFunction) {
      var regexpResult = aFunction.toString().match(/function(\s*)(\w*)/);
      if (regexpResult && regexpResult.length >= 2 && regexpResult[2]) {
          return regexpResult[2];
      }
      return 'anonymous';
  }
  
  function getStackTrace() {
      var result = '';
  
      if (typeof(arguments.caller) != 'undefined') { // IE, not ECMA
          for (var a = arguments.caller; a != null; a = a.caller) {
              result += '> ' + getFunctionName(a.callee) + '\n';
              if (a.caller == a) {
                  result += '*';
                  break;
              }
          }
      }
      else { // Mozilla, not ECMA
          // fake an exception so we can get Mozilla's error stack
          var testExcp;
          try
          {
              throw new Error();
          }
          catch(testExcp)
          {
              var stack = parseErrorStack(testExcp);
              for (var i = 1; i < stack.length; i++)
              {
                  result += '> ' + stack[i] + '\n';
              }
          }
      }
  
      return result;
  }
  
  function parseErrorStack(excp)
  {
      var stack = [];
      var name;
  
      if (!excp || !excp.stack)
      {
          return stack;
      }
  
      var stacklist = excp.stack.split('\n');
  
      for (var i = 0; i < stacklist.length - 1; i++)
      {
          var framedata = stacklist[i];
  
          name = framedata.match(/^(\w*)/)[1];
          if (!name) {
              name = 'anonymous';
          }
  
          stack[stack.length] = name;
      }
      // remove top level anonymous functions to match IE
  
      while (stack.length && stack[stack.length - 1] == 'anonymous')
      {
          stack.length = stack.length - 1;
      }
      return stack;
  }
  
  function JsUnitException(comment, message) {
      this.isJsUnitException = true;
      this.comment = comment;
      this.jsUnitMessage = message;
      this.stackTrace = getStackTrace();
  }
  JsUnitException.prototype.toString = function () {
    return ('[JsUnitException ' + (this.comment || '')
            + ' : ' + this.jsUnitMessage + '\n' + this.stackTrace + ']');
  };
  
  function warn() {
      if (top.tracer != null)
          top.tracer.warn(arguments[0], arguments[1]);
  }
  
  function inform() {
      if (top.tracer != null)
          top.tracer.inform(arguments[0], arguments[1]);
  }
  
  function info() {
      inform(arguments[0], arguments[1]);
  }
  
  function debug() {
      if (top.tracer != null)
          top.tracer.debug(arguments[0], arguments[1]);
  }
  
  function setJsUnitTracer(aJsUnitTracer) {
      top.tracer = aJsUnitTracer;
  }
  
  function trim(str) {
      if (str == null)
          return null;
  
      var startingIndex = 0;
      var endingIndex = str.length - 1;
  
      while (str.substring(startingIndex, startingIndex + 1) == ' ')
          startingIndex++;
  
      while (str.substring(endingIndex, endingIndex + 1) == ' ')
          endingIndex--;
  
      if (endingIndex < startingIndex)
          return '';
  
      return str.substring(startingIndex, endingIndex + 1);
  }
  
  function isBlank(str) {
      return trim(str) == '';
  }
  
  // the functions push(anArray, anObject) and pop(anArray)
  // exist because the JavaScript Array.push(anObject) and Array.pop()
  // functions are not available in IE 5.0
  
  function push(anArray, anObject) {
      anArray[anArray.length] = anObject;
  }
  function pop(anArray) {
      if (anArray.length >= 1) {
          delete anArray[anArray.length - 1];
          anArray.length--;
      }
  }
  
  function jsUnitGetParm(name)
  {
      if (typeof(top.jsUnitParmHash[name]) != 'undefined')
      {
          return top.jsUnitParmHash[name];
      }
      return null;
  }
  
  if (typeof top !== 'undefined' && typeof(top.xbDEBUG) !== 'undefined' && top.xbDEBUG.on && top.testManager)
  {
      top.xbDebugTraceObject('top.testManager.containerTestFrame', 'JSUnitException');
      // asserts
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', '_displayStringForValue');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'error');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'argumentsIncludeComments');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'commentArg');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'nonCommentArg');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', '_validateArguments');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', '_assert');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assert');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertTrue');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertEquals');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNotEquals');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNull');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNotNull');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertUndefined');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNotUndefined');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNaN');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNotNaN');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'isLoaded');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'setUp');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'tearDown');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'getFunctionName');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'getStackTrace');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'warn');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'inform');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'debug');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'setJsUnitTracer');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'trim');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'isBlank');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'newOnLoadEvent');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'push');
      top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'pop');
  }
  
  function newOnLoadEvent() {
      isTestPageLoaded = true;
  }
  
  function jsUnitSetOnLoad(windowRef, onloadHandler) {
      var isKonqueror = navigator.userAgent.indexOf('Konqueror/') != -1;
  
      if (typeof(windowRef.attachEvent) !== 'undefined') {
          // Internet Explorer, Opera
          windowRef.attachEvent("onload", onloadHandler);
      } else if (typeof(windowRef.addEventListener) != 'undefined' && !isKonqueror) {
          // Mozilla
          // exclude Konqueror due to load issues
          windowRef.addEventListener("load", onloadHandler, false);
      } else if (typeof(windowRef.document.addEventListener) != 'undefined' && !isKonqueror) {
          // DOM 2 Events
          // exclude Mozilla, Konqueror due to load issues
          windowRef.document.addEventListener("load", onloadHandler, false);
      } else if (typeof(windowRef.onload) != 'undefined' && windowRef.onload) {
          windowRef.jsunit_original_onload = windowRef.onload;
          windowRef.onload = function() {
              windowRef.jsunit_original_onload();
              onloadHandler();
          };
      } else {
          // browsers that do not support windowRef.attachEvent or
          // windowRef.addEventListener will override a page's own onload event
          windowRef.onload = onloadHandler;
      }
  }
  
  if (typeof window !== 'undefined') {
    jsUnitSetOnLoad(window, newOnLoadEvent);
  }
  