[jboss-svn-commits] JBL Code SVN: r5994 - in labs/jbosslabs/trunk/portal-extensions/portal-dnd: . dndRenderer.war/js/portal jsunit jsunit/app jsunit/app/css jsunit/bin jsunit/bin/mac jsunit/bin/unix jsunit/css jsunit/images jsunit/java jsunit/java/bin jsunit/java/config jsunit/java/lib jsunit/java/source_core jsunit/java/source_core/net jsunit/java/source_core/net/jsunit jsunit/java/source_core/net/jsunit/configuration jsunit/java/source_core/net/jsunit/logging jsunit/java/source_core/net/jsunit/model jsunit/java/source_core/net/jsunit/utility jsunit/java/source_core/net/jsunit/version jsunit/java/source_server jsunit/java/source_server/net jsunit/java/source_server/net/jsunit jsunit/java/source_server/net/jsunit/action jsunit/java/source_server/net/jsunit/interceptor jsunit/java/testlib jsunit/java/tests_core jsunit/java/tests_core/net jsunit/java/tests_core/net/jsunit jsunit/java/tests_core/net/jsunit/configuration jsunit/java/tests_core/net/jsunit/model jsunit/java/tests_core/net/j! sunit/version jsunit/java/tests_server jsunit/java/tests_server/net jsunit/java/tests_server/net/jsunit jsunit/java/tests_server/net/jsunit/action jsunit/java/tests_server/net/jsunit/interceptor jsunit/licenses jsunit/tests jsunit/tests/data test

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Mon Aug 28 17:39:20 EDT 2006


Author: szimano
Date: 2006-08-28 17:37:06 -0400 (Mon, 28 Aug 2006)
New Revision: 5994

Added:
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/css/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/css/jsUnitStyle.css
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/css/readme
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/emptyPage.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/jsUnitCore.js
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/jsUnitMockTimeout.js
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/jsUnitTestManager.js
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/jsUnitTestSuite.js
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/jsUnitTracer.js
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/jsUnitVersionCheck.js
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-counts-errors.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-counts-failures.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-counts-runs.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-counts.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-data.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-errors.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-frame.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-loader.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-progress.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-results.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-status.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/testContainer.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/testContainerController.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/xbDebug.js
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/readme.txt
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/start-firefox.scpt
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/start-firefox.sh
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/start-safari.scpt
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/start-safari.sh
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/stop-firefox.scpt
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/stop-firefox.sh
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/stop-safari.scpt
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/stop-safari.sh
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/unix/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/unix/start-firefox.sh
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/unix/stop-firefox.sh
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/build.xml
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/changelog.txt
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/css/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/css/jsUnitStyle.css
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/images/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/images/green.gif
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/images/logo_jsunit.gif
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/images/powerby-transparent.gif
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/images/red.gif
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/index.jsp
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/bin/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/bin/jsunit.jar
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/config/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/config/farm_xwork.xml
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/config/xwork.xml
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/ant.jar
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/commons-el.jar
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/commons-logging.jar
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/jasper-compiler.jar
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/jasper-runtime.jar
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/javax.servlet.jar
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/jdom.jar
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/junit.jar
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/ognl.jar
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/org.mortbay.jetty.jar
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/oscore.jar
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/rife-continuations.jar
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/start.jar
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/stop.jar
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/webwork-2.2-beta-4.jar
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/xercesImpl-2.6.2.jar
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/xwork-1.1.jar
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/BrowserLaunchSpecification.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/BrowserTestRunner.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/ClientSideConnection.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/InvalidBrowserIdException.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/MessageReceiver.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/RemoteTestRunClient.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/ServerSideConnection.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/TestRunListener.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/TestRunNotifierServer.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/XmlRenderable.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/ArgumentsConfigurationSource.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/CompositeConfigurationSource.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/Configuration.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/ConfigurationException.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/ConfigurationProperty.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/ConfigurationSource.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/DelegatingConfigurationSource.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/EnvironmentVariablesConfigurationSource.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/FarmConfiguration.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/FarmConfigurationSource.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/PropertiesFileConfigurationSource.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/ServerType.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/logging/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/logging/BrowserResultRepository.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/logging/FileBrowserResultRepository.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/logging/StubBrowserResultRepository.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/AbstractResult.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/Browser.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/BrowserResult.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/BrowserResultBuilder.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/BrowserResultWriter.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/BrowserSource.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/DistributedTestRunResult.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/DistributedTestRunResultBuilder.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/Result.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/ResultType.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/TestCaseResult.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/TestCaseResultBuilder.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/TestCaseResultWriter.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/TestPageResult.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/TestRunResult.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/TestRunResultBuilder.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/utility/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/utility/CollectionUtility.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/utility/FileUtility.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/utility/StreamUtility.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/utility/StringUtility.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/utility/SystemUtility.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/utility/XmlUtility.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/version/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/version/JsUnitWebsiteVersionGrabber.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/version/VersionChecker.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/version/VersionGrabber.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/AbstractJsUnitServer.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/BlowingUpProcessStarter.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/BrowserResultLogWriter.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/DefaultProcessStarter.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/DistributedTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/DistributedTestRunManager.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/DistributedTestSuiteBuilder.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/JsUnitFarmServer.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/JsUnitServer.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/JsUnitStandardServer.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/LaunchTestRunCommand.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/NoUrlSpecifiedException.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/PlatformType.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/ProcessStarter.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/RemoteConfigurationSource.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/RemoteMachineServerHitter.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/RemoteServerHitter.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/ServerRegistry.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/StandaloneTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/TestRunManager.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/TimeoutChecker.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/BrowserResultAware.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/BrowserTestRunnerConfigurationAction.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/DistributedTestRunnerAction.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/ErrorXmlRenderable.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/FarmServerConfigurationAction.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/IndexAction.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/JsUnitBrowserTestRunnerAction.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/JsUnitFarmServerAction.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/JsUnitServerAware.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/LatestVersionAction.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/LatestVersionResult.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/LatestVersionSource.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/RemoteRunnerHitterAware.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/RequestSourceAware.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/ResultAcceptorAction.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/ResultDisplayerAction.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/StandaloneTestAware.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/TestRunnerAction.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/VersionGrabberAware.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/XmlProducer.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/XmlResult.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/BrowserResultInterceptor.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/BrowserTestRunnerInterceptor.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/BrowserTestRunnerSource.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/DefaultBrowserTestRunnerSource.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/FarmServerInterceptor.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/JsUnitInterceptor.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/RemoteRunnerHitterInterceptor.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/RequestSourceInterceptor.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/VersionGrabberInterceptor.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/testlib/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/testlib/ashcroft.jar
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/testlib/httpunit-1.5.4.jar
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/testlib/js-1.5R4.1.jar
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/testlib/jwebunit-1.2.jar
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/testlib/nekohtml-0.8.1.jar
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/testlib/xml-apis-1.0.b2.jar
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/BrowserLaunchSpecificationTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/ClientServerConnectionTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/ClientServerInteractionTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/DistributedTestRunResultTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/DummyBrowserResult.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/MockBrowserTestRunner.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/MockMessageReceiver.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/MockTestRunListener.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/RemoteTestRunClientTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/StubConfigurationSource.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/TestRunNotifierServerTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/TestRunResultTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/configuration/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/configuration/ArgumentsConfigurationSourceTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/configuration/CompositeConfigurationSourceTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/configuration/ConfigurationSourceResolutionTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/configuration/ConfigurationTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/configuration/EnvironmentVariablesConfigurationSourceTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/configuration/PropertiesConfigurationSourceTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/BrowserResultTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/BrowserTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/DistributedTestRunResultBuilderTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/DummyBrowserSource.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/ExternallyShutDownBrowserResultTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/FailedToLaunchBrowserResultTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/TestCaseResultTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/TestPageResultTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/TestRunResultBuilderTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/TimedOutBrowerResultTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/version/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/version/BlowingUpVersionGrabber.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/version/MockVersionGrabber.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/version/VersionCheckerTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/AcceptorFunctionalTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/BlowingUpRemoteServerHitter.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/BrowserResultLogWriterTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/ConfigurationFunctionalTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/DisplayerFunctionalTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/DistributedTestRunManagerTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/DistributedTestSuiteBuilderTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/DummyConfigurationSource.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/DummyFarmConfigurationSource.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/DummyHttpRequest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/EndToEndTestCase.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/ExternallyShutDownStandaloneTestTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FailedToLaunchBrowserStandaloneTestTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FarmServerFunctionalTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FarmServerFunctionalTestSuite.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FarmServerLandingPageFunctionalTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FunctionalTestCase.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FunctionalTestConfigurationSource.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FunctionalTestFarmConfigurationSource.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FunctionalTestSuite.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/ImpureUnitTestSuite.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/InvalidRemoteMachinesDistributedTestTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/JsUnitFarmServerTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/JsUnitStandardServerTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/MockBrowserResultRepository.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/MockProcessStarter.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/MockRemoteServerHitter.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/OverrideURLDistributedTestTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/PureUnitTestSuite.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/RemoteConfigurationSourceFunctionalTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/RemoteConfigurationSourceTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/RemoteMachineRunnerHitterTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/ResultAcceptorTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/RunnerFunctionalTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/ServerLandingPageFunctionalTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/SpecificBrowserDistributedTestTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/SuccessfulStandaloneTestTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/TestPortManager.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/TestRunManagerTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/TimedOutBrowserStandaloneTestTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/TimeoutCheckerTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/TwoValidLocalhostsDistributedTestTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/UnitTestSuite.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/UrlOverrideStandaloneTestTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/BlockingTestRunner.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/DistributedTestRunnerActionTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/ErrorXmlRenderableTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/FarmServerConfigurationActionTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/LatestVersionActionTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/ResultAcceptorActionTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/ResultDisplayerActionTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/TestRunnerActionSimultaneousRunBlockingTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/TestRunnerActionTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/interceptor/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/interceptor/BrowserResultInterceptorTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/interceptor/BrowserTestRunnerInterceptorTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/interceptor/FarmServerInterceptorTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/interceptor/MockActionInvocation.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/interceptor/RemoteRunnerHitterInterceptorTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/interceptor/RequestSourceInterceptorTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/interceptor/VersionGrabberInterceptorTest.java
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/jsunit.properties.sample
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/JDOM_license.txt
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/Jetty_license.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/MPL-1.1.txt
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/gpl-2.txt
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/index.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/lgpl-2.1.txt
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/mpl-tri-license-c.txt
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/mpl-tri-license-html.txt
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/logging.properties
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/logs/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/readme.txt
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/testRunner.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/data/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/data/data.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/data/staff.css
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/data/staff.dtd
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/data/staff.xml
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitAssertionTests.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitFrameworkUtilityTests.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitMockTimeoutTest.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitOnLoadTests.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitRestoredHTMLDivTests.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitSetUpTearDownTests.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitTestLoadData.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitTestLoadStaff.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitTestSetUpPages.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitTestSetUpPagesSuite.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitTestSuite.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitUtilityTests.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitVersionCheckTests.html
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/test/
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/test/jsUnitCore.js
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/test/testPortletDrop.html
Modified:
   labs/jbosslabs/trunk/portal-extensions/portal-dnd/dndRenderer.war/js/portal/PortalDD.js
Log:
prototype testsuite for ajax stuff
JBLAB-728

Modified: labs/jbosslabs/trunk/portal-extensions/portal-dnd/dndRenderer.war/js/portal/PortalDD.js
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/dndRenderer.war/js/portal/PortalDD.js	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/dndRenderer.war/js/portal/PortalDD.js	2006-08-28 21:37:06 UTC (rev 5994)
@@ -2,7 +2,12 @@
 
 var borderBefore = "";
 var borderTopBefore = "";
+var ajaxEnabled = true;
 
+function setAjaxEnabled(enabled) {
+	ajaxEnabled = enabled;
+}
+
 function getBorder(id) {
 	YAHOO.util.Dom.setStyle(id, "border-top", borderTopBefore);
 	YAHOO.util.Dom.setStyle(id, "border", borderBefore);
@@ -27,31 +32,32 @@
 }
 
 function invokeAjax(postData) {
-
-    var handleSuccess = function(o){ 
-	 
-	    if(o.responseText !== undefined){ 
-	        log.log("Transaction id: " + o.tId); 
-	        log.log("HTTP status: " + o.status); 
-	        log.log("Status code message: " + o.statusText); 
-	        log.log("<li>HTTP headers: <ul>" + o.getAllResponseHeaders + "</ul></li>"); 
-	        log.log("Servlet response: " + o.responseText); 
-	        log.log("Argument object: " + o.argument); 
-	    } 
-	} 
-	
-	var handleFailure = function(o) {
-		log.log("Failure: " + o);
+	if (ajaxEnabled) {
+	    var handleSuccess = function(o){ 
+		 
+		    if(o.responseText !== undefined){ 
+		        log.log("Transaction id: " + o.tId); 
+		        log.log("HTTP status: " + o.status); 
+		        log.log("Status code message: " + o.statusText); 
+		        log.log("<li>HTTP headers: <ul>" + o.getAllResponseHeaders + "</ul></li>"); 
+		        log.log("Servlet response: " + o.responseText); 
+		        log.log("Argument object: " + o.argument); 
+		    } 
+		} 
+		
+		var handleFailure = function(o) {
+			log.log("Failure: " + o);
+		}
+		 
+		var callback = 
+		{ 
+		  success:handleSuccess, 
+		  failure: handleFailure, 
+		  argument: ['foo','bar'] 
+		}; 
+		
+		var request = YAHOO.util.Connect.asyncRequest('POST', "/dndRenderer/ajax", callback, postData);
 	}
-	 
-	var callback = 
-	{ 
-	  success:handleSuccess, 
-	  failure: handleFailure, 
-	  argument: ['foo','bar'] 
-	}; 
-	
-	var request = YAHOO.util.Connect.asyncRequest('POST', "/dndRenderer/ajax", callback, postData); 
 }
 
 YAHOO.util.PortalDD = function(id, sGroup, config) {

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/css/jsUnitStyle.css
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/css/jsUnitStyle.css	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/css/jsUnitStyle.css	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,50 @@
+body {
+    margin-top: 0;
+    margin-bottom: 0;
+    font-family: Verdana, Arial, Helvetica, sans-serif;
+    color: #000;
+    font-size: 0.8em;
+    background-color: #fff;
+}
+
+a:link, a:visited {
+    color: #00F;
+}
+
+a:hover {
+    color: #F00;
+}
+
+h1 {
+    font-size: 1.2em;
+    font-weight: bold;
+    color: #039;
+    font-family: Verdana, Arial, Helvetica, sans-serif;
+}
+
+h2 {
+    font-weight: bold;
+    color: #039;
+    font-family: Verdana, Arial, Helvetica, sans-serif;
+}
+
+h3 {
+    font-weight: bold;
+    color: #039;
+    text-decoration: underline;
+    font-family: Verdana, Arial, Helvetica, sans-serif;
+}
+
+h4 {
+    font-weight: bold;
+    color: #039;
+    font-family: Verdana, Arial, Helvetica, sans-serif;
+}
+
+.jsUnitTestResultSuccess {
+    color: #000;
+}
+
+.jsUnitTestResultNotSuccess {
+    color: #F00;
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/css/readme
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/css/readme	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/css/readme	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,10 @@
+this file is required due to differences in behavior between Mozilla/Opera 
+and Internet Explorer.
+
+main-data.html calls kickOffTests() which calls top.testManager.start()
+in the top most frame. top.testManager.start() initializes the output 
+frames using document.write and HTML containing a relative <link> to the 
+jsUnitStyle.css file. In MSIE, the base href used to find the CSS file is 
+that of the top level frame however in Mozilla/Opera the base href is
+that of main-data.html. This leads to not-found for the jsUnitStyle.css
+in Mozilla/Opera. Creating app/css/jsUnitStyle.css works around this problem.

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/emptyPage.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/emptyPage.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/emptyPage.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>emptyPage</title>
+</head>
+
+<body>
+</body>
+</html>
+

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/jsUnitCore.js
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/jsUnitCore.js	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/jsUnitCore.js	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,534 @@
+var JSUNIT_UNDEFINED_VALUE;
+var JSUNIT_VERSION = 2.2;
+var isTestPageLoaded = false;
+
+//hack for NS62 bug
+function jsUnitFixTop() {
+    var tempTop = top;
+    if (!tempTop) {
+        tempTop = window;
+        while (tempTop.parent) {
+            tempTop = tempTop.parent;
+            if (tempTop.top && tempTop.top.jsUnitTestSuite) {
+                tempTop = tempTop.top;
+                break;
+            }
+        }
+    }
+    try {
+        window.top = tempTop;
+    } catch (e) {
+    }
+}
+
+jsUnitFixTop();
+
+/**
+ + * 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 String:
+                        result = 'String';
+                        break;
+                    case Boolean:
+                        result = 'Boolean';
+                        break;
+                    case Number:
+                        result = 'Number';
+                        break;
+                    case Array:
+                        result = 'Array';
+                        break;
+                    case RegExp:
+                        result = 'RegExp';
+                        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 = '<' + aVar + '>';
+    if (!(aVar === null || aVar === top.JSUNIT_UNDEFINED_VALUE)) {
+        result += ' (' + _trueTypeOf(aVar) + ')';
+    }
+    return result;
+}
+
+function fail(failureMessage) {
+    throw new JsUnitException("Call to fail()", failureMessage);
+}
+
+function error(errorMessage) {
+    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)
+        throw new JsUnitException(comment, failureMessage);
+}
+
+function assert() {
+    _validateArguments(1, arguments);
+    var booleanValue = nonCommentArg(1, 1, arguments);
+
+    if (typeof(booleanValue) != 'boolean')
+        error('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('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('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);
+    _assert(commentArg(2, arguments), 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 === top.JSUNIT_UNDEFINED_VALUE, 'Expected ' + _displayStringForValue(top.JSUNIT_UNDEFINED_VALUE) + ' but was ' + _displayStringForValue(aVar));
+}
+
+function assertNotUndefined() {
+    _validateArguments(1, arguments);
+    var aVar = nonCommentArg(1, 1, arguments);
+    _assert(commentArg(1, arguments), aVar !== top.JSUNIT_UNDEFINED_VALUE, 'Expected not to be ' + _displayStringForValue(top.JSUNIT_UNDEFINED_VALUE));
+}
+
+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 = (var1 === var2);
+                break;
+            case 'RegExp':
+            case 'Function':
+                isEqual = (var1.toString() === var2.toString());
+                break;
+            default: //Object | Array
+                var i;
+                if (isEqual = (var1.length === var2.length))
+                    for (i in var1)
+                        assertObjectEquals(msg + ' found nested ' + type + '@' + i + '\n', var1[i], var2[i]);
+        }
+        _assert(msg, isEqual, 'Expected ' + _displayStringForValue(var1) + ' but was ' + _displayStringForValue(var2));
+    }
+}
+
+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 expected = nonCommentArg(1, 3, arguments);
+    var actual = nonCommentArg(2, 3, arguments);
+    var tolerance = nonCommentArg(3, 3, arguments);
+    assertTrue(
+            "Expected " + expected + ", but got " + actual + " which was more than " + tolerance + " away",
+            Math.abs(expected - actual) < tolerance
+            );
+}
+
+function assertContains() {
+    _validateArguments(2, arguments);
+    var contained = nonCommentArg(1, 2, arguments);
+    var container = nonCommentArg(2, 2, arguments);
+    assertTrue(
+            "Expected '" + container + "' to contain '" + contained + "'",
+            container.indexOf(contained) != -1
+            );
+}
+
+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
+        {
+            foo.bar;
+        }
+        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();
+}
+
+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 (top && 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 ||
+                      navigator.userAgent.indexOf('Safari/') != -1;
+
+    if (typeof(windowRef.attachEvent) != 'undefined') {
+        // Internet Explorer, Opera
+        windowRef.attachEvent("onload", onloadHandler);
+    } else if (typeof(windowRef.addEventListener) != 'undefined' && !isKonqueror) {
+        // Mozilla, Konqueror
+        // 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;
+    }
+}
+
+jsUnitSetOnLoad(window, newOnLoadEvent);
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/jsUnitMockTimeout.js
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/jsUnitMockTimeout.js	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/jsUnitMockTimeout.js	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,81 @@
+// Mock setTimeout, clearTimeout
+// Contributed by Pivotal Computer Systems, www.pivotalsf.com
+
+var Clock = {
+    timeoutsMade: 0,
+    scheduledFunctions: {},
+    nowMillis: 0,
+    reset: function() {
+        this.scheduledFunctions = {};
+        this.nowMillis = 0;
+        this.timeoutsMade = 0;
+    },
+    tick: function(millis) {
+        var oldMillis = this.nowMillis;
+        var newMillis = oldMillis + millis;
+        this.runFunctionsWithinRange(oldMillis, newMillis);
+        this.nowMillis = newMillis;
+    },
+    runFunctionsWithinRange: function(oldMillis, nowMillis) {
+        var scheduledFunc;
+        var funcsToRun = [];
+        for (var timeoutKey in this.scheduledFunctions) {
+            scheduledFunc = this.scheduledFunctions[timeoutKey];
+            if (scheduledFunc != undefined &&
+                scheduledFunc.runAtMillis >= oldMillis &&
+                scheduledFunc.runAtMillis <= nowMillis) {
+                funcsToRun.push(scheduledFunc);
+                this.scheduledFunctions[timeoutKey] = undefined;
+            }
+        }
+
+        if (funcsToRun.length > 0) {
+            funcsToRun.sort(function(a, b) {
+                return a.runAtMillis - b.runAtMillis;
+            });
+            for (var i = 0; i < funcsToRun.length; ++i) {
+                try {
+                    this.nowMillis = funcsToRun[i].runAtMillis;
+                    funcsToRun[i].funcToCall();
+                    if (funcsToRun[i].recurring) {
+                        Clock.scheduleFunction(funcsToRun[i].timeoutKey,
+                                funcsToRun[i].funcToCall,
+                                funcsToRun[i].millis,
+                                true);
+                    }
+                } catch(e) {
+                }
+            }
+            this.runFunctionsWithinRange(oldMillis, nowMillis);
+        }
+    },
+    scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) {
+        Clock.scheduledFunctions[timeoutKey] = {
+            runAtMillis: Clock.nowMillis + millis,
+            funcToCall: funcToCall,
+            recurring: recurring,
+            timeoutKey: timeoutKey,
+            millis: millis
+        };
+    }
+};
+
+function setTimeout(funcToCall, millis) {
+    Clock.timeoutsMade = Clock.timeoutsMade + 1;
+    Clock.scheduleFunction(Clock.timeoutsMade, funcToCall, millis, false);
+    return Clock.timeoutsMade;
+}
+
+function setInterval(funcToCall, millis) {
+    Clock.timeoutsMade = Clock.timeoutsMade + 1;
+    Clock.scheduleFunction(Clock.timeoutsMade, funcToCall, millis, true);
+    return Clock.timeoutsMade;
+}
+
+function clearTimeout(timeoutKey) {
+    Clock.scheduledFunctions[timeoutKey] = undefined;
+}
+
+function clearInterval(timeoutKey) {
+    Clock.scheduledFunctions[timeoutKey] = undefined;
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/jsUnitTestManager.js
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/jsUnitTestManager.js	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/jsUnitTestManager.js	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,705 @@
+function jsUnitTestManager() {
+    this._windowForAllProblemMessages = null;
+
+    this.container = top.frames.testContainer
+    this.documentLoader = top.frames.documentLoader;
+    this.mainFrame = top.frames.mainFrame;
+
+    this.containerController = this.container.frames.testContainerController;
+    this.containerTestFrame = this.container.frames.testFrame;
+
+    var mainData = this.mainFrame.frames.mainData;
+
+    // form elements on mainData frame
+    this.testFileName = mainData.document.testRunnerForm.testFileName;
+    this.runButton = mainData.document.testRunnerForm.runButton;
+    this.traceLevel = mainData.document.testRunnerForm.traceLevel;
+    this.closeTraceWindowOnNewRun = mainData.document.testRunnerForm.closeTraceWindowOnNewRun;
+    this.timeout = mainData.document.testRunnerForm.timeout;
+    this.setUpPageTimeout = mainData.document.testRunnerForm.setUpPageTimeout;
+
+    // image output
+    this.progressBar = this.mainFrame.frames.mainProgress.document.progress;
+
+    this.problemsListField = this.mainFrame.frames.mainErrors.document.testRunnerForm.problemsList;
+    this.testCaseResultsField = this.mainFrame.frames.mainResults.document.resultsForm.testCases;
+    this.resultsTimeField = this.mainFrame.frames.mainResults.document.resultsForm.time;
+
+    // 'layer' output frames
+    this.uiFrames = new Object();
+    this.uiFrames.mainStatus = this.mainFrame.frames.mainStatus;
+
+    var mainCounts = this.mainFrame.frames.mainCounts;
+
+    this.uiFrames.mainCountsErrors = mainCounts.frames.mainCountsErrors;
+    this.uiFrames.mainCountsFailures = mainCounts.frames.mainCountsFailures;
+    this.uiFrames.mainCountsRuns = mainCounts.frames.mainCountsRuns;
+    this._baseURL = "";
+
+    this.setup();
+}
+
+// seconds to wait for each test page to load
+jsUnitTestManager.TESTPAGE_WAIT_SEC = 120;
+jsUnitTestManager.TIMEOUT_LENGTH = 20;
+
+// seconds to wait for setUpPage to complete
+jsUnitTestManager.SETUPPAGE_TIMEOUT = 120;
+
+// milliseconds to wait between polls on setUpPages
+jsUnitTestManager.SETUPPAGE_INTERVAL = 100;
+
+jsUnitTestManager.RESTORED_HTML_DIV_ID = "jsUnitRestoredHTML";
+
+jsUnitTestManager.prototype.setup = function () {
+    this.totalCount = 0;
+    this.errorCount = 0;
+    this.failureCount = 0;
+    this._suiteStack = Array();
+
+    var initialSuite = new top.jsUnitTestSuite();
+    push(this._suiteStack, initialSuite);
+}
+
+jsUnitTestManager.prototype.start = function () {
+    this._baseURL = this.resolveUserEnteredTestFileName();
+    var firstQuery = this._baseURL.indexOf("?");
+    if (firstQuery >= 0) {
+        this._baseURL = this._baseURL.substring(0, firstQuery);
+    }
+    var lastSlash = this._baseURL.lastIndexOf("/");
+    var lastRevSlash = this._baseURL.lastIndexOf("\\");
+    if (lastRevSlash > lastSlash) {
+        lastSlash = lastRevSlash;
+    }
+    if (lastSlash > 0) {
+        this._baseURL = this._baseURL.substring(0, lastSlash + 1);
+    }
+
+    this._timeRunStarted = new Date();
+    this.initialize();
+    setTimeout('top.testManager._nextPage();', jsUnitTestManager.TIMEOUT_LENGTH);
+}
+
+jsUnitTestManager.prototype.getBaseURL = function () {
+    return this._baseURL;
+}
+
+jsUnitTestManager.prototype.doneLoadingPage = function (pageName) {
+    //this.containerTestFrame.setTracer(top.tracer);
+    this._testFileName = pageName;
+    if (this.isTestPageSuite())
+        this._handleNewSuite();
+    else
+    {
+        this._testIndex = 0;
+        this._testsInPage = this.getTestFunctionNames();
+        this._numberOfTestsInPage = this._testsInPage.length;
+        this._runTest();
+    }
+}
+
+jsUnitTestManager.prototype._handleNewSuite = function () {
+    var allegedSuite = this.containerTestFrame.suite();
+    if (allegedSuite.isjsUnitTestSuite) {
+        var newSuite = allegedSuite.clone();
+        if (newSuite.containsTestPages())
+            push(this._suiteStack, newSuite);
+        this._nextPage();
+    }
+    else {
+        this.fatalError('Invalid test suite in file ' + this._testFileName);
+        this.abort();
+    }
+}
+
+jsUnitTestManager.prototype._runTest = function () {
+    if (this._testIndex + 1 > this._numberOfTestsInPage)
+    {
+        // execute tearDownPage *synchronously*
+        // (unlike setUpPage which is asynchronous)
+        if (typeof this.containerTestFrame.tearDownPage == 'function') {
+            this.containerTestFrame.tearDownPage();
+        }
+
+        this._nextPage();
+        return;
+    }
+
+    if (this._testIndex == 0) {
+        this.storeRestoredHTML();
+        if (typeof(this.containerTestFrame.setUpPage) == 'function') {
+            // first test for this page and a setUpPage is defined
+            if (typeof(this.containerTestFrame.setUpPageStatus) == 'undefined') {
+                // setUpPage() not called yet, so call it
+                this.containerTestFrame.setUpPageStatus = false;
+                this.containerTestFrame.startTime = new Date();
+                this.containerTestFrame.setUpPage();
+                // try test again later
+                setTimeout('top.testManager._runTest()', jsUnitTestManager.SETUPPAGE_INTERVAL);
+                return;
+            }
+
+            if (this.containerTestFrame.setUpPageStatus != 'complete') {
+                top.status = 'setUpPage not completed... ' + this.containerTestFrame.setUpPageStatus + ' ' + (new Date());
+                if ((new Date() - this.containerTestFrame.startTime) / 1000 > this.getsetUpPageTimeout()) {
+                    this.fatalError('setUpPage timed out without completing.');
+                    if (!this.userConfirm('Retry Test Run?')) {
+                        this.abort();
+                        return;
+                    }
+                    this.containerTestFrame.startTime = (new Date());
+                }
+                // try test again later
+                setTimeout('top.testManager._runTest()', jsUnitTestManager.SETUPPAGE_INTERVAL);
+                return;
+            }
+        }
+    }
+
+    top.status = '';
+    // either not first test, or no setUpPage defined, or setUpPage completed
+    this.executeTestFunction(this._testsInPage[this._testIndex]);
+    this.totalCount++;
+    this.updateProgressIndicators();
+    this._testIndex++;
+    setTimeout('top.testManager._runTest()', jsUnitTestManager.TIMEOUT_LENGTH);
+}
+
+jsUnitTestManager.prototype._done = function () {
+    var secondsSinceRunBegan = (new Date() - this._timeRunStarted) / 1000;
+    this.setStatus('Done (' + secondsSinceRunBegan + ' seconds)');
+    this._cleanUp();
+    if (top.shouldSubmitResults()) {
+        this.resultsTimeField.value = secondsSinceRunBegan;
+        top.submitResults();
+    }
+}
+
+jsUnitTestManager.prototype._nextPage = function () {
+    this._restoredHTML = null;
+    if (this._currentSuite().hasMorePages()) {
+        this.loadPage(this._currentSuite().nextPage());
+    }
+    else {
+        pop(this._suiteStack);
+        if (this._currentSuite() == null)
+            this._done();
+        else
+            this._nextPage();
+    }
+}
+
+jsUnitTestManager.prototype._currentSuite = function () {
+    var suite = null;
+
+    if (this._suiteStack && this._suiteStack.length > 0)
+        suite = this._suiteStack[this._suiteStack.length - 1];
+
+    return suite;
+}
+
+jsUnitTestManager.prototype.calculateProgressBarProportion = function () {
+    if (this.totalCount == 0)
+        return 0;
+    var currentDivisor = 1;
+    var result = 0;
+
+    for (var i = 0; i < this._suiteStack.length; i++) {
+        var aSuite = this._suiteStack[i];
+        currentDivisor *= aSuite.testPages.length;
+        result += (aSuite.pageIndex - 1) / currentDivisor;
+    }
+    result += (this._testIndex + 1) / (this._numberOfTestsInPage * currentDivisor);
+    return result;
+}
+
+jsUnitTestManager.prototype._cleanUp = function () {
+    this.containerController.setTestPage('./app/emptyPage.html');
+    this.finalize();
+    top.tracer.finalize();
+}
+
+jsUnitTestManager.prototype.abort = function () {
+    this.setStatus('Aborted');
+    this._cleanUp();
+}
+
+jsUnitTestManager.prototype.getTimeout = function () {
+    var result = jsUnitTestManager.TESTPAGE_WAIT_SEC;
+    try {
+        result = eval(this.timeout.value);
+    }
+    catch (e) {
+    }
+    return result;
+}
+
+jsUnitTestManager.prototype.getsetUpPageTimeout = function () {
+    var result = jsUnitTestManager.SETUPPAGE_TIMEOUT;
+    try {
+        result = eval(this.setUpPageTimeout.value);
+    }
+    catch (e) {
+    }
+    return result;
+}
+
+jsUnitTestManager.prototype.isTestPageSuite = function () {
+    var result = false;
+    if (typeof(this.containerTestFrame.suite) == 'function')
+    {
+        result = true;
+    }
+    return result;
+}
+
+jsUnitTestManager.prototype.getTestFunctionNames = function () {
+    var testFrame = this.containerTestFrame;
+    var testFunctionNames = new Array();
+    var i;
+
+    if (testFrame && typeof(testFrame.exposeTestFunctionNames) == 'function')
+        return testFrame.exposeTestFunctionNames();
+
+    if (testFrame &&
+        testFrame.document &&
+        typeof(testFrame.document.scripts) != 'undefined' &&
+        testFrame.document.scripts.length > 0) { // IE5 and up
+        var scriptsInTestFrame = testFrame.document.scripts;
+
+        for (i = 0; i < scriptsInTestFrame.length; i++) {
+            var someNames = this._extractTestFunctionNamesFromScript(scriptsInTestFrame[i]);
+            if (someNames)
+                testFunctionNames = testFunctionNames.concat(someNames);
+        }
+    }
+    else {
+        for (i in testFrame) {
+            if (i.substring(0, 4) == 'test' && typeof(testFrame[i]) == 'function')
+                push(testFunctionNames, i);
+        }
+    }
+    return testFunctionNames;
+}
+
+jsUnitTestManager.prototype._extractTestFunctionNamesFromScript = function (aScript) {
+    var result;
+    var remainingScriptToInspect = aScript.text;
+    var currentIndex = this._indexOfTestFunctionIn(remainingScriptToInspect);
+    while (currentIndex != -1) {
+        if (!result)
+            result = new Array();
+
+        var fragment = remainingScriptToInspect.substring(currentIndex, remainingScriptToInspect.length);
+        result = result.concat(fragment.substring('function '.length, fragment.indexOf('(')));
+        remainingScriptToInspect = remainingScriptToInspect.substring(currentIndex + 12, remainingScriptToInspect.length);
+        currentIndex = this._indexOfTestFunctionIn(remainingScriptToInspect);
+    }
+    return result;
+}
+
+jsUnitTestManager.prototype._indexOfTestFunctionIn = function (string) {
+    return string.indexOf('function test');
+}
+
+jsUnitTestManager.prototype.loadPage = function (testFileName) {
+    this._testFileName = testFileName;
+    this._loadAttemptStartTime = new Date();
+    this.setStatus('Opening Test Page "' + this._testFileName + '"');
+    this.containerController.setTestPage(this._testFileName);
+    this._callBackWhenPageIsLoaded();
+}
+
+jsUnitTestManager.prototype._callBackWhenPageIsLoaded = function () {
+    if ((new Date() - this._loadAttemptStartTime) / 1000 > this.getTimeout()) {
+        this.fatalError('Reading Test Page ' + this._testFileName + ' timed out.\nMake sure that the file exists and is a Test Page.');
+        if (this.userConfirm('Retry Test Run?')) {
+            this.loadPage(this._testFileName);
+            return;
+        } else {
+            this.abort();
+            return;
+        }
+    }
+    if (!this._isTestFrameLoaded()) {
+        setTimeout('top.testManager._callBackWhenPageIsLoaded();', jsUnitTestManager.TIMEOUT_LENGTH);
+        return;
+    }
+    this.doneLoadingPage(this._testFileName);
+}
+
+jsUnitTestManager.prototype._isTestFrameLoaded = function () {
+    try {
+        return this.containerController.isPageLoaded();
+    }
+    catch (e) {
+    }
+    return false;
+}
+
+jsUnitTestManager.prototype.executeTestFunction = function (functionName) {
+    this._testFunctionName = functionName;
+    this.setStatus('Running test "' + this._testFunctionName + '"');
+    var excep = null;
+    var timeBefore = new Date();
+    try {
+        if (this._restoredHTML)
+            top.testContainer.testFrame.document.getElementById(jsUnitTestManager.RESTORED_HTML_DIV_ID).innerHTML = this._restoredHTML;
+        if (this.containerTestFrame.setUp !== JSUNIT_UNDEFINED_VALUE)
+            this.containerTestFrame.setUp();
+        this.containerTestFrame[this._testFunctionName]();
+    }
+    catch (e1) {
+        excep = e1;
+    }
+    finally {
+        try {
+            if (this.containerTestFrame.tearDown !== JSUNIT_UNDEFINED_VALUE)
+                this.containerTestFrame.tearDown();
+        }
+        catch (e2) {
+            //Unlike JUnit, only assign a tearDown exception to excep if there is not already an exception from the test body
+            if (excep == null)
+                excep = e2;
+        }
+    }
+    var timeTaken = (new Date() - timeBefore) / 1000;
+    if (excep != null)
+        this._handleTestException(excep);
+    var serializedTestCaseString = this._currentTestFunctionNameWithTestPageName(true) + "|" + timeTaken + "|";
+    if (excep == null)
+        serializedTestCaseString += "S||";
+    else {
+        if (typeof(excep.isJsUnitException) != 'undefined' && excep.isJsUnitException)
+            serializedTestCaseString += "F|";
+        else {
+            serializedTestCaseString += "E|";
+        }
+        serializedTestCaseString += this._problemDetailMessageFor(excep);
+    }
+    this._addOption(this.testCaseResultsField,
+            serializedTestCaseString,
+            serializedTestCaseString);
+}
+
+jsUnitTestManager.prototype._currentTestFunctionNameWithTestPageName = function(useFullyQualifiedTestPageName) {
+    var testURL = this.containerTestFrame.location.href;
+    var testQuery = testURL.indexOf("?");
+    if (testQuery >= 0) {
+        testURL = testURL.substring(0, testQuery);
+    }
+    if (!useFullyQualifiedTestPageName) {
+        if (testURL.substring(0, this._baseURL.length) == this._baseURL)
+            testURL = testURL.substring(this._baseURL.length);
+    }
+    return testURL + ':' + this._testFunctionName;
+}
+
+jsUnitTestManager.prototype._addOption = function(listField, problemValue, problemMessage) {
+    if (typeof(listField.ownerDocument) != 'undefined'
+            && typeof(listField.ownerDocument.createElement) != 'undefined') {
+        // DOM Level 2 HTML method.
+        // this is required for Opera 7 since appending to the end of the
+        // options array does not work, and adding an Option created by new Option()
+        // and appended by listField.options.add() fails due to WRONG_DOCUMENT_ERR
+        var problemDocument = listField.ownerDocument;
+        var errOption = problemDocument.createElement('option');
+        errOption.setAttribute('value', problemValue);
+        errOption.appendChild(problemDocument.createTextNode(problemMessage));
+        listField.appendChild(errOption);
+    }
+    else {
+        // new Option() is DOM 0
+        errOption = new Option(problemMessage, problemValue);
+        if (typeof(listField.add) != 'undefined') {
+            // DOM 2 HTML
+            listField.add(errOption, null);
+        }
+        else if (typeof(listField.options.add) != 'undefined') {
+            // DOM 0
+            listField.options.add(errOption, null);
+        }
+        else {
+            // DOM 0
+            listField.options[listField.length] = errOption;
+        }
+    }
+}
+
+jsUnitTestManager.prototype._handleTestException = function (excep) {
+    var problemMessage = this._currentTestFunctionNameWithTestPageName(false) + ' ';
+    var errOption;
+    if (typeof(excep.isJsUnitException) == 'undefined' || !excep.isJsUnitException) {
+        problemMessage += 'had an error';
+        this.errorCount++;
+    }
+    else {
+        problemMessage += 'failed';
+        this.failureCount++;
+    }
+    var listField = this.problemsListField;
+    this._addOption(listField,
+            this._problemDetailMessageFor(excep),
+            problemMessage);
+}
+
+jsUnitTestManager.prototype._problemDetailMessageFor = function (excep) {
+    var result = null;
+    if (typeof(excep.isJsUnitException) != 'undefined' && excep.isJsUnitException) {
+        result = '';
+        if (excep.comment != null)
+            result += ('"' + excep.comment + '"\n');
+
+        result += excep.jsUnitMessage;
+
+        if (excep.stackTrace)
+            result += '\n\nStack trace follows:\n' + excep.stackTrace;
+    }
+    else {
+        result = 'Error message is:\n"';
+        result +=
+        (typeof(excep.description) == 'undefined') ?
+        excep :
+        excep.description;
+        result += '"';
+        if (typeof(excep.stack) != 'undefined') // Mozilla only
+            result += '\n\nStack trace follows:\n' + excep.stack;
+    }
+    return result;
+}
+
+jsUnitTestManager.prototype._setTextOnLayer = function (layerName, str) {
+    try {
+        var content;
+        if (content = this.uiFrames[layerName].document.getElementById('content'))
+            content.innerHTML = str;
+        else
+            throw 'No content div found.';
+    }
+    catch (e) {
+        var html = '';
+        html += '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">';
+        html += '<html><head><link rel="stylesheet" type="text/css" href="css/jsUnitStyle.css"><\/head>';
+        html += '<body><div id="content">';
+        html += str;
+        html += '<\/div><\/body>';
+        html += '<\/html>';
+        this.uiFrames[layerName].document.write(html);
+        this.uiFrames[layerName].document.close();
+    }
+}
+
+jsUnitTestManager.prototype.setStatus = function (str) {
+    this._setTextOnLayer('mainStatus', '<b>Status:<\/b> ' + str);
+}
+
+jsUnitTestManager.prototype._setErrors = function (n) {
+    this._setTextOnLayer('mainCountsErrors', '<b>Errors: <\/b>' + n);
+}
+
+jsUnitTestManager.prototype._setFailures = function (n) {
+    this._setTextOnLayer('mainCountsFailures', '<b>Failures:<\/b> ' + n);
+}
+
+jsUnitTestManager.prototype._setTotal = function (n) {
+    this._setTextOnLayer('mainCountsRuns', '<b>Runs:<\/b> ' + n);
+}
+
+jsUnitTestManager.prototype._setProgressBarImage = function (imgName) {
+    this.progressBar.src = imgName;
+}
+
+jsUnitTestManager.prototype._setProgressBarWidth = function (w) {
+    this.progressBar.width = w;
+}
+
+jsUnitTestManager.prototype.updateProgressIndicators = function () {
+    this._setTotal(this.totalCount);
+    this._setErrors(this.errorCount);
+    this._setFailures(this.failureCount);
+    this._setProgressBarWidth(300 * this.calculateProgressBarProportion());
+
+    if (this.errorCount > 0 || this.failureCount > 0)
+        this._setProgressBarImage('../images/red.gif');
+    else
+        this._setProgressBarImage('../images/green.gif');
+}
+
+jsUnitTestManager.prototype.showMessageForSelectedProblemTest = function () {
+    var problemTestIndex = this.problemsListField.selectedIndex;
+    if (problemTestIndex != -1)
+        this.fatalError(this.problemsListField[problemTestIndex].value);
+}
+
+jsUnitTestManager.prototype.showMessagesForAllProblemTests = function () {
+    if (this.problemsListField.length == 0)
+        return;
+
+    try {
+        if (this._windowForAllProblemMessages && !this._windowForAllProblemMessages.closed)
+            this._windowForAllProblemMessages.close();
+    }
+    catch(e) {
+    }
+
+    this._windowForAllProblemMessages = window.open('', '', 'width=600, height=350,status=no,resizable=yes,scrollbars=yes');
+    var resDoc = this._windowForAllProblemMessages.document;
+    resDoc.write('<html><head><link rel="stylesheet" href="../css/jsUnitStyle.css"><title>Tests with problems - JsUnit<\/title><head><body>');
+    resDoc.write('<p class="jsUnitSubHeading">Tests with problems (' + this.problemsListField.length + ' total) - JsUnit<\/p>');
+    resDoc.write('<p class="jsUnitSubSubHeading"><i>Running on ' + navigator.userAgent + '</i></p>');
+    for (var i = 0; i < this.problemsListField.length; i++)
+    {
+        resDoc.write('<p class="jsUnitDefault">');
+        resDoc.write('<b>' + (i + 1) + '. ');
+        resDoc.write(this.problemsListField[i].text);
+        resDoc.write('<\/b><\/p><p><pre>');
+        resDoc.write(this._makeHTMLSafe(this.problemsListField[i].value));
+        resDoc.write('<\/pre><\/p>');
+    }
+
+    resDoc.write('<\/body><\/html>');
+    resDoc.close();
+}
+
+jsUnitTestManager.prototype._makeHTMLSafe = function (string) {
+    string = string.replace(/&/g, '&amp;');
+    string = string.replace(/</g, '&lt;');
+    string = string.replace(/>/g, '&gt;');
+    return string;
+}
+
+jsUnitTestManager.prototype._clearProblemsList = function () {
+    var listField = this.problemsListField;
+    var initialLength = listField.options.length;
+
+    for (var i = 0; i < initialLength; i++)
+        listField.remove(0);
+}
+
+jsUnitTestManager.prototype.initialize = function () {
+    this.setStatus('Initializing...');
+    this._setRunButtonEnabled(false);
+    this._clearProblemsList();
+    this.updateProgressIndicators();
+    this.setStatus('Done initializing');
+}
+
+jsUnitTestManager.prototype.finalize = function () {
+    this._setRunButtonEnabled(true);
+}
+
+jsUnitTestManager.prototype._setRunButtonEnabled = function (b) {
+    this.runButton.disabled = !b;
+}
+
+jsUnitTestManager.prototype.getTestFileName = function () {
+    var rawEnteredFileName = this.testFileName.value;
+    var result = rawEnteredFileName;
+
+    while (result.indexOf('\\') != -1)
+        result = result.replace('\\', '/');
+
+    return result;
+}
+
+jsUnitTestManager.prototype.getTestFunctionName = function () {
+    return this._testFunctionName;
+}
+
+jsUnitTestManager.prototype.resolveUserEnteredTestFileName = function (rawText) {
+    var userEnteredTestFileName = top.testManager.getTestFileName();
+
+    // only test for file:// since Opera uses a different format
+    if (userEnteredTestFileName.indexOf('http://') == 0 || userEnteredTestFileName.indexOf('https://') == 0 || userEnteredTestFileName.indexOf('file://') == 0)
+        return userEnteredTestFileName;
+
+    return getTestFileProtocol() + this.getTestFileName();
+}
+
+jsUnitTestManager.prototype.storeRestoredHTML = function () {
+    if (document.getElementById && top.testContainer.testFrame.document.getElementById(jsUnitTestManager.RESTORED_HTML_DIV_ID))
+        this._restoredHTML = top.testContainer.testFrame.document.getElementById(jsUnitTestManager.RESTORED_HTML_DIV_ID).innerHTML;
+}
+
+jsUnitTestManager.prototype.fatalError = function(aMessage) {
+    if (top.shouldSubmitResults())
+        this.setStatus(aMessage);
+    else
+        alert(aMessage);
+}
+
+jsUnitTestManager.prototype.userConfirm = function(aMessage) {
+    if (top.shouldSubmitResults())
+        return false;
+    else
+        return confirm(aMessage);
+}
+
+function getTestFileProtocol() {
+    return getDocumentProtocol();
+}
+
+function getDocumentProtocol() {
+    var protocol = top.document.location.protocol;
+
+    if (protocol == "file:")
+        return "file:///";
+
+    if (protocol == "http:")
+        return "http://";
+
+    if (protocol == 'https:')
+        return 'https://';
+
+    if (protocol == "chrome:")
+        return "chrome://";
+
+    return null;
+}
+
+function browserSupportsReadingFullPathFromFileField() {
+    return !isOpera() && !isIE7();
+}
+
+function isOpera() {
+    return navigator.userAgent.toLowerCase().indexOf("opera") != -1;
+}
+
+function isIE7() {
+    return navigator.userAgent.toLowerCase().indexOf("msie 7") != -1;
+}
+
+function isBeingRunOverHTTP() {
+    return getDocumentProtocol() == "http://";
+}
+
+function getWebserver() {
+    if (isBeingRunOverHTTP()) {
+        var myUrl = location.href;
+        var myUrlWithProtocolStripped = myUrl.substring(myUrl.indexOf("/") + 2);
+        return myUrlWithProtocolStripped.substring(0, myUrlWithProtocolStripped.indexOf("/"));
+    }
+    return null;
+}
+
+// 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--;
+    }
+}
+
+if (xbDEBUG.on) {
+    xbDebugTraceObject('window', 'jsUnitTestManager');
+    xbDebugTraceFunction('window', 'getTestFileProtocol');
+    xbDebugTraceFunction('window', 'getDocumentProtocol');
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/jsUnitTestSuite.js
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/jsUnitTestSuite.js	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/jsUnitTestSuite.js	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,44 @@
+function jsUnitTestSuite() {
+    this.isjsUnitTestSuite = true;
+    this.testPages = Array();
+    this.pageIndex = 0;
+}
+
+jsUnitTestSuite.prototype.addTestPage = function (pageName)
+{
+    this.testPages[this.testPages.length] = pageName;
+}
+
+jsUnitTestSuite.prototype.addTestSuite = function (suite)
+{
+    for (var i = 0; i < suite.testPages.length; i++)
+        this.addTestPage(suite.testPages[i]);
+}
+
+jsUnitTestSuite.prototype.containsTestPages = function ()
+{
+    return this.testPages.length > 0;
+}
+
+jsUnitTestSuite.prototype.nextPage = function ()
+{
+    return this.testPages[this.pageIndex++];
+}
+
+jsUnitTestSuite.prototype.hasMorePages = function ()
+{
+    return this.pageIndex < this.testPages.length;
+}
+
+jsUnitTestSuite.prototype.clone = function ()
+{
+    var clone = new jsUnitTestSuite();
+    clone.testPages = this.testPages;
+    return clone;
+}
+
+if (xbDEBUG.on)
+{
+    xbDebugTraceObject('window', 'jsUnitTestSuite');
+}
+

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/jsUnitTracer.js
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/jsUnitTracer.js	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/jsUnitTracer.js	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,102 @@
+var TRACE_LEVEL_NONE = new JsUnitTraceLevel(0, null);
+var TRACE_LEVEL_WARNING = new JsUnitTraceLevel(1, "#FF0000");
+var TRACE_LEVEL_INFO = new JsUnitTraceLevel(2, "#009966");
+var TRACE_LEVEL_DEBUG = new JsUnitTraceLevel(3, "#0000FF");
+
+function JsUnitTracer(testManager) {
+    this._testManager = testManager;
+    this._traceWindow = null;
+    this.popupWindowsBlocked = false;
+}
+
+JsUnitTracer.prototype.initialize = function() {
+    if (this._traceWindow != null && top.testManager.closeTraceWindowOnNewRun.checked)
+        this._traceWindow.close();
+    this._traceWindow = null;
+}
+
+JsUnitTracer.prototype.finalize = function() {
+    if (this._traceWindow != null) {
+        this._traceWindow.document.write('<\/body>\n<\/html>');
+        this._traceWindow.document.close();
+    }
+}
+
+JsUnitTracer.prototype.warn = function() {
+    this._trace(arguments[0], arguments[1], TRACE_LEVEL_WARNING);
+}
+
+JsUnitTracer.prototype.inform = function() {
+    this._trace(arguments[0], arguments[1], TRACE_LEVEL_INFO);
+}
+
+JsUnitTracer.prototype.debug = function() {
+    this._trace(arguments[0], arguments[1], TRACE_LEVEL_DEBUG);
+}
+
+JsUnitTracer.prototype._trace = function(message, value, traceLevel) {
+    if (!top.shouldSubmitResults() && this._getChosenTraceLevel().matches(traceLevel)) {
+        var traceString = message;
+        if (value)
+            traceString += ': ' + value;
+        var prefix = this._testManager.getTestFileName() + ":" +
+                     this._testManager.getTestFunctionName() + " - ";
+        this._writeToTraceWindow(prefix, traceString, traceLevel);
+    }
+}
+
+JsUnitTracer.prototype._getChosenTraceLevel = function() {
+    var levelNumber = eval(top.testManager.traceLevel.value);
+    return traceLevelByLevelNumber(levelNumber);
+}
+
+JsUnitTracer.prototype._writeToTraceWindow = function(prefix, traceString, traceLevel) {
+    var htmlToAppend = '<p class="jsUnitDefault">' + prefix + '<font color="' + traceLevel.getColor() + '">' + traceString + '</font><\/p>\n';
+    this._getTraceWindow().document.write(htmlToAppend);
+}
+
+JsUnitTracer.prototype._getTraceWindow = function() {
+    if (this._traceWindow == null && !top.shouldSubmitResults() && !this.popupWindowsBlocked) {
+        this._traceWindow = window.open('', '', 'width=600, height=350,status=no,resizable=yes,scrollbars=yes');
+        if (!this._traceWindow)
+            this.popupWindowsBlocked = true;
+        else {
+            var resDoc = this._traceWindow.document;
+            resDoc.write('<html>\n<head>\n<link rel="stylesheet" href="css/jsUnitStyle.css">\n<title>Tracing - JsUnit<\/title>\n<head>\n<body>');
+            resDoc.write('<h2>Tracing - JsUnit<\/h2>\n');
+            resDoc.write('<p class="jsUnitDefault"><i>(Traces are color coded: ');
+            resDoc.write('<font color="' + TRACE_LEVEL_WARNING.getColor() + '">Warning</font> - ');
+            resDoc.write('<font color="' + TRACE_LEVEL_INFO.getColor() + '">Information</font> - ');
+            resDoc.write('<font color="' + TRACE_LEVEL_DEBUG.getColor() + '">Debug</font>');
+            resDoc.write(')</i></p>');
+        }
+    }
+    return this._traceWindow;
+}
+
+if (xbDEBUG.on) {
+    xbDebugTraceObject('window', 'JsUnitTracer');
+}
+
+function JsUnitTraceLevel(levelNumber, color) {
+    this._levelNumber = levelNumber;
+    this._color = color;
+}
+
+JsUnitTraceLevel.prototype.matches = function(anotherTraceLevel) {
+    return this._levelNumber >= anotherTraceLevel._levelNumber;
+}
+
+JsUnitTraceLevel.prototype.getColor = function() {
+    return this._color;
+}
+
+function traceLevelByLevelNumber(levelNumber) {
+    switch (levelNumber) {
+        case 0: return TRACE_LEVEL_NONE;
+        case 1: return TRACE_LEVEL_WARNING;
+        case 2: return TRACE_LEVEL_INFO;
+        case 3: return TRACE_LEVEL_DEBUG;
+    }
+    return null;
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/jsUnitVersionCheck.js
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/jsUnitVersionCheck.js	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/jsUnitVersionCheck.js	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,59 @@
+var versionRequest;
+
+function isOutOfDate(newVersionNumber) {
+    return JSUNIT_VERSION < newVersionNumber;
+}
+
+function sendRequestForLatestVersion(url) {
+    versionRequest = createXmlHttpRequest();
+    if (versionRequest) {
+        versionRequest.onreadystatechange = requestStateChanged;
+        versionRequest.open("GET", url, true);
+        versionRequest.send(null);
+    }
+}
+
+function createXmlHttpRequest() {
+    if (window.XMLHttpRequest)
+        return new XMLHttpRequest();
+    else if (window.ActiveXObject)
+        return new ActiveXObject("Microsoft.XMLHTTP");
+}
+
+function requestStateChanged() {
+    if (versionRequest && versionRequest.readyState == 4) {
+        if (versionRequest.status == 200) {
+            var latestVersion = versionRequest.responseText;
+            if (isOutOfDate(latestVersion))
+                versionNotLatest(latestVersion);
+            else
+                versionLatest();
+        } else
+            versionCheckError();
+    }
+}
+
+function checkForLatestVersion(url) {
+    setLatestVersionDivHTML("Checking for newer version...");
+    try {
+        sendRequestForLatestVersion(url);
+    } catch (e) {
+        setLatestVersionDivHTML("An error occurred while checking for a newer version: " + e.message);
+    }
+}
+
+function versionNotLatest(latestVersion) {
+    setLatestVersionDivHTML('<font color="red">A newer version of JsUnit, version ' + latestVersion + ', is available.</font>');
+}
+
+function versionLatest() {
+    setLatestVersionDivHTML("You are running the latest version of JsUnit.");
+}
+
+function setLatestVersionDivHTML(string) {
+    document.getElementById("versionCheckDiv").innerHTML = string;
+}
+
+function versionCheckError() {
+    setLatestVersionDivHTML("An error occurred while checking for a newer version.");
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-counts-errors.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-counts-errors.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-counts-errors.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title></title>
+    <link rel="stylesheet" type="text/css" href="../css/jsUnitStyle.css">
+</head>
+
+<body>
+<div id="content"><b>Errors:</b> 0</div>
+</body>
+</html>
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-counts-failures.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-counts-failures.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-counts-failures.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title></title>
+    <link rel="stylesheet" type="text/css" href="../css/jsUnitStyle.css">
+</head>
+
+<body>
+<div id="content"><b>Failures:</b> 0</div>
+
+</body>
+</html>

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-counts-runs.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-counts-runs.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-counts-runs.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title></title>
+    <link rel="stylesheet" type="text/css" href="../css/jsUnitStyle.css">
+</head>
+
+<body>
+<div id="content"><b>Runs:</b> 0</div>
+
+</body>
+</html>

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-counts.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-counts.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-counts.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title></title>
+</head>
+
+<frameset cols="200,190,*" border="0">
+    <frame name="mainCountsRuns" src="main-counts-runs.html" scrolling="no" frameborder="0">
+    <frame name="mainCountsErrors" src="main-counts-errors.html" scrolling="no" frameborder="0">
+    <frame name="mainCountsFailures" src="main-counts-failures.html" scrolling="no" frameborder="0">
+
+    <noframes>
+        <body>
+        <p>jsUnit uses frames in order to remove dependencies upon a browser's implementation of document.getElementById
+            and HTMLElement.innerHTML.</p>
+        </body>
+    </noframes>
+</frameset>
+</html>
+

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-data.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-data.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-data.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,178 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+        "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>JsUnit main-data.html</title>
+    <link rel="stylesheet" type="text/css" href="../css/jsUnitStyle.css">
+    <script language="JavaScript" type="text/javascript" src="jsUnitCore.js"></script>
+    <script language="JavaScript" type="text/javascript" src="jsUnitVersionCheck.js"></script>
+    <script language="JavaScript" type="text/javascript">
+
+        function pageLoaded() {
+            giveFocusToTestFileNameField();
+        }
+
+        function giveFocusToTestFileNameField() {
+            if (document.testRunnerForm.testFileName.type != "hidden")
+                document.testRunnerForm.testFileName.focus();
+        }
+
+        function kickOffTests() {
+            //
+            //    Check if Init was called by onload handler
+            //
+            if (typeof(top.testManager) == 'undefined') {
+                top.init();
+            }
+
+            if (isBlank(top.testManager.getTestFileName())) {
+                top.testManager.fatalError('No Test Page specified.');
+                return;
+            }
+
+            top.testManager.setup();
+
+            top.testManager._currentSuite().addTestPage(top.testManager.resolveUserEnteredTestFileName());
+            top.tracer.initialize();
+
+            var traceLevel = document.forms.testRunnerForm.traceLevel;
+            if (traceLevel.value != '0')
+            {
+                var traceWindow = top.tracer._getTraceWindow();
+                if (traceWindow) {
+                    traceWindow.focus();
+                }
+                else {
+                    top.testManager.fatalError('Tracing requires popup windows, and popups are blocked in your browser.\n\nPlease enable popups if you wish to use tracing.');
+                }
+            }
+
+            top.testManager.start();
+        }
+
+    </script>
+</head>
+
+<body onload="pageLoaded();">
+<table width="100%" cellpadding="0" cellspacing="0" border="0" summary="jsUnit Information" bgcolor="#DDDDDD">
+    <tr>
+        <td width="1"><a href="http://www.jsunit.net" target="_blank"><img src="../images/logo_jsunit.gif" alt="JsUnit" border="0"/></a></td>
+        <td width="50">&nbsp;</td>
+        <th nowrap align="left">
+            <h4>JsUnit <script language="javascript">document.write(JSUNIT_VERSION);</script> TestRunner</h4>
+            <font size="-2"><i>Running on <script language="javascript" type="text/javascript">document.write(navigator.userAgent);</script>
+            </i></font>
+        </th>
+
+        <td nowrap align="right" valign="middle">
+            <font size="-2">
+                <b><a href="http://www.jsunit.net/" target="_blank">www.jsunit.net</a></b>&nbsp;&nbsp;<br>
+            </font>
+            <a href="http://www.pivotalsf.com/" target="top">
+                <img border="0" src="../images/powerby-transparent.gif" alt="Powered By Pivotal">
+            </a>
+        </td>
+    </tr>
+</table>
+
+<form name="testRunnerForm" action="">
+    <script type="text/javascript" language="javascript">
+        if (!jsUnitGetParm('testpage')) {
+            document.write("<p>Enter the filename of the Test Page to be run:</p>");
+        } else {
+            document.write("<br>");
+        };
+    </script>
+
+    <table cellpadding="0" cellspacing="0" border="0" summary="Form for entering test case location">
+        <tr>
+            <td align="center" valign="middle">
+                <script language="JavaScript" type="text/javascript">
+                    document.write(top.getDocumentProtocol());
+                </script>
+            </td>
+
+            <td nowrap align="center" valign="bottom">
+                &nbsp;
+                <script language="JavaScript" type="text/javascript">
+                    var specifiedTestPage = jsUnitGetParm('testpage');
+                    if (specifiedTestPage) {
+                        var html = '<input type="hidden" name="testFileName" value="';
+                        var valueString = '';
+                        if ((top.getDocumentProtocol() == 'http://' || top.getDocumentProtocol() == 'https://') && jsUnitGetParm('testpage').indexOf('/') == 0)
+                            valueString += top.location.host;
+                        valueString += specifiedTestPage;
+                        var testParms = top.jsUnitConstructTestParms();
+                        if (testParms != '') {
+                            valueString += '?';
+                            valueString += testParms;
+                        }
+                        html += valueString;
+                        html += '">';
+                        html += valueString;
+                        document.write(html);
+                    } else {
+                        if (top.getDocumentProtocol() == 'file:///' && top.browserSupportsReadingFullPathFromFileField())
+                            document.write('<input type="file" name="testFileName" size="60">');
+                        else
+                            document.write('<input type="text" name="testFileName" size="60">');
+                    }
+                </script>
+                <input type="button" name="runButton" value="Run" onclick="kickOffTests()">
+            </td>
+        </tr>
+    </table>
+    <br>
+    <hr>
+
+    <table cellpadding="0" cellspacing="0" border="0" summary="Choose Trace Level">
+        <tr>
+            <td nowrap>Trace level:</td>
+
+            <td><select name="traceLevel">
+                <option value="0" selected>
+                    no tracing
+                </option>
+
+                <option value="1">
+                    warning (lowest)
+                </option>
+
+                <option value="2">
+                    info
+                </option>
+
+                <option value="3">
+                    debug (highest)
+                </option>
+            </select></td>
+
+            <td>&nbsp;&nbsp;&nbsp;</td>
+
+            <td><input type="checkbox" name="closeTraceWindowOnNewRun" checked></td>
+            <td nowrap>Close old trace window on new run</td>
+
+            <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
+
+            <td nowrap>Page load timeout:</td>
+            <td>&nbsp;
+                <script language="javascript" type="text/javascript">
+                    document.write('<input type="text" size="2" name="timeout" value="' + top.jsUnitTestManager.TESTPAGE_WAIT_SEC + '">');
+                </script>
+            </td>
+
+            <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
+
+            <td nowrap>Setup page timeout:</td>
+            <td>&nbsp;
+                <script language="javascript" type="text/javascript">
+                    document.write('<input type="text" size="2" name="setUpPageTimeout" value="' + top.jsUnitTestManager.SETUPPAGE_TIMEOUT + '">');
+                </script>
+            </td>
+        </tr>
+    </table>
+    <hr>
+</form>
+</body>
+</html>

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-errors.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-errors.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-errors.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>JsUnit main-errors.html</title>
+    <link rel="stylesheet" type="text/css" href="../css/jsUnitStyle.css">
+</head>
+
+<body>
+<hr>
+
+<form name="testRunnerForm" action="javascript:top.testManager.showMessageForSelectedProblemTest()">
+    <p>Errors and failures:&nbsp;</p>
+    <select size="5" ondblclick="top.testManager.showMessageForSelectedProblemTest()" name="problemsList">
+        <option>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option>
+    </select>
+    <br>
+    <input type="button" value="Show selected" onclick="top.testManager.showMessageForSelectedProblemTest()">
+    &nbsp;&nbsp;&nbsp;
+    <input type="button" value="Show all" onclick="top.testManager.showMessagesForAllProblemTests()">
+</form>
+</body>
+</html>

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-frame.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-frame.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-frame.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
+<html>
+<head>
+    <title>jsUnit Main Frame</title>
+</head>
+<frameset rows="230,30,30,30,0,*" border="0">>
+    <frame name="mainData" src="main-data.html" scrolling="no" frameborder="0">
+    <frame name="mainStatus" src="main-status.html" scrolling="no" frameborder="0">
+    <frame name="mainProgress" src="main-progress.html" scrolling="no" frameborder="0">
+    <frame name="mainCounts" src="main-counts.html" scrolling="no" frameborder="0">
+    <frame name="mainResults" src="main-results.html" scrolling="no" frameborder="0">
+    <frame name="mainErrors" src="main-errors.html" scrolling="no" frameborder="0">
+    <noframes>
+        <body>
+        <p>Sorry, JsUnit requires frames.</p>
+        </body>
+    </noframes>
+</frameset>
+</html>

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-loader.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-loader.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-loader.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>jsUnit External Data Document loader</title>
+    <script language="JavaScript" type="text/javascript">
+
+        var loadStatus;
+        var callback = function () {
+        };
+
+        function buffer() {
+            return window.frames.documentBuffer;
+        }
+
+        function load(uri) {
+            loadStatus = 'loading';
+            buffer().document.location.href = uri;
+        }
+
+        function loadComplete() {
+            top.xbDEBUG.dump('main-loader.html:loadComplete(): loadStatus = ' + loadStatus + ' href=' + buffer().document.location.href);
+            if (loadStatus == 'loading') {
+                loadStatus = 'complete';
+                callback();
+                callback = function () {
+                };
+            }
+        }
+
+        if (top.xbDEBUG.on) {
+            var scopeName = 'main_loader_' + (new Date()).getTime();
+            top[scopeName] = window;
+            top.xbDebugTraceFunction(scopeName, 'buffer');
+            top.xbDebugTraceFunction(scopeName, 'load');
+            top.xbDebugTraceFunction(scopeName, 'loadComplete');
+        }
+
+    </script>
+</head>
+
+<body>
+<iframe name="documentBuffer" onload="loadComplete()"></iframe>
+</body>
+</html>

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-progress.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-progress.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-progress.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>JsUnit main-progress.html</title>
+    <link rel="stylesheet" type="text/css" href="../css/jsUnitStyle.css">
+</head>
+
+<body>
+<table width="375" cellpadding="0" cellspacing="0" border="0" summary="Test progress indicator">
+    <tr>
+        <td width="65" valign="top"><b>Progress:</b></td>
+
+        <td width="300" height="14" valign="middle">
+            <table width="300" cellpadding="0" cellspacing="0" border="1" summary="Progress image">
+                <tr>
+                    <td width="300" height="14" valign="top"><img name="progress" height="14" width="0"
+                                                                  alt="progress image" src="../images/green.gif"></td>
+                </tr>
+            </table>
+        </td>
+    </tr>
+</table>
+</body>
+</html>

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-results.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-results.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-results.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,67 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>JsUnit main-results.html</title>
+    <link rel="stylesheet" type="text/css" href="../css/jsUnitStyle.css">
+</head>
+
+<body>
+<script language="javascript" type="text/javascript">
+    var DEFAULT_SUBMIT_WEBSERVER = "localhost:8080";
+
+    function submitUrlFromSpecifiedUrl() {
+        var result = "";
+        var specifiedUrl = top.getSpecifiedResultUrl();
+        if (specifiedUrl.indexOf("http://") != 0)
+            result = "http://";
+        result += specifiedUrl;
+        return result;
+    }
+
+    function submitUrlFromTestRunnerLocation() {
+        var result = "http://";
+        var webserver = top.getWebserver();
+        if (webserver == null) // running over file:///
+            webserver = DEFAULT_SUBMIT_WEBSERVER;
+        result += webserver;
+        result += "/jsunit/acceptor";
+        return result;
+    }
+
+    var submitUrl = "";
+    if (top.wasResultUrlSpecified()) {
+        submitUrl = submitUrlFromSpecifiedUrl();
+    } else {
+        submitUrl = submitUrlFromTestRunnerLocation();
+    }
+
+    var formString = "<form name=\"resultsForm\" action=\"" + submitUrl + "\" method=\"post\" target=\"_top\">";
+    document.write(formString);
+</script>
+<input type="hidden" name="id">
+<input type="hidden" name="userAgent">
+<input type="hidden" name="jsUnitVersion">
+<input type="hidden" name="time">
+<input type="hidden" name="url">
+<input type="hidden" name="cacheBuster">
+<select size="5" name="testCases" multiple></select>
+</form>
+<script language="javascript" type="text/javascript">
+    function populateHeaderFields(id, userAgent, jsUnitVersion, baseURL) {
+        document.resultsForm.id.value = id;
+        document.resultsForm.userAgent.value = userAgent;
+        document.resultsForm.jsUnitVersion.value = jsUnitVersion;
+        document.resultsForm.url.value = baseURL;
+        document.resultsForm.cacheBuster.value = new Date().getTime();
+    }
+    function submitResults() {
+        var testCasesField = document.resultsForm.testCases;
+        for (var i = 0; i < testCasesField.length; i++) {
+            testCasesField[i].selected = true;
+        }
+        document.resultsForm.submit();
+    }
+</script>
+</body>
+</html>

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-status.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-status.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/main-status.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>JsUnit main-status.html</title>
+    <link rel="stylesheet" type="text/css" href="../css/jsUnitStyle.css">
+</head>
+
+<body>
+<div id="content"><b>Status:</b> (Idle)</div>
+
+</body>
+</html>

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/testContainer.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/testContainer.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/testContainer.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,16 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>JsUnit Test Container</title>
+</head>
+<frameset rows="0, *" border="0">
+    <frame name="testContainerController" src="testContainerController.html">
+    <frame name="testFrame" src="emptyPage.html">
+    <noframes>
+        <body>
+        <p>Sorry, JsUnit requires frames.</p>
+        </body>
+    </noframes>
+</frameset>
+</html>

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/testContainerController.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/testContainerController.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/testContainerController.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,77 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>JsUnit Test Container Controller</title>
+    <script language="javascript" type="text/javascript">
+        var containerReady = false;
+
+        function init() {
+            containerReady = true;
+        }
+
+        function isPageLoaded() {
+            if (!containerReady)
+                return false;
+
+            var isTestPageLoaded = false;
+
+            try {
+                // attempt to access the var isTestPageLoaded in the testFrame
+                if (typeof(top.testManager.containerTestFrame.isTestPageLoaded) != 'undefined') {
+                    isTestPageLoaded = top.testManager.containerTestFrame.isTestPageLoaded;
+                }
+
+                // ok, if the above did not throw an exception, then the
+                // variable is defined. If the onload has not fired in the
+                // testFrame then isTestPageLoaded is still false. Otherwise
+                // the testFrame has set it to true
+            }
+            catch (e) {
+                // an error occured while attempting to access the isTestPageLoaded
+                // in the testFrame, therefore the testFrame has not loaded yet
+                isTestPageLoaded = false;
+            }
+            return isTestPageLoaded;
+        }
+
+        function isContainerReady() {
+            return containerReady;
+        }
+
+        function setNotReady() {
+            try {
+                // attempt to set the isTestPageLoaded variable
+                // in the test frame to false.
+                top.testManager.containerTestFrame.isTestPageLoaded = false;
+            }
+            catch (e) {
+                // testFrame.isTestPageLoaded not available... ignore
+            }
+        }
+        function setTestPage(testPageURI) {
+            setNotReady();
+            top.jsUnitParseParms(testPageURI);
+            testPageURI = appendCacheBusterParameterTo(testPageURI);
+            try {
+                top.testManager.containerTestFrame.location.href = testPageURI;
+            } catch (e) {
+            }
+        }
+
+        function appendCacheBusterParameterTo(testPageURI) {
+            if (testPageURI.indexOf("?") == -1)
+                testPageURI += "?";
+            else
+                testPageURI += "&";
+            testPageURI += "cacheBuster=";
+            testPageURI += new Date().getTime();
+            return testPageURI;
+        }
+    </script>
+</head>
+
+<body onload="init()">
+Test Container Controller
+</body>
+</html>
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/xbDebug.js
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/xbDebug.js	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/app/xbDebug.js	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,306 @@
+// xbDebug.js revision: 0.003 2002-02-26
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Licensed under Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ * Full Terms at /xbProjects-srce/license/mpl-tri-license.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Netscape code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2001
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Bob Clary <bclary at netscape.com>
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ChangeLog:
+
+2002-02-25: bclary - modified xbDebugTraceOject to make sure 
+            that original versions of wrapped functions were not
+            rewrapped. This had caused an infinite loop in IE.
+
+2002-02-07: bclary - modified xbDebug.prototype.close to not null
+            the debug window reference. This can cause problems with
+	          Internet Explorer if the page is refreshed. These issues will
+	          be addressed at a later date.
+*/
+
+function xbDebug()
+{
+    this.on = false;
+    this.stack = new Array();
+    this.debugwindow = null;
+    this.execprofile = new Object();
+}
+
+xbDebug.prototype.push = function ()
+{
+    this.stack[this.stack.length] = this.on;
+    this.on = true;
+}
+
+xbDebug.prototype.pop = function ()
+{
+    this.on = this.stack[this.stack.length - 1];
+    --this.stack.length;
+}
+
+xbDebug.prototype.open = function ()
+{
+    if (this.debugwindow && !this.debugwindow.closed)
+        this.close();
+
+    this.debugwindow = window.open('about:blank', 'DEBUGWINDOW', 'height=400,width=600,resizable=yes,scrollbars=yes');
+
+    this.debugwindow.title = 'xbDebug Window';
+    this.debugwindow.document.write('<html><head><title>xbDebug Window</title></head><body><h3>Javascript Debug Window</h3></body></html>');
+    this.debugwindow.focus();
+}
+
+xbDebug.prototype.close = function ()
+{
+    if (!this.debugwindow)
+        return;
+
+    if (!this.debugwindow.closed)
+        this.debugwindow.close();
+
+    // bc 2002-02-07, other windows may still hold a reference to this: this.debugwindow = null;
+}
+
+xbDebug.prototype.dump = function (msg)
+{
+    if (!this.on)
+        return;
+
+    if (!this.debugwindow || this.debugwindow.closed)
+        this.open();
+
+    this.debugwindow.document.write(msg + '<br>');
+
+    return;
+}
+
+var xbDEBUG = new xbDebug();
+
+window.onunload = function () {
+    xbDEBUG.close();
+}
+
+function xbDebugGetFunctionName(funcref)
+{
+
+    if (!funcref)
+    {
+        return '';
+    }
+
+    if (funcref.name)
+        return funcref.name;
+
+    var name = funcref + '';
+    name = name.substring(name.indexOf(' ') + 1, name.indexOf('('));
+    funcref.name = name;
+
+    if (!name) alert('name not defined');
+    return name;
+}
+
+// emulate functionref.apply for IE mac and IE win < 5.5
+function xbDebugApplyFunction(funcname, funcref, thisref, argumentsref)
+{
+    var rv;
+
+    if (!funcref)
+    {
+        alert('xbDebugApplyFunction: funcref is null');
+    }
+
+    if (typeof(funcref.apply) != 'undefined')
+        return funcref.apply(thisref, argumentsref);
+
+    var applyexpr = 'thisref.xbDebug_orig_' + funcname + '(';
+    var i;
+
+    for (i = 0; i < argumentsref.length; i++)
+    {
+        applyexpr += 'argumentsref[' + i + '],';
+    }
+
+    if (argumentsref.length > 0)
+    {
+        applyexpr = applyexpr.substring(0, applyexpr.length - 1);
+    }
+
+    applyexpr += ')';
+
+    return eval(applyexpr);
+}
+
+function xbDebugCreateFunctionWrapper(scopename, funcname, precall, postcall)
+{
+    var wrappedfunc;
+    var scopeobject = eval(scopename);
+    var funcref = scopeobject[funcname];
+
+    scopeobject['xbDebug_orig_' + funcname] = funcref;
+
+    wrappedfunc = function ()
+    {
+        var rv;
+
+        precall(scopename, funcname, arguments);
+        rv = xbDebugApplyFunction(funcname, funcref, scopeobject, arguments);
+        postcall(scopename, funcname, arguments, rv);
+        return rv;
+    };
+
+    if (typeof(funcref.constructor) != 'undefined')
+        wrappedfunc.constructor = funcref.constuctor;
+
+    if (typeof(funcref.prototype) != 'undefined')
+        wrappedfunc.prototype = funcref.prototype;
+
+    scopeobject[funcname] = wrappedfunc;
+}
+
+function xbDebugCreateMethodWrapper(contextname, classname, methodname, precall, postcall)
+{
+    var context = eval(contextname);
+    var methodref = context[classname].prototype[methodname];
+
+    context[classname].prototype['xbDebug_orig_' + methodname] = methodref;
+
+    var wrappedmethod = function ()
+    {
+        var rv;
+        // eval 'this' at method run time to pick up reference to the object's instance
+        var thisref = eval('this');
+        // eval 'arguments' at method run time to pick up method's arguments
+        var argsref = arguments;
+
+        precall(contextname + '.' + classname, methodname, argsref);
+        rv = xbDebugApplyFunction(methodname, methodref, thisref, argsref);
+        postcall(contextname + '.' + classname, methodname, argsref, rv);
+        return rv;
+    };
+
+    return wrappedmethod;
+}
+
+function xbDebugPersistToString(obj)
+{
+    var s = '';
+    var p;
+
+    if (obj == null)
+        return 'null';
+
+    switch (typeof(obj))
+            {
+        case 'number':
+            return obj;
+        case 'string':
+            return '"' + obj + '"';
+        case 'undefined':
+            return 'undefined';
+        case 'boolean':
+            return obj + '';
+    }
+
+    if (obj.constructor)
+        return '[' + xbDebugGetFunctionName(obj.constructor) + ']';
+
+    return null;
+}
+
+function xbDebugTraceBefore(scopename, funcname, funcarguments)
+{
+    var i;
+    var s = '';
+    var execprofile = xbDEBUG.execprofile[scopename + '.' + funcname];
+    if (!execprofile)
+        execprofile = xbDEBUG.execprofile[scopename + '.' + funcname] = { started: 0, time: 0, count: 0 };
+
+    for (i = 0; i < funcarguments.length; i++)
+    {
+        s += xbDebugPersistToString(funcarguments[i]);
+        if (i < funcarguments.length - 1)
+            s += ', ';
+    }
+
+    xbDEBUG.dump('enter ' + scopename + '.' + funcname + '(' + s + ')');
+    execprofile.started = (new Date()).getTime();
+}
+
+function xbDebugTraceAfter(scopename, funcname, funcarguments, rv)
+{
+    var i;
+    var s = '';
+    var execprofile = xbDEBUG.execprofile[scopename + '.' + funcname];
+    if (!execprofile)
+        xbDEBUG.dump('xbDebugTraceAfter: execprofile not created for ' + scopename + '.' + funcname);
+    else if (execprofile.started == 0)
+        xbDEBUG.dump('xbDebugTraceAfter: execprofile.started == 0 for ' + scopename + '.' + funcname);
+    else
+    {
+        execprofile.time += (new Date()).getTime() - execprofile.started;
+        execprofile.count++;
+        execprofile.started = 0;
+    }
+
+    for (i = 0; i < funcarguments.length; i++)
+    {
+        s += xbDebugPersistToString(funcarguments[i]);
+        if (i < funcarguments.length - 1)
+            s += ', ';
+    }
+
+    xbDEBUG.dump('exit  ' + scopename + '.' + funcname + '(' + s + ')==' + xbDebugPersistToString(rv));
+}
+
+function xbDebugTraceFunction(scopename, funcname)
+{
+    xbDebugCreateFunctionWrapper(scopename, funcname, xbDebugTraceBefore, xbDebugTraceAfter);
+}
+
+function xbDebugTraceObject(contextname, classname)
+{
+    var classref = eval(contextname + '.' + classname);
+    var p;
+    var sp;
+
+    if (!classref || !classref.prototype)
+        return;
+
+    for (p in classref.prototype)
+    {
+        sp = p + '';
+        if (typeof(classref.prototype[sp]) == 'function' && (sp).indexOf('xbDebug_orig') == -1)
+        {
+            classref.prototype[sp] = xbDebugCreateMethodWrapper(contextname, classname, sp, xbDebugTraceBefore, xbDebugTraceAfter);
+        }
+    }
+}
+
+function xbDebugDumpProfile()
+{
+    var p;
+    var execprofile;
+    var avg;
+
+    for (p in xbDEBUG.execprofile)
+    {
+        execprofile = xbDEBUG.execprofile[p];
+        avg = Math.round(100 * execprofile.time / execprofile.count) / 100;
+        xbDEBUG.dump('Execution profile ' + p + ' called ' + execprofile.count + ' times. Total time=' + execprofile.time + 'ms. Avg Time=' + avg + 'ms.');
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/readme.txt
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/readme.txt	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/readme.txt	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,3 @@
+This directory contains shell scripts (*.sh) and AppleScripts (*.scpt) to start and stop browsers.
+
+The shell scripts invoke the AppleScripts, so use the shell scripts.
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/start-firefox.scpt
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/start-firefox.scpt
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/start-firefox.sh
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/start-firefox.sh	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/start-firefox.sh	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# Starts Firefox. Use this instead of calling the AppleScripts directly.
+
+osascript bin/mac/stop-firefox.scpt
+osascript bin/mac/start-firefox.scpt $1
+

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/start-safari.scpt
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/start-safari.scpt
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/start-safari.sh
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/start-safari.sh	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/start-safari.sh	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# Starts Safari. Use this instead of calling the AppleScripts directly.
+
+osascript bin/mac/stop-safari.scpt
+osascript bin/mac/start-safari.scpt $1
+

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/stop-firefox.scpt
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/stop-firefox.scpt
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/stop-firefox.sh
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/stop-firefox.sh	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/stop-firefox.sh	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# Stops Firefox. Use this instead of calling the AppleScripts directly.
+
+osascript bin/mac/stop-firefox.scpt
+

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/stop-safari.scpt
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/stop-safari.scpt
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/stop-safari.sh
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/stop-safari.sh	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/mac/stop-safari.sh	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# Stops Safari. Use this instead of calling the AppleScripts directly.
+
+osascript bin/mac/stop-safari.scpt
+

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/unix/start-firefox.sh
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/unix/start-firefox.sh	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/unix/start-firefox.sh	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,3 @@
+#!/bin/sh
+killall -9 -w firefox-bin
+firefox $1 &

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/unix/stop-firefox.sh
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/unix/stop-firefox.sh	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/bin/unix/stop-firefox.sh	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,2 @@
+#!/bin/sh
+killall -9 -w firefox-bin

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/build.xml
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/build.xml	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/build.xml	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,271 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<project name="JsUnit" default="create_distribution" basedir=".">
+
+    <!--
+     The following are the properties used to configure the JsUnit server.  You need to provide values for the mandatory properties.
+     See the documentation at http://www.jsunit.net for more information.
+     -->
+
+    <property
+            name="browserFileNames"
+            value=""
+            description="browserFileNames is the list of browsers in which to run tests when StandaloneTest is invoked on this machine. For a JsUnit Server, this is a mandatory property. For example: 'c:\program files\internet explorer\iexplore.exe,c:\program files\netscape\netscape7.1\netscp.exe'"
+            />
+
+    <property
+            id="closeBrowsersAfterTestRuns"
+            name="closeBrowsersAfterTestRuns"
+            value=""
+            description="closeBrowsersAfterTestRuns determines whether to attempt to close browsers after test runs. This is not a mandatory property. The default is true. For example: 'true'"
+            />
+
+    <property
+            id="description"
+            name="description"
+            value=""
+            description="description is a human-readable description of a standard or farm server. This is not a mandatory property. The default is blank. For example: 'This is our Mac - it's only running Safari right now'"
+            />
+
+    <property
+            id="ignoreUnresponsiveRemoteMachines"
+            name="ignoreUnresponsiveRemoteMachines"
+            value=""
+            description="ignoreUnresponsiveRemoteMachines is a property used only by the JsUnit Farm Server and the distributed_test target. Its value is whether to ignore a remove machine that does not respond.  If true, test runs will be green even if one or more remove machines fail to respond; if false, an unresponsive remove machine results in a failure.  This is not a mandatory property.  Its default is false. For example: 'true'"
+            />
+
+    <property
+            id="logsDirectory"
+            name="logsDirectory"
+            value=""
+            description="logsDirectory is the directory in which the JsUnitStandardServer stores the XML logs produced from tests run. It can be specified relative to the working directory. This is not a mandatory property. If not specified, the directory called 'logs' inside resourceBase is assumed. For example: 'c:\jsunit\java\logs'"
+            />
+
+    <property
+            id="port"
+            name="port"
+            value=""
+            description="port is the port on which the JsUnitStandardServer runs. This is not a mandatory property. If not specified, 8080 is assumed. For exapmle: '8080'"
+            />
+
+    <property
+            id="remoteMachineURLs"
+            name="remoteMachineURLs"
+            value=""
+            description="remoteMachineURLs is a property used only by the JsUnit Farm Server and the distributed_test target. Its value is the list of URLs of remove machines to which a request to run tests will be sent. For example: 'http://machine1.company.com:8080,http://localhost:8080,http://192.168.1.200:9090'"
+            />
+
+    <property
+            id="resourceBase"
+            name="resourceBase"
+            value=""
+            description="resourceBase is the directory that the JsUnitStandardServer considers to be its document root. It can be specified relative to the working directory. This is not a mandatory property. If not specified, the working directory is assumed. For example: 'c:\jsunit'"
+            />
+
+    <property
+            id="timeoutSeconds"
+            name="timeoutSeconds"
+            value=""
+            description="timeoutSeconds is the number of seconds to wait before timing out a browser during a test run. This is not a mandatory property. If not specified, 60 is assumed. For example: '60'"
+            />
+
+    <property
+            id="url"
+            name="url"
+            value=""
+            description="url is the URL (HTTP or file protocol) to open in the browser. For a JsUnit Server, this is a mandatory property for a test run if the server is not passed the 'url' parameter. For example: 'file:///c:/jsunit/testRunner.html?testPage=c:/jsunit/tests/jsUnitTestSuite.html'"
+            />
+
+    <!--
+     The remainder of this build file is not intended to be modified by the end user.
+     Those targets whose name begins with an underscore are not intended to be run directly by the end user.
+     -->
+
+    <property name="source_core" location="java/source_core"/>
+    <property name="source_server" location="java/source_server"/>
+    <property name="tests_core" location="java/tests_core"/>
+    <property name="tests_server" location="java/tests_server"/>
+    <property name="bin" location="java/bin"/>
+    <property name="lib" location="java/lib"/>
+    <property name="testlib" location="java/testlib"/>
+    <property name="config" location="java/config"/>
+    <property name="loggingPropertiesFile" location="logging.properties"/>
+
+    <path id="classpath">
+        <fileset dir="${lib}">
+            <include name="*.jar"/>
+        </fileset>
+        <fileset dir="${bin}">
+            <include name="jsunit.jar"/>
+        </fileset>
+        <dirset dir="${config}"/>
+    </path>
+
+    <path id="self_tests_classpath">
+        <fileset dir="${lib}">
+            <include name="*.jar"/>
+        </fileset>
+        <fileset dir="${testlib}">
+            <include name="*.jar"/>
+        </fileset>
+        <fileset dir="${bin}">
+            <include name="jsunit.jar"/>
+        </fileset>
+        <dirset dir="${config}"/>
+    </path>
+
+    <target name="_compile_source" description="Compiles the source">
+        <delete dir="${bin}/net"/>
+        <javac srcdir="${source_core}" destdir="${bin}" debug="true">
+            <classpath>
+                <fileset dir="${lib}">
+                    <include name="*.jar"/>
+                </fileset>
+            </classpath>
+        </javac>
+        <javac srcdir="${source_server}" destdir="${bin}" debug="true">
+            <classpath>
+                <fileset dir="${lib}">
+                    <include name="*.jar"/>
+                </fileset>
+                <path location="${bin}"/>
+            </classpath>
+        </javac>
+    </target>
+
+    <target name="_compile_tests" description="Compiles the self-tests">
+        <javac srcdir="${tests_core}" destdir="${bin}" debug="true">
+            <classpath refid="self_tests_classpath"/>
+        </javac>
+        <javac srcdir="${tests_server}" destdir="${bin}" debug="true">
+            <classpath refid="self_tests_classpath"/>
+        </javac>
+    </target>
+
+    <target name="_create_jar" depends="_compile_source" description="Creates jsunit.jar">
+        <delete file="${bin}/jsunit.jar"/>
+        <jar jarfile="${bin}/jsunit.jar" basedir="${bin}"/>
+        <delete dir="${bin}/net"/>
+    </target>
+
+    <target name="_generateJsUnitPropertiesSample" description="Generates the jsunit.properties.sample file">
+        <xslt in="build.xml" out="jsunit.properties.sample" destdir="."
+              style="xsl/buildDotXmlToJsUnitDotProperties.xsl"></xslt>
+    </target>
+
+    <target name="_run_unit_tests" depends="_compile_tests" description="Runs the JsUnit Java unit tests">
+        <junit fork="yes" haltonfailure="false" forkmode="once" showoutput="yes" printsummary="withOutAndErr"
+               failureproperty="junit_test_failed">
+            <formatter type="plain" usefile="false"/>
+            <classpath refid="self_tests_classpath"/>
+            <classpath path="${bin}"/>
+            <test name="net.jsunit.UnitTestSuite"/>
+        </junit>
+        <fail if="junit_test_failed"/>
+    </target>
+
+    <target name="_run_all_tests" depends="_create_jar,_compile_tests"
+            description="Runs all the JsUnit Java tests.  Used in the continuous build">
+        <junit fork="yes" haltonfailure="false" forkmode="once" showoutput="yes" printsummary="withOutAndErr"
+               failureproperty="junit_test_failed">
+            <formatter type="xml"/>
+            <classpath refid="self_tests_classpath"/>
+            <classpath path="${bin}"/>
+            <sysproperty key="java.security.manager" value="com.thoughtworks.ashcroft.runtime.JohnAshcroft"/>
+            <test name="net.jsunit.PureUnitTestSuite"/>
+        </junit>
+        <junit fork="yes" haltonfailure="false" forkmode="once" showoutput="yes" printsummary="withOutAndErr"
+               failureproperty="junit_test_failed">
+            <formatter type="xml"/>
+            <classpath refid="self_tests_classpath"/>
+            <classpath path="${bin}"/>
+            <test name="net.jsunit.ImpureUnitTestSuite"/>
+        </junit>
+        <junit fork="yes" haltonfailure="false" forkmode="once" showoutput="yes" printsummary="withOutAndErr"
+               failureproperty="junit_test_failed">
+            <formatter type="xml"/>
+            <classpath refid="self_tests_classpath"/>
+            <classpath path="${bin}"/>
+            <test name="net.jsunit.FunctionalTestSuite"/>
+        </junit>
+        <junit fork="yes" haltonfailure="false" forkmode="once" showoutput="yes" printsummary="withOutAndErr"
+               failureproperty="junit_test_failed">
+            <formatter type="xml"/>
+            <classpath refid="self_tests_classpath"/>
+            <classpath path="${bin}"/>
+            <test name="net.jsunit.FarmServerFunctionalTestSuite"/>
+        </junit>
+        <fail if="junit_test_failed"/>
+    </target>
+
+    <target name="create_distribution" depends="_create_jar,_run_unit_tests"
+            description="Creates and tests the JsUnit distribution"/>
+
+    <target name="start_server" description="Starts a JsUnit Server">
+        <java fork="true" classname="net.jsunit.JsUnitStandardServer">
+            <classpath refid="classpath"/>
+            <sysproperty key="java.util.logging.config.file" value="${loggingPropertiesFile}"/>
+            <sysproperty key="description" value="${description}"/>
+            <sysproperty key="browserFileNames" value="${browserFileNames}"/>
+            <sysproperty key="url" value="${url}"/>
+            <sysproperty key="port" value="${port}"/>
+            <sysproperty key="resourceBase" value="${resourceBase}"/>
+            <sysproperty key="logsDirectory" value="${logsDirectory}"/>
+            <sysproperty key="timeoutSeconds" value="${timeoutSeconds}"/>
+            <sysproperty key="closeBrowsersAfterTestRuns" value="${closeBrowsersAfterTestRuns}"/>
+        </java>
+    </target>
+
+    <target name="start_farm_server" description="Starts a JsUnit Farm Server">
+        <java fork="true" classname="net.jsunit.JsUnitFarmServer">
+            <classpath refid="classpath"/>
+            <sysproperty key="java.util.logging.config.file" value="${loggingPropertiesFile}"/>
+            <sysproperty key="description" value="${description}"/>
+            <sysproperty key="ignoreUnresponsiveRemoteMachines" value="${ignoreUnresponsiveRemoteMachines}"/>
+            <sysproperty key="logsDirectory" value="${logsDirectory}"/>
+            <sysproperty key="port" value="${port}"/>
+            <sysproperty key="remoteMachineURLs" value="${remoteMachineURLs}"/>
+            <sysproperty key="resourceBase" value="${resourceBase}"/>
+            <sysproperty key="url" value="${url}"/>
+        </java>
+    </target>
+
+    <target name="stop_server" description="Stops the JsUnit Server">
+        <java fork="true" classname="org.mortbay.stop.Main" failonerror="true">
+            <classpath refid="classpath"/>
+        </java>
+    </target>
+
+    <target name="standalone_test" description="Runs tests on the local machine">
+        <junit showoutput="true" haltonerror="true" haltonfailure="true">
+            <formatter type="plain" usefile="false"/>
+            <classpath refid="classpath"/>
+            <sysproperty key="browserFileNames" value="${browserFileNames}"/>
+            <sysproperty key="description" value="${description}"/>
+            <sysproperty key="closeBrowsersAfterTestRuns" value="${closeBrowsersAfterTestRuns}"/>
+            <sysproperty key="logsDirectory" value="${logsDirectory}"/>
+            <sysproperty key="port" value="${port}"/>
+            <sysproperty key="resourceBase" value="${resourceBase}"/>
+            <sysproperty key="timeoutSeconds" value="${timeoutSeconds}"/>
+            <sysproperty key="url" value="${url}"/>
+            <test name="net.jsunit.StandaloneTest"/>
+        </junit>
+    </target>
+
+    <target name="distributed_test" description="Runs tests the remote machines">
+        <junit showoutput="true" haltonerror="true" haltonfailure="true">
+            <formatter type="plain" usefile="false"/>
+            <classpath refid="classpath"/>
+            <sysproperty key="browserFileNames" value="${browserFileNames}"/>
+            <sysproperty key="description" value="${description}"/>
+            <sysproperty key="ignoreUnresponsiveRemoteMachines" value="${ignoreUnresponsiveRemoteMachines}"/>
+            <sysproperty key="logsDirectory" value="${logsDirectory}"/>
+            <sysproperty key="port" value="${port}"/>
+            <sysproperty key="remoteMachineURLs" value="${remoteMachineURLs}"/>
+            <sysproperty key="resourceBase" value="${resourceBase}"/>
+            <sysproperty key="url" value="${url}"/>
+            <test name="net.jsunit.DistributedTest"/>
+        </junit>
+    </target>
+
+</project>

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/changelog.txt
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/changelog.txt	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/changelog.txt	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,60 @@
+TRACING
+- Tracing is now color coded by trace level
+- Traces are now prefixed with the Test Page and Test Function from which the trace is made
+
+ASSERTION FUNCTIONS
+- assertArrayEquals(array1, array2) introduced
+- assertObjectEquals(object1, object2) introduced
+- assertHTMLEquals function introduced
+- assertEvaluatesToTrue and assertEvaluatesToFalse introduced
+- assertHashEquals     }
+- assertRoughlyEquals  } Pivotal functions
+- assertContains       }
+
+- changed expected/actual values display strings to use angle brackets, rather than square brackets
+
+- CLIENT-SIDE
+- HTML in result output is now correctly escaped
+- page load timeout changed to 120 seconds by default
+- setup page timeout change to 120 seconds by default
+- cache-buster for testpage retrieval & results submission
+- jsUnitRestoredHTMLDiv
+- turn off tracing, alerts, confirms when submitting
+- testPage parameter should be URL-encoded (only opera cares though)
+- Speed-up of Firefox/Mozilla (thanks to Chris Wesseling)
+- jsUnitMockTimeout.js (thanks to Pivotal, especially Nathan Wilmes)
+
+SERVER
+- start-browser scripts in bin
+- Migration of Java code to require Java 5.0
+- JSPs require a JDK
+- StandaloneTest and DistributedTest continue on after a failure in a particular browser or remote server respectively
+- StandaloneTest has a suite() method that makes the test run have multiple JUnit tests, one per browser
+- DistribuedTest has a suite() method that makes the test run have multiple JUnit tests, one per remote machine URL
+- Change to XML output format of test runs to include more information and be more hierarchical (machine->browser->test page->test case)
+- Logs are now prefixed with "JSTEST-" in order to match JUnit's "TEST-"
+- Logs now contain the browser ID (e.g. JSTEST-12345.5.xml means browser with ID 5); displayer servlet now takes an id and a browserId parameter
+- added support for launching the default system browser on Windows and UNIX (see the constant on net.jsunit.StandaloneTest)
+- StandaloneTest now runs tests in all specified browsers, even after an earlier browser failed
+- New "config" servlet that shows the configuration as XML of the server
+- Distributed Tests now send back an XML document that includes the XML for browser results as opposed to just a "success"/"failure" node
+- runner servlet takes a "url" querystring parameter that overrides the server's url property
+- test run requests to the JsUnitServer and the FarmServer are queued up and in serial so that different clients don't step on eachother
+- addition of new configuration parameter, "closeBrowsersAfterTestRuns", for whether to attempt to close browsers after test runs
+- addition of new configuration property, "timeoutSeconds", for how long to time browsers out
+- addition of new configuration property, "ignoreUnresponsiveRemoteMachines", for whether to care that remote machines don't uccessfully run the tests
+- addition of new configuration property, "description", which contains a human-readable description of the server
+- new index.jsp ("/") page
+- jsunit.org registered; redirects to edwardh.com/jsunit
+
+BUGS
+- fix for "retry test run" bug
+- bug 1070436 fixed
+- bug with multiple browsers and resultId specified fixed
+- Bug 1281427 fixed (test submission for Opera)
+- Safari fix
+- Bug 1431040 fixed
+
+ECLIPSE PLUGIN
+- Eclipse plugin version 1.0
+

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/css/jsUnitStyle.css
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/css/jsUnitStyle.css	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/css/jsUnitStyle.css	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,83 @@
+body {
+    margin-top: 0;
+    margin-bottom: 0;
+    font-family: Verdana, Arial, Helvetica, sans-serif;
+    color: #000;
+    font-size: 0.8em;
+    background-color: #fff;
+}
+
+a:link, a:visited {
+    color: #00F;
+}
+
+a:hover {
+    color: #F00;
+}
+
+h1 {
+    font-size: 1.2em;
+    font-weight: bold;
+    color: #039;
+    font-family: Verdana, Arial, Helvetica, sans-serif;
+}
+
+h2 {
+    font-weight: bold;
+    color: #039;
+    font-family: Verdana, Arial, Helvetica, sans-serif;
+}
+
+h3 {
+    font-weight: bold;
+    color: #039;
+    text-decoration: underline;
+    font-family: Verdana, Arial, Helvetica, sans-serif;
+}
+
+h4 {
+    font-weight: bold;
+    color: #039;
+    font-family: Verdana, Arial, Helvetica, sans-serif;
+}
+
+.jsUnitTestResultSuccess {
+    color: #000;
+}
+
+.jsUnitTestResultNotSuccess {
+    color: #F00;
+}
+
+.unselectedTab {
+    font-family: Verdana, Arial, Helvetica, sans-serif;
+    height: 26px;
+    background: #FFFFFF;
+    border-style: solid;
+    border-bottom-width: 1px;
+    border-top-width: 1px;
+    border-left-width: 1px;
+    border-right-width: 1px;
+}
+
+.selectedTab {
+    font-family: Verdana, Arial, Helvetica, sans-serif;
+    height: 26px;
+    background: #DDDDDD;
+    font-weight: bold;
+    border-style: solid;
+    border-bottom-width: 0px;
+    border-top-width: 1px;
+    border-left-width: 1px;
+    border-right-width: 1px;
+}
+
+.tabHeaderSeparator {
+    height: 26px;
+    background: #FFFFFF;
+    border-style: solid;
+    border-bottom-width: 1px;
+    border-top-width: 0px;
+    border-left-width: 0px;
+    border-right-width: 0px;
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/images/green.gif
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/images/green.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/images/logo_jsunit.gif
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/images/logo_jsunit.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/images/powerby-transparent.gif
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/images/powerby-transparent.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/images/red.gif
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/images/red.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/index.jsp
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/index.jsp	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/index.jsp	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,252 @@
+<%@ page import="net.jsunit.JsUnitServer" %>
+<%@ page import="net.jsunit.ServerRegistry" %>
+<%@ page import="net.jsunit.configuration.Configuration" %>
+<%@ page import="net.jsunit.configuration.ConfigurationProperty" %>
+<%@ page import="net.jsunit.model.Browser" %>
+<%@ page import="net.jsunit.utility.SystemUtility" %>
+<%@ page import="java.text.SimpleDateFormat" %>
+<%JsUnitServer server = ServerRegistry.getServer();%>
+<%Configuration configuration = server.getConfiguration();%>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>JsUnit <%if (server.isFarmServer()) {%> Farm<%}%> Server</title>
+    <script type="text/javascript" src="app/jsUnitCore.js"></script>
+    <script type="text/javascript" src="app/jsUnitVersionCheck.js"></script>
+    <script type="text/javascript">
+        function selectDiv(selectedDivName) {
+            updateDiv("testRunnerDiv", selectedDivName);
+            updateDiv("configDiv", selectedDivName);
+            updateDiv("runnerDiv", selectedDivName);
+            updateDiv("displayerDiv", selectedDivName);
+        }
+
+        function updateDiv(divName, selectedDivName) {
+            var isSelected = divName == selectedDivName;
+            var theDiv = document.getElementById(divName);
+            theDiv.style.visibility = isSelected ? "visible" : "hidden";
+            theDiv.style.height = isSelected ? "" : "0";
+
+            var theDivHeader = document.getElementById(divName + "Header");
+            theDivHeader.className = isSelected ? "selectedTab" : "unselectedTab";
+        }
+    </script>
+    <link rel="stylesheet" type="text/css" href="./css/jsUnitStyle.css">
+</head>
+
+<body onload="selectDiv('runnerDiv')">
+<table height="90" width="100%" cellpadding="0" cellspacing="0" border="0" summary="jsUnit Information"
+       bgcolor="#DDDDDD">
+    <tr>
+        <td width="1">
+            <a href="http://www.jsunit.net" target="_blank"><img src="images/logo_jsunit.gif" alt="JsUnit" border="0"/></a>
+        </td>
+        <td width="50">&nbsp;</td>
+        <th nowrap align="left">
+            <h4>JsUnit <%=SystemUtility.jsUnitVersion()%><%if (server.isFarmServer()) {%> Farm<%}%> Server</h4>
+            <font size="-2"><i>Running on <%=SystemUtility.displayString()%>
+                since <%=new SimpleDateFormat().format(server.getStartDate())%></i></font>
+            <%if (!server.isFarmServer()) {%>
+            <br>
+            <font size="-2"><i><%=server.getTestRunCount()%> test run(s) completed</i></font>
+            <br>
+            <%}%>
+        </th>
+        <td nowrap align="right" valign="middle">
+            <font size="-2">
+                <b><a href="http://www.jsunit.net/" target="_blank">www.jsunit.net</a></b><br>
+
+                <div id="versionCheckDiv"><a href="javascript:checkForLatestVersion('latestversion')">Check for newer
+                    version</a></div>
+            </font>
+            <a href="http://www.pivotalsf.com/" target="top">
+                <img border="0" src="images/powerby-transparent.gif" alt="Powered By Pivotal">
+            </a>
+        </td>
+
+    </tr>
+</table>
+<h4>
+    Server configuration
+</h4>
+<table border="0">
+    <tr>
+        <th nowrap align="right">Server type:</th>
+        <td width="10">&nbsp;</td>
+        <td><%=server.serverType().getDisplayName()%></td>
+    </tr>
+    <%
+        for (ConfigurationProperty property : configuration.getRequiredAndOptionalConfigurationProperties(server.serverType())) {
+    %>
+    <tr>
+        <th nowrap align="right"><%=property.getDisplayName()%>:</th>
+        <td width="10">&nbsp;</td>
+        <td>
+            <%
+                for (String valueString : property.getValueStrings(configuration)) {
+            %><div><%
+            if (valueString != null) {
+                if (property.isURL()) {
+        %><a href="<%=valueString%>"><%=valueString%></a><%
+        } else {
+        %><%=valueString%><%
+                }
+            }
+        %></div><%
+            }
+        %>
+        </td></tr>
+    <%
+        }
+    %>
+</table>
+<br>
+<h4>
+    Available services
+</h4>
+
+<table cellpadding="0" cellspacing="0">
+<tr>
+    <td class="tabHeaderSeparator">&nbsp;</td>
+    <td id="runnerDivHeader" class="selectedTab">
+        &nbsp;&nbsp;<a href="javascript:selectDiv('runnerDiv')">runner</a>&nbsp;&nbsp;
+    </td>
+    <td class="tabHeaderSeparator">&nbsp;</td>
+    <%if (!server.isFarmServer()) {%>
+    <td id="displayerDivHeader" class="unselectedTab">
+        &nbsp;&nbsp;<a href="javascript:selectDiv('displayerDiv')">displayer</a>&nbsp;&nbsp;
+    </td>
+    <td class="tabHeaderSeparator">&nbsp;</td>
+    <%}%>
+    <td id="testRunnerDivHeader" class="unselectedTab">
+        &nbsp;&nbsp;<a href="javascript:selectDiv('testRunnerDiv')">testRunner.html</a>&nbsp;&nbsp;
+    </td>
+    <td class="tabHeaderSeparator">&nbsp;</td>
+    <td id="configDivHeader" class="unselectedTab">
+        &nbsp;&nbsp;<a href="javascript:selectDiv('configDiv')">config</a>&nbsp;&nbsp;
+    </td>
+    <td class="tabHeaderSeparator" width="99%">&nbsp;</td>
+</tr>
+<tr>
+<td colspan="9"
+    style="border-style: solid;border-bottom-width:1px;border-top-width:0px;border-left-width:1px;border-right-width:1px;">
+<div id="runnerDiv" style="width:100%;visibility:visible;background:#DDDDDD">
+    <br>
+
+    <form action="/jsunit/runner" method="get" name="runnerForm">
+        <table>
+            <tr>
+                <td colspan="2">
+                    You can ask the server to run JsUnit tests using the <i>runner</i> servlet.
+                    You can run using the server's default URL for tests by going to <a href="/jsunit/runner">runner</a>,
+                    or you can specify a custom URL and/or browser ID using this form:
+                </td>
+            </tr>
+            <tr>
+                <td width="1">
+                    URL:
+                </td>
+                <td>
+                    <input type="text" name="url" size="100" value=""/>
+                </td>
+            </tr>
+            <tr>
+                <td colspan="2">
+                    <font size="-2"><i>e.g.
+                        http://www.jsunit.net/runner/testRunner.html?testPage=http://www.jsunit.net/runner/tests/jsUnitTestSuite.html</i>
+                    </font>
+                </td>
+            </tr>
+            <tr>
+                <td width="1">
+                    Browser:
+                </td>
+                <td>
+                    <%if (!server.isFarmServer()) {%>
+
+                    <select name="browserId">
+                        <option value="">(All browsers)</option>
+                        <%
+                            for (Browser browser : configuration.getBrowsers()) {
+                        %><option value="<%=browser.getId()%>"><%=browser.getFileName()%></option>
+                        <%}%>
+                    </select><br>
+                    <%}%>
+                </td>
+            </tr>
+            <tr>
+                <td colspan="2">
+                    <input type="submit" value="go"/>
+                </td>
+            </tr>
+        </table>
+    </form>
+    <br>&nbsp;
+</div>
+
+<%if (!server.isFarmServer()) {%>
+
+<div id="displayerDiv" style="width:100%;visibility:hidden;background:#DDDDDD">
+    <br>
+
+    <form action="/jsunit/displayer" name="displayerForm">
+        <table>
+            <tr>
+                <td colspan="2">
+                    You can view the logs of past runs using the displayer command.
+                    Use this form to specify the ID of the run you want to see:
+                </td>
+            </tr>
+            <tr>
+                <td width="1">
+                    ID:
+                </td>
+                <td>
+                    <input type="text" name="id" size="20"/>
+                </td>
+            </tr>
+            <tr>
+                <td width="1">
+                    Browser:
+                </td>
+                <td>
+                    <select name="browserId">
+                        <%
+                            for (Browser browser : configuration.getBrowsers()) {
+                        %><option value="<%=browser.getId()%>"><%=browser.getFileName()%></option>
+                        <%}%>
+                    </select><br>
+                </td>
+            </tr>
+            <tr>
+                <td colspan="2">
+                    <input type="submit" value="go"/>
+                </td>
+            </tr>
+        </table>
+    </form>
+    <br>&nbsp;
+</div>
+<%}%>
+
+<div id="testRunnerDiv" style="width:100%;visibility:hidden;background:#DDDDDD">
+    <br>
+    The manual Test Runner is at <a id="testRunnerHtml" href="./testRunner.html">testRunner.html</a>.
+    <br>&nbsp;
+</div>
+
+
+<div id="configDiv" style="width:100%;visibility:hidden;background:#DDDDDD">
+    <br>
+    You can see the configuration of this server as XML by going to <a id="config"
+                                                                       href="/jsunit/config">config</a>.
+    The config service is usually only used programmatically.
+    <br>&nbsp;
+</div>
+</td>
+</tr>
+</table>
+
+</body>
+</html>
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/bin/jsunit.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/bin/jsunit.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/config/farm_xwork.xml
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/config/farm_xwork.xml	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/config/farm_xwork.xml	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,41 @@
+<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN"
+        "http://www.opensymphony.com/xwork/xwork-1.0.dtd">
+
+<xwork>
+
+    <include file="webwork-default.xml"/>
+
+    <package name="default" extends="webwork-default">
+
+        <result-types>
+            <result-type name="jsUnitXml" class="net.jsunit.action.XmlResult"/>
+        </result-types>
+
+        <interceptors>
+            <interceptor name="farmServer" class="net.jsunit.interceptor.FarmServerInterceptor"/>
+            <interceptor name="remoteRunnerHitter" class="net.jsunit.interceptor.RemoteRunnerHitterInterceptor"/>
+
+            <interceptor-stack name="defaultStack">
+                <interceptor-ref name="servlet-config"/>
+                <interceptor-ref name="prepare"/>
+                <interceptor-ref name="static-params"/>
+                <interceptor-ref name="params"/>
+                <interceptor-ref name="conversionError"/>
+                <interceptor-ref name="farmServer"/>
+                <interceptor-ref name="remoteRunnerHitter"/>
+            </interceptor-stack>
+        </interceptors>
+
+        <default-interceptor-ref name="defaultStack"/>
+
+        <action name="runner" class="net.jsunit.action.DistributedTestRunnerAction">
+            <result name="success" type="jsUnitXml"/>
+        </action>
+
+        <action name="config" class="net.jsunit.action.FarmServerConfigurationAction">
+            <result name="success" type="jsUnitXml"/>
+        </action>
+
+    </package>
+
+</xwork>

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/config/xwork.xml
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/config/xwork.xml	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/config/xwork.xml	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,62 @@
+<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN" "http://www.opensymphony.com/xwork/xwork-1.0.dtd">
+
+<xwork>
+
+    <include file="webwork-default.xml"/>
+
+    <package name="default" extends="webwork-default">
+
+        <result-types>
+            <result-type name="jsUnitXml" class="net.jsunit.action.XmlResult"/>
+            <result-type name="jsUnitLatestVersion" class="net.jsunit.action.LatestVersionResult"/>
+        </result-types>
+
+        <interceptors>
+            <interceptor name="browserTestRunner" class="net.jsunit.interceptor.BrowserTestRunnerInterceptor"/>
+            <interceptor name="browserResult" class="net.jsunit.interceptor.BrowserResultInterceptor"/>
+            <interceptor name="requestSource" class="net.jsunit.interceptor.RequestSourceInterceptor"/>
+            <interceptor name="versionGrabber" class="net.jsunit.interceptor.VersionGrabberInterceptor"/>
+
+            <interceptor-stack name="defaultStack">
+                <interceptor-ref name="servlet-config"/>
+                <interceptor-ref name="prepare"/>
+                <interceptor-ref name="params"/>
+                <interceptor-ref name="browserTestRunner"/>
+            </interceptor-stack>
+        </interceptors>
+
+        <default-interceptor-ref name="defaultStack"/>
+
+        <action name="acceptor" class="net.jsunit.action.ResultAcceptorAction">
+            <result name="success" type="jsUnitXml"/>
+            <interceptor-ref name="defaultStack"/>
+            <interceptor-ref name="browserResult"/>
+        </action>
+
+        <action name="runner" class="net.jsunit.action.TestRunnerAction">
+            <result name="success" type="jsUnitXml"/>
+            <result name="error" type="jsUnitXml"/>
+            <interceptor-ref name="defaultStack"/>
+            <interceptor-ref name="requestSource"/>
+        </action>
+
+        <action name="displayer" class="net.jsunit.action.ResultDisplayerAction">
+            <result name="success" type="jsUnitXml"/>
+            <result name="error" type="jsUnitXml"/>
+        </action>
+
+        <action name="config" class="net.jsunit.action.BrowserTestRunnerConfigurationAction">
+            <result name="success" type="jsUnitXml"/>
+        </action>
+
+        <action name="latestversion" class="net.jsunit.action.LatestVersionAction">
+            <result name="success" type="jsUnitLatestVersion"/>
+            <result name="error" type="httpheader">
+                <param name="status">500</param>
+            </result>
+            <interceptor-ref name="versionGrabber"/>
+        </action>
+
+    </package>
+
+</xwork>

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/ant.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/ant.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/commons-el.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/commons-el.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/commons-logging.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/commons-logging.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/jasper-compiler.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/jasper-compiler.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/jasper-runtime.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/jasper-runtime.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/javax.servlet.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/javax.servlet.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/jdom.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/jdom.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/junit.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/junit.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/ognl.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/ognl.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/org.mortbay.jetty.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/org.mortbay.jetty.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/oscore.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/oscore.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/rife-continuations.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/rife-continuations.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/start.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/start.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/stop.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/stop.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/webwork-2.2-beta-4.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/webwork-2.2-beta-4.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/xercesImpl-2.6.2.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/xercesImpl-2.6.2.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/xwork-1.1.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/lib/xwork-1.1.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/BrowserLaunchSpecification.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/BrowserLaunchSpecification.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/BrowserLaunchSpecification.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,35 @@
+package net.jsunit;
+
+import net.jsunit.model.Browser;
+import net.jsunit.utility.StringUtility;
+
+public class BrowserLaunchSpecification {
+
+    private final Browser browser;
+    private final String overrideUrl;
+
+    public BrowserLaunchSpecification(Browser browser) {
+        this(browser, null);
+    }
+
+    public BrowserLaunchSpecification(Browser browser, String overrideUrl) {
+        this.browser = browser;
+        this.overrideUrl = overrideUrl;
+    }
+
+    public String getOverrideUrl() {
+        return overrideUrl;
+    }
+
+    public boolean hasOverrideUrl() {
+        return !StringUtility.isEmpty(overrideUrl);
+    }
+
+    public boolean isForDefaultBrowser() {
+        return browser.isDefault();
+    }
+
+    public Browser getBrowser() {
+        return browser;
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/BrowserTestRunner.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/BrowserTestRunner.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/BrowserTestRunner.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,34 @@
+package net.jsunit;
+
+import net.jsunit.model.Browser;
+import net.jsunit.model.BrowserResult;
+
+import java.util.List;
+
+public interface BrowserTestRunner extends XmlRenderable {
+
+    void startTestRun();
+
+    void finishTestRun();
+
+    long launchBrowserTestRun(BrowserLaunchSpecification launchSpec);
+
+    void accept(BrowserResult result);
+
+    boolean hasReceivedResultSince(long launchTime);
+
+    BrowserResult lastResult();
+
+    void dispose();
+
+    BrowserResult findResultWithId(String id, int browserId) throws InvalidBrowserIdException;
+
+    void logStatus(String message);
+
+    List<Browser> getBrowsers();
+
+    int timeoutSeconds();
+
+    boolean isAlive();
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/ClientSideConnection.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/ClientSideConnection.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/ClientSideConnection.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,59 @@
+/**
+ * 
+ */
+package net.jsunit;
+
+import java.io.*;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+public class ClientSideConnection extends Thread {
+
+    private MessageReceiver receiver;
+    private final int port;
+    private ServerSocket serverSocket;
+    private Socket socket;
+    private BufferedReader reader;
+    private PrintWriter writer;
+    private boolean running;
+
+    public ClientSideConnection(MessageReceiver receiver, int port) {
+        this.port = port;
+        this.receiver = receiver;
+    }
+
+    public void run() {
+        try {
+            serverSocket = new ServerSocket(port);
+            socket = serverSocket.accept();
+            reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
+            writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF-8"));
+            String message;
+            running = true;
+            while (running && reader != null && (message = reader.readLine()) != null)
+                receiver.messageReceived(message);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        shutdown();
+    }
+
+    public boolean isRunning() {
+        return running;
+    }
+
+    public void shutdown() {
+        try {
+            if (serverSocket != null)
+                serverSocket.close();
+        } catch (IOException e) {
+        }
+        running = false;
+    }
+
+    public void sendMessage(String message) {
+        writer.println(message);
+        writer.flush();
+    }
+
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/InvalidBrowserIdException.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/InvalidBrowserIdException.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/InvalidBrowserIdException.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,7 @@
+package net.jsunit;
+
+public class InvalidBrowserIdException extends Throwable {
+    public InvalidBrowserIdException(int invalidBrowserId) {
+        super("Invalid browser ID: " + invalidBrowserId);
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/MessageReceiver.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/MessageReceiver.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/MessageReceiver.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,8 @@
+/**
+ * 
+ */
+package net.jsunit;
+
+interface MessageReceiver {
+    public void messageReceived(String message);
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/RemoteTestRunClient.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/RemoteTestRunClient.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/RemoteTestRunClient.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,75 @@
+package net.jsunit;
+
+import net.jsunit.model.Browser;
+import net.jsunit.model.BrowserResult;
+import net.jsunit.model.BrowserResultBuilder;
+import net.jsunit.model.BrowserSource;
+
+public class RemoteTestRunClient implements MessageReceiver {
+
+    private BrowserSource browserSource;
+    private final TestRunListener listener;
+    private MessageReceiver complexMessageReceiver;
+    private ClientSideConnection clientSideConnection;
+
+    public RemoteTestRunClient(BrowserSource browserSource, TestRunListener listener, int serverPort) {
+        this.browserSource = browserSource;
+        this.listener = listener;
+        clientSideConnection = new ClientSideConnection(this, serverPort);
+    }
+
+    public void startListening() {
+        clientSideConnection.start();
+    }
+
+    public void stopListening() {
+        clientSideConnection.shutdown();
+    }
+
+    public void messageReceived(String message) {
+        if (message.equals(TestRunNotifierServer.TEST_RUN_STARTED))
+            listener.testRunStarted();
+        else if (message.equals(TestRunNotifierServer.TEST_RUN_FINISHED))
+            listener.testRunFinished();
+        else if (message.equals(TestRunNotifierServer.BROWSER_TEST_RUN_STARTED))
+            complexMessageReceiver = new TestRunStartedReceiver();
+        else if (message.equals(TestRunNotifierServer.BROWSER_TEST_RUN_FINISHED))
+            complexMessageReceiver = new TestRunFinishedReceiver();
+        else
+            complexMessageReceiver.messageReceived(message);
+    }
+
+    private class TestRunStartedReceiver implements MessageReceiver {
+
+        public void messageReceived(String browserIdString) {
+            int browserId = Integer.parseInt(browserIdString);
+            Browser browser = browserSource.getBrowserById(browserId);
+            listener.browserTestRunStarted(browser);
+        }
+    }
+
+    private class TestRunFinishedReceiver implements MessageReceiver {
+
+        private Browser browser;
+        private String xmlString = "";
+
+        public void messageReceived(String message) {
+            if (browser == null) {
+                int browserId = Integer.parseInt(message);
+                browser = browserSource.getBrowserById(browserId);
+            } else if (message.equals(TestRunNotifierServer.END_XML)) {
+                BrowserResult result = new BrowserResultBuilder(browserSource).build(xmlString);
+                listener.browserTestRunFinished(browser, result);
+            } else if (message.trim().length() > 0) {
+                xmlString += message;
+                xmlString += "\n";
+            }
+        }
+
+    }
+
+    public void sendStopServer() {
+        clientSideConnection.sendMessage("stop");
+    }
+
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/ServerSideConnection.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/ServerSideConnection.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/ServerSideConnection.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,77 @@
+package net.jsunit;
+
+import java.io.*;
+import java.net.Socket;
+
+public class ServerSideConnection {
+
+    private int port;
+    private Socket clientSocket;
+    private PrintWriter writer;
+    private String host = "localhost";
+    private boolean isConnected;
+    private final MessageReceiver receiver;
+    private BufferedReader reader;
+
+    public ServerSideConnection(MessageReceiver receiver, int port) {
+        this.receiver = receiver;
+        this.port = port;
+    }
+
+    public void connect() {
+        for (int i = 1; i < 30; i++) {
+            try {
+                clientSocket = new Socket(host, port);
+                writer = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream(), "UTF-8"), false);
+                reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(), "UTF-8"));
+                isConnected = true;
+                new ReaderThread().start();
+                return;
+            } catch (IOException e1) {
+                try {
+                    Thread.sleep(250);
+                } catch (InterruptedException e2) {
+                }
+            }
+        }
+        throw new RuntimeException("server could not connect");
+    }
+
+    public void shutDown() {
+        if (writer != null) {
+            writer.close();
+            writer = null;
+        }
+
+        try {
+            if (clientSocket != null) {
+                clientSocket.close();
+                clientSocket = null;
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void sendMessage(String message) {
+        writer.println(message);
+        writer.flush();
+    }
+
+    public boolean isConnected() {
+        return isConnected;
+    }
+
+    class ReaderThread extends Thread {
+        public void run() {
+            String message;
+            try {
+                while (isConnected && reader != null && (message = reader.readLine()) != null)
+                    receiver.messageReceived(message);
+            } catch (IOException e) {
+            }
+
+        }
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/TestRunListener.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/TestRunListener.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/TestRunListener.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,18 @@
+package net.jsunit;
+
+import net.jsunit.model.Browser;
+import net.jsunit.model.BrowserResult;
+
+public interface TestRunListener {
+
+    boolean isReady();
+
+    void testRunStarted();
+
+    void testRunFinished();
+
+    void browserTestRunStarted(Browser browser);
+
+    void browserTestRunFinished(Browser browser, BrowserResult result);
+
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/TestRunNotifierServer.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/TestRunNotifierServer.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/TestRunNotifierServer.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,63 @@
+package net.jsunit;
+
+import net.jsunit.model.Browser;
+import net.jsunit.model.BrowserResult;
+import net.jsunit.utility.XmlUtility;
+
+public class TestRunNotifierServer implements TestRunListener {
+
+    public static final String TEST_RUN_FINISHED = "testRunFinished";
+    public static final String TEST_RUN_STARTED = "testRunStarted";
+    public static final String BROWSER_TEST_RUN_FINISHED = "browserTestRunFinished";
+    public static final String BROWSER_TEST_RUN_STARTED = "browserTestRunStarted";
+    public static final String END_XML = "endXml";
+    private ServerSideConnection serverSideConnection;
+
+    public TestRunNotifierServer(BrowserTestRunner runner, int port) {
+        serverSideConnection = new ServerSideConnection(new StopMessageReceiver(runner), port);
+    }
+
+    public void browserTestRunStarted(Browser browser) {
+        serverSideConnection.sendMessage(BROWSER_TEST_RUN_STARTED);
+        serverSideConnection.sendMessage(String.valueOf(browser.getId()));
+    }
+
+    public void browserTestRunFinished(Browser browser, BrowserResult result) {
+        serverSideConnection.sendMessage(BROWSER_TEST_RUN_FINISHED);
+        serverSideConnection.sendMessage(String.valueOf(browser.getId()));
+        serverSideConnection.sendMessage(XmlUtility.asString(result.asXmlDocument()));
+        serverSideConnection.sendMessage(END_XML);
+    }
+
+    public void testRunStarted() {
+        serverSideConnection.connect();
+        serverSideConnection.sendMessage(TEST_RUN_STARTED);
+    }
+
+    public void testRunFinished() {
+        serverSideConnection.sendMessage(TEST_RUN_FINISHED);
+        serverSideConnection.shutDown();
+    }
+
+    public boolean isReady() {
+        return serverSideConnection.isConnected();
+    }
+
+    static class StopMessageReceiver implements MessageReceiver {
+
+        private final BrowserTestRunner runner;
+
+        public StopMessageReceiver(BrowserTestRunner runner) {
+            this.runner = runner;
+        }
+
+        public void messageReceived(String message) {
+            if ("stop".equals(message)) {
+                runner.logStatus("Stopping Test Run");
+                runner.dispose();
+            }
+        }
+
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/XmlRenderable.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/XmlRenderable.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/XmlRenderable.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,9 @@
+package net.jsunit;
+
+import org.jdom.Element;
+
+public interface XmlRenderable {
+
+    Element asXml();
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/ArgumentsConfigurationSource.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/ArgumentsConfigurationSource.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/ArgumentsConfigurationSource.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,66 @@
+package net.jsunit.configuration;
+
+import java.util.List;
+
+public class ArgumentsConfigurationSource implements ConfigurationSource {
+
+    private List<String> arguments;
+
+    public ArgumentsConfigurationSource(List<String> arguments) {
+        this.arguments = arguments;
+    }
+
+    private String argumentValue(ConfigurationProperty property) {
+        for (int i = 0; i < arguments.size(); i++) {
+            if (arguments.get(i).equalsIgnoreCase("-" + property.getName())) {
+                String value = arguments.get(i + 1);
+                if (!value.startsWith("-"))
+                    return value;
+                else
+                    return "";
+            }
+        }
+        return null;
+    }
+
+    public String resourceBase() {
+        return argumentValue(ConfigurationProperty.RESOURCE_BASE);
+    }
+
+    public String port() {
+        return argumentValue(ConfigurationProperty.PORT);
+    }
+
+    public String remoteMachineURLs() {
+        return argumentValue(ConfigurationProperty.REMOTE_MACHINE_URLS);
+    }
+
+    public String logsDirectory() {
+        return argumentValue(ConfigurationProperty.LOGS_DIRECTORY);
+    }
+
+    public String browserFileNames() {
+        return argumentValue(ConfigurationProperty.BROWSER_FILE_NAMES);
+    }
+
+    public String url() {
+        return argumentValue(ConfigurationProperty.URL);
+    }
+
+    public String ignoreUnresponsiveRemoteMachines() {
+        return argumentValue(ConfigurationProperty.IGNORE_UNRESPONSIVE_REMOTE_MACHINES);
+    }
+
+    public String closeBrowsersAfterTestRuns() {
+        return argumentValue(ConfigurationProperty.CLOSE_BROWSERS_AFTER_TEST_RUNS);
+    }
+
+    public String description() {
+        return argumentValue(ConfigurationProperty.DESCRIPTION);
+    }
+
+    public String timeoutSeconds() {
+        return argumentValue(ConfigurationProperty.TIMEOUT_SECONDS);
+    }
+
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/CompositeConfigurationSource.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/CompositeConfigurationSource.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/CompositeConfigurationSource.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,135 @@
+package net.jsunit.configuration;
+
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class CompositeConfigurationSource implements ConfigurationSource {
+    private List<ConfigurationSource> sources;
+
+    public CompositeConfigurationSource() {
+        this.sources = new ArrayList<ConfigurationSource>();
+    }
+
+    public CompositeConfigurationSource(ConfigurationSource... sources) {
+        this();
+        add(sources);
+    }
+
+    public static ConfigurationSource productionConfiguration(String[] arguments) {
+        CompositeConfigurationSource result = new CompositeConfigurationSource(
+                new ArgumentsConfigurationSource(Arrays.asList(arguments)),
+                new EnvironmentVariablesConfigurationSource());
+        try {
+            result.add(new PropertiesFileConfigurationSource());
+        } catch (FileNotFoundException e) {
+            // Skip the properties file configuration source if there is no appropriately names properties file.
+        }
+        return result;
+    }
+
+    public void add(ConfigurationSource... sources) {
+        this.sources.addAll(Arrays.asList(sources));
+    }
+
+    public String browserFileNames() {
+        for (ConfigurationSource source : sources) {
+            String result = source.browserFileNames();
+            if (result != null) {
+                return result;
+            }
+        }
+        return null;
+    }
+
+    public String closeBrowsersAfterTestRuns() {
+        for (ConfigurationSource source : sources) {
+            String result = source.closeBrowsersAfterTestRuns();
+            if (result != null) {
+                return result;
+            }
+        }
+        return null;
+    }
+
+    public String description() {
+        for (ConfigurationSource source : sources) {
+            String result = source.description();
+            if (result != null) {
+                return result;
+            }
+        }
+        return null;
+    }
+
+    public String logsDirectory() {
+        for (ConfigurationSource source : sources) {
+            String result = source.logsDirectory();
+            if (result != null) {
+                return result;
+            }
+        }
+        return null;
+    }
+
+    public String port() {
+        for (ConfigurationSource source : sources) {
+            String result = source.port();
+            if (result != null) {
+                return result;
+            }
+        }
+        return null;
+    }
+
+    public String remoteMachineURLs() {
+        for (ConfigurationSource source : sources) {
+            String result = source.remoteMachineURLs();
+            if (result != null) {
+                return result;
+            }
+        }
+        return null;
+    }
+
+    public String resourceBase() {
+        for (ConfigurationSource source : sources) {
+            String result = source.resourceBase();
+            if (result != null) {
+                return result;
+            }
+        }
+        return null;
+    }
+
+    public String timeoutSeconds() {
+        for (ConfigurationSource source : sources) {
+            String result = source.timeoutSeconds();
+            if (result != null) {
+                return result;
+            }
+        }
+        return null;
+    }
+
+    public String url() {
+        for (ConfigurationSource source : sources) {
+            String result = source.url();
+            if (result != null) {
+                return result;
+            }
+        }
+        return null;
+    }
+
+    public String ignoreUnresponsiveRemoteMachines() {
+        for (ConfigurationSource source : sources) {
+            String result = source.ignoreUnresponsiveRemoteMachines();
+            if (result != null) {
+                return result;
+            }
+        }
+        return null;
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/Configuration.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/Configuration.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/Configuration.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,177 @@
+package net.jsunit.configuration;
+
+import net.jsunit.model.Browser;
+import net.jsunit.model.BrowserSource;
+import net.jsunit.utility.SystemUtility;
+import org.jdom.Element;
+
+import java.io.File;
+import java.net.URL;
+import java.util.List;
+
+public final class Configuration implements BrowserSource {
+
+    private List<Browser> browsers;
+    private boolean closeBrowsersAfterTestRuns;
+    private String description;
+    private boolean ignoreUnresponsiveRemoteMachines;
+    private File logsDirectory;
+    private int port;
+    private List<URL> remoteMachineURLs;
+    private File resourceBase;
+    private int timeoutSeconds;
+    private URL testURL;
+
+    public static Configuration resolve(String[] arguments) {
+        return new Configuration(resolveSource(arguments));
+    }
+
+    public static ConfigurationSource resolveSource(String[] arguments) {
+        return CompositeConfigurationSource.productionConfiguration(arguments);
+    }
+
+    public static ConfigurationSource resolveSource() {
+        return resolveSource(new String[]{});
+    }
+
+    public Configuration(ConfigurationSource source) {
+        for (ConfigurationProperty property : ConfigurationProperty.values())
+            property.configure(this, source);
+    }
+
+    public Element asXml(ServerType serverType) {
+        Element configurationElement = new Element("configuration");
+        configurationElement.setAttribute("type", serverType.name());
+        addSystemElementsTo(configurationElement);
+        for (ConfigurationProperty property : getRequiredAndOptionalConfigurationProperties(serverType))
+            property.addXmlTo(configurationElement, this);
+        return configurationElement;
+    }
+
+    private void addSystemElementsTo(Element element) {
+        Element osElement = new Element("os");
+        osElement.setText(SystemUtility.osString());
+        element.addContent(osElement);
+        Element ipAddressElement = new Element("ipAddress");
+        ipAddressElement.setText(SystemUtility.ipAddress());
+        element.addContent(ipAddressElement);
+        Element hostnameElement = new Element("hostname");
+        hostnameElement.setText(SystemUtility.hostname());
+        element.addContent(hostnameElement);
+    }
+
+    public List<ConfigurationProperty> getRequiredAndOptionalConfigurationProperties(ServerType serverType) {
+        return serverType.getRequiredAndOptionalConfigurationProperties();
+    }
+
+    public String[] asArgumentsArray() {
+        List<ConfigurationProperty> properties = ConfigurationProperty.all();
+        String[] arguments = new String[properties.size() * 2];
+        int i = 0;
+        for (ConfigurationProperty property : properties) {
+            arguments[i++] = "-" + property.getName();
+            arguments[i++] = property.getValueString(this);
+        }
+        return arguments;
+    }
+
+    public boolean isValidFor(ServerType type) {
+        return type.getPropertiesInvalidFor(this).isEmpty();
+    }
+
+    public String toString() {
+        return getDescription() == null ? super.toString() : getDescription();
+    }
+
+    public List<Browser> getBrowsers() {
+        return browsers;
+    }
+
+    public void setBrowsers(List<Browser> browsers) {
+        this.browsers = browsers;
+    }
+
+    public boolean shouldCloseBrowsersAfterTestRuns() {
+        return closeBrowsersAfterTestRuns;
+    }
+
+    public void setCloseBrowsersAfterTestRuns(boolean closeBrowsersAfterTestRuns) {
+        this.closeBrowsersAfterTestRuns = closeBrowsersAfterTestRuns;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public boolean shouldIgnoreUnresponsiveRemoteMachines() {
+        return ignoreUnresponsiveRemoteMachines;
+    }
+
+    public void setIgnoreUnresponsiveRemoteMachines(boolean ignoreUnresponsiveRemoteMachines) {
+        this.ignoreUnresponsiveRemoteMachines = ignoreUnresponsiveRemoteMachines;
+    }
+
+    public File getLogsDirectory() {
+        return logsDirectory;
+    }
+
+    public void setLogsDirectory(File logsDirectory) {
+        this.logsDirectory = logsDirectory;
+    }
+
+    public int getPort() {
+        return port;
+    }
+
+    public void setPort(int port) {
+        this.port = port;
+    }
+
+    public List<URL> getRemoteMachineURLs() {
+        return remoteMachineURLs;
+    }
+
+    public void setRemoteMachineURLs(List<URL> remoteMachineURLs) {
+        this.remoteMachineURLs = remoteMachineURLs;
+    }
+
+    public File getResourceBase() {
+        return resourceBase;
+    }
+
+    public void setResourceBase(File resourceBase) {
+        this.resourceBase = resourceBase;
+    }
+
+    public int getTimeoutSeconds() {
+        return timeoutSeconds;
+    }
+
+    public void setTimeoutSeconds(int timeoutSeconds) {
+        this.timeoutSeconds = timeoutSeconds;
+    }
+
+    public URL getTestURL() {
+        return testURL;
+    }
+
+    public void setTestURL(URL url) {
+        this.testURL = url;
+    }
+
+    public Browser getBrowserById(int id) {
+        for (Browser browser : browsers)
+            if (browser.hasId(id))
+                return browser;
+        return null;
+    }
+
+    public URL getRemoteMachineURLById(int id) {
+        return getRemoteMachineURLs().get(id);
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/ConfigurationException.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/ConfigurationException.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/ConfigurationException.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,36 @@
+package net.jsunit.configuration;
+
+public class ConfigurationException extends RuntimeException {
+    private ConfigurationProperty propertyInError;
+    private String invalidValue;
+
+    public ConfigurationException(ConfigurationProperty property, String invalidValue) {
+        this.propertyInError = property;
+        this.invalidValue = invalidValue;
+    }
+
+    public ConfigurationException(ConfigurationProperty property, String invalidValue, Exception exception) {
+        super(exception);
+        this.propertyInError = property;
+        this.invalidValue = invalidValue;
+    }
+
+    public ConfigurationProperty getPropertyInError() {
+        return propertyInError;
+    }
+
+    public String getInvalidValue() {
+        return invalidValue;
+    }
+
+    public String toString() {
+        StringBuffer result = new StringBuffer();
+        result.append("Invalid property ");
+        result.append(propertyInError.getName());
+        result.append(" - \"");
+        result.append(invalidValue);
+        result.append("\"");
+        return result.toString();
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/ConfigurationProperty.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/ConfigurationProperty.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/ConfigurationProperty.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,286 @@
+package net.jsunit.configuration;
+
+import net.jsunit.model.Browser;
+import net.jsunit.utility.StringUtility;
+import org.jdom.Element;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.*;
+
+public enum ConfigurationProperty {
+
+    BROWSER_FILE_NAMES("browserFileNames", "Browser file names", false, true) {
+
+        public String getValueString(Configuration configuration) {
+            StringBuffer buffer = new StringBuffer();
+            for (Iterator it = configuration.getBrowsers().iterator(); it.hasNext();) {
+                Browser browser = (Browser) it.next();
+                buffer.append(browser.getFileName());
+                if (it.hasNext())
+                    buffer.append(",");
+            }
+            return buffer.toString();
+        }
+
+        protected void addContentTo(Configuration configuration, Element element) {
+            for (Browser browser : configuration.getBrowsers()) {
+                Element fileNameElement = new Element("browserFileName");
+                fileNameElement.setAttribute("id", String.valueOf(browser.getId()));
+                fileNameElement.setText(browser.getFileName());
+                element.addContent(fileNameElement);
+            }
+        }
+
+        public void configure(Configuration configuration, ConfigurationSource source) throws ConfigurationException {
+            String browserFileNamesString = source.browserFileNames();
+            try {
+                List<String> browserFileNames = StringUtility.listFromCommaDelimitedString(browserFileNamesString);
+                Set<String> alreadyAddedBrowserFileNames = new HashSet<String>();
+                int id = 0;
+                List<Browser> browsers = new ArrayList<Browser>();
+                for (String browserFileName : browserFileNames) {
+                    if (!alreadyAddedBrowserFileNames.contains(browserFileName) || Browser.DEFAULT_SYSTEM_BROWSER.equals(browserFileName))
+                    {
+                        browsers.add(new Browser(browserFileName, id++));
+                        alreadyAddedBrowserFileNames.add(browserFileName);
+                    }
+                }
+                configuration.setBrowsers(browsers);
+            } catch (Exception e) {
+                throw new ConfigurationException(this, browserFileNamesString, e);
+            }
+        }
+    },
+
+    CLOSE_BROWSERS_AFTER_TEST_RUNS("closeBrowsersAfterTestRuns", "Close browsers?", false, false) {
+        public String getValueString(Configuration configuration) {
+            return String.valueOf(configuration.shouldCloseBrowsersAfterTestRuns());
+        }
+
+        public void configure(Configuration configuration, ConfigurationSource source) throws ConfigurationException {
+            String string = source.closeBrowsersAfterTestRuns();
+            if (StringUtility.isEmpty(string))
+                string = String.valueOf(true);
+            configuration.setCloseBrowsersAfterTestRuns(Boolean.valueOf(string));
+        }
+    },
+
+    DESCRIPTION("description", "Description", false, false) {
+        public String getValueString(Configuration configuration) {
+            String description = configuration.getDescription();
+            if (StringUtility.isEmpty(description))
+                return "";
+            return description;
+        }
+
+        public void configure(Configuration configuration, ConfigurationSource source) throws ConfigurationException {
+            configuration.setDescription(source.description());
+        }
+    },
+
+    IGNORE_UNRESPONSIVE_REMOTE_MACHINES("ignoreUnresponsiveRemoteMachines", "Ignore unresponsive remove machines?", false, false) {
+        public String getValueString(Configuration configuration) {
+            return String.valueOf(configuration.shouldIgnoreUnresponsiveRemoteMachines());
+        }
+
+        public void configure(Configuration configuration, ConfigurationSource source) throws ConfigurationException {
+            String string = source.ignoreUnresponsiveRemoteMachines();
+            if (StringUtility.isEmpty(string))
+                string = String.valueOf(false);
+            configuration.setIgnoreUnresponsiveRemoteMachines(Boolean.valueOf(string));
+        }
+    },
+
+    LOGS_DIRECTORY("logsDirectory", "Logs directory", false, false) {
+        public String getValueString(Configuration configuration) {
+            return configuration.getLogsDirectory().getAbsolutePath();
+        }
+
+        public void configure(Configuration configuration, ConfigurationSource source) throws ConfigurationException {
+            String logsDirectoryString = source.logsDirectory();
+            try {
+                if (StringUtility.isEmpty(logsDirectoryString))
+                    logsDirectoryString = "logs";
+                configuration.setLogsDirectory(new File(logsDirectoryString));
+            } catch (Exception e) {
+                throw new ConfigurationException(this, logsDirectoryString, e);
+            }
+
+        }
+    },
+
+    PORT("port", "Port", false, false) {
+        public String getValueString(Configuration configuration) {
+            return String.valueOf(configuration.getPort());
+        }
+
+        public void configure(Configuration configuration, ConfigurationSource source) throws ConfigurationException {
+            String portString = source.port();
+            if (StringUtility.isEmpty(portString))
+                portString = "8080";
+            try {
+                configuration.setPort(Integer.parseInt(portString));
+            } catch (NumberFormatException e) {
+                throw new ConfigurationException(this, portString, e);
+            }
+        }
+    },
+
+    REMOTE_MACHINE_URLS("remoteMachineURLs", "Remote machine URLs", true, true) {
+        public String getValueString(Configuration configuration) {
+            return StringUtility.commaSeparatedString(configuration.getRemoteMachineURLs());
+        }
+
+        protected void addContentTo(Configuration configuration, Element element) {
+            for (int i = 0; i < configuration.getRemoteMachineURLs().size(); i++) {
+                URL remoteMachineURL = configuration.getRemoteMachineURLs().get(i);
+                Element urlElement = new Element("remoteMachineURL");
+                urlElement.setAttribute("id", String.valueOf(i));
+                urlElement.setText(remoteMachineURL.toString());
+                element.addContent(urlElement);
+            }
+        }
+
+        public void configure(Configuration configuration, ConfigurationSource source) throws ConfigurationException {
+            String remoteMachineURLs = source.remoteMachineURLs();
+            List<String> strings = StringUtility.listFromCommaDelimitedString(remoteMachineURLs);
+            List<URL> result = new ArrayList<URL>(strings.size());
+            Set<String> alreadyAddedURLStrings = new HashSet<String>();
+            for (String string : strings)
+                try {
+                    URL attemptedURL = new URL(string);
+                    URL normalizedURL = new URL(attemptedURL.getProtocol(), attemptedURL.getHost(), attemptedURL.getPort(), "/jsunit");
+                    if (!alreadyAddedURLStrings.contains(normalizedURL.toString())) {
+                        result.add(normalizedURL);
+                        alreadyAddedURLStrings.add(normalizedURL.toString());
+                    }
+                } catch (MalformedURLException e) {
+                    throw new ConfigurationException(this, remoteMachineURLs, e);
+                }
+            configuration.setRemoteMachineURLs(result);
+        }
+    },
+
+    RESOURCE_BASE("resourceBase", "Resource base", false, false) {
+        public String getValueString(Configuration configuration) {
+            return configuration.getResourceBase().getAbsolutePath();
+        }
+
+        public void configure(Configuration configuration, ConfigurationSource source) throws ConfigurationException {
+            String resourceBaseString = source.resourceBase();
+            if (StringUtility.isEmpty(resourceBaseString))
+                resourceBaseString = ".";
+            try {
+                configuration.setResourceBase(new File(resourceBaseString));
+            } catch (Exception e) {
+                throw new ConfigurationException(this, resourceBaseString, e);
+            }
+        }
+    },
+
+    TIMEOUT_SECONDS("timeoutSeconds", "Test timeout (seconds)", false, false) {
+        public String getValueString(Configuration configuration) {
+            return String.valueOf(configuration.getTimeoutSeconds());
+        }
+
+        public void configure(Configuration configuration, ConfigurationSource source) throws ConfigurationException {
+            String timeoutSecondsString = source.timeoutSeconds();
+            if (StringUtility.isEmpty(timeoutSecondsString))
+                timeoutSecondsString = "60";
+            try {
+                configuration.setTimeoutSeconds(Integer.parseInt(timeoutSecondsString));
+            } catch (NumberFormatException e) {
+                throw new ConfigurationException(ConfigurationProperty.TIMEOUT_SECONDS, timeoutSecondsString, e);
+            }
+
+        }
+    },
+
+    URL("url", "Test Page URL", true, false) {
+        public String getValueString(Configuration configuration) {
+            URL testURL = configuration.getTestURL();
+            return testURL == null ? "" : testURL.toString();
+        }
+
+        public void configure(Configuration configuration, ConfigurationSource source) throws ConfigurationException {
+            String urlString = source.url();
+            if (StringUtility.isEmpty(urlString))
+                return;
+            try {
+                configuration.setTestURL(new URL(urlString));
+            } catch (MalformedURLException e) {
+                throw new ConfigurationException(this, urlString, e);
+            }
+
+        }
+    };
+
+    private String name;
+    private String displayName;
+    private boolean isURL;
+    private boolean isMultiValued;
+
+    private ConfigurationProperty(String name, String displayName, boolean isURL, boolean isMultiValued) {
+        this.displayName = displayName;
+        this.name = name;
+        this.isURL = isURL;
+        this.isMultiValued = isMultiValued;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public abstract String getValueString(Configuration configuration);
+
+    public void addXmlTo(Element parentElement, Configuration configuration) {
+        Element element = new Element(name);
+        addContentTo(configuration, element);
+        parentElement.addContent(element);
+    }
+
+    protected void addContentTo(Configuration configuration, Element element) {
+        element.setText(getValueString(configuration));
+    }
+
+    public static List<ConfigurationProperty> all() {
+        List<ConfigurationProperty> result = Arrays.asList(ConfigurationProperty.values());
+        Collections.sort(result, comparator());
+        return result;
+    }
+
+    public static Comparator<ConfigurationProperty> comparator() {
+        return new Comparator<ConfigurationProperty>() {
+            public int compare(ConfigurationProperty property1, ConfigurationProperty property2) {
+                return property1.name().compareTo(property2.name());
+            }
+        };
+    }
+
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    public boolean isURL() {
+        return isURL;
+    }
+
+    public List<String> getValueStrings(Configuration configuration) {
+        List<String> result = new ArrayList<String>();
+        if (isMultiValued())
+            for (String value : StringUtility.listFromCommaDelimitedString(getValueString(configuration)))
+                result.add(value);
+        else
+            result.add(getValueString(configuration));
+        return result;
+    }
+
+    private boolean isMultiValued() {
+        return isMultiValued;
+    }
+
+    public abstract void configure(Configuration configuration, ConfigurationSource source) throws ConfigurationException;
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/ConfigurationSource.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/ConfigurationSource.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/ConfigurationSource.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,24 @@
+package net.jsunit.configuration;
+
+public interface ConfigurationSource {
+
+    String browserFileNames();
+
+    String closeBrowsersAfterTestRuns();
+
+    String description();
+
+    String logsDirectory();
+
+    String port();
+
+    String remoteMachineURLs();
+
+    String resourceBase();
+
+    String timeoutSeconds();
+
+    String url();
+
+    String ignoreUnresponsiveRemoteMachines();
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/DelegatingConfigurationSource.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/DelegatingConfigurationSource.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/DelegatingConfigurationSource.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,49 @@
+package net.jsunit.configuration;
+
+public class DelegatingConfigurationSource implements ConfigurationSource {
+    private ConfigurationSource source;
+
+    public DelegatingConfigurationSource(ConfigurationSource source) {
+        this.source = source;
+    }
+
+    public String browserFileNames() {
+        return source.browserFileNames();
+    }
+
+    public String closeBrowsersAfterTestRuns() {
+        return source.closeBrowsersAfterTestRuns();
+    }
+
+    public String description() {
+        return source.description();
+    }
+
+    public String logsDirectory() {
+        return source.logsDirectory();
+    }
+
+    public String port() {
+        return source.port();
+    }
+
+    public String remoteMachineURLs() {
+        return source.remoteMachineURLs();
+    }
+
+    public String resourceBase() {
+        return source.resourceBase();
+    }
+
+    public String timeoutSeconds() {
+        return source.timeoutSeconds();
+    }
+
+    public String url() {
+        return source.url();
+    }
+
+    public String ignoreUnresponsiveRemoteMachines() {
+        return source.ignoreUnresponsiveRemoteMachines();
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/EnvironmentVariablesConfigurationSource.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/EnvironmentVariablesConfigurationSource.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/EnvironmentVariablesConfigurationSource.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,49 @@
+package net.jsunit.configuration;
+
+public class EnvironmentVariablesConfigurationSource implements ConfigurationSource {
+
+    private String environmentVariableValue(ConfigurationProperty property) {
+        return System.getProperty(property.getName());
+    }
+
+    public String resourceBase() {
+        return environmentVariableValue(ConfigurationProperty.RESOURCE_BASE);
+    }
+
+    public String port() {
+        return environmentVariableValue(ConfigurationProperty.PORT);
+    }
+
+    public String remoteMachineURLs() {
+        return environmentVariableValue(ConfigurationProperty.REMOTE_MACHINE_URLS);
+    }
+
+    public String logsDirectory() {
+        return environmentVariableValue(ConfigurationProperty.LOGS_DIRECTORY);
+    }
+
+    public String browserFileNames() {
+        return environmentVariableValue(ConfigurationProperty.BROWSER_FILE_NAMES);
+    }
+
+    public String url() {
+        return environmentVariableValue(ConfigurationProperty.URL);
+    }
+
+    public String closeBrowsersAfterTestRuns() {
+        return environmentVariableValue(ConfigurationProperty.CLOSE_BROWSERS_AFTER_TEST_RUNS);
+    }
+
+    public String description() {
+        return environmentVariableValue(ConfigurationProperty.DESCRIPTION);
+    }
+
+    public String timeoutSeconds() {
+        return environmentVariableValue(ConfigurationProperty.TIMEOUT_SECONDS);
+    }
+
+    public String ignoreUnresponsiveRemoteMachines() {
+        return environmentVariableValue(ConfigurationProperty.IGNORE_UNRESPONSIVE_REMOTE_MACHINES);
+    }
+
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/FarmConfiguration.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/FarmConfiguration.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/FarmConfiguration.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,31 @@
+package net.jsunit.configuration;
+
+import net.jsunit.utility.StringUtility;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+public class FarmConfiguration {
+
+    private final FarmConfigurationSource source;
+
+    public FarmConfiguration(FarmConfigurationSource source) {
+        this.source = source;
+    }
+
+    public List<URL> getRemoteMachineURLs() {
+        String remoteMachineURLs = source.remoteMachineURLs();
+        List<String> strings = StringUtility.listFromCommaDelimitedString(remoteMachineURLs);
+        List<URL> result = new ArrayList<URL>(strings.size());
+        for (String string : strings)
+            try {
+                result.add(new URL(string));
+            } catch (MalformedURLException e) {
+                throw new ConfigurationException(ConfigurationProperty.REMOTE_MACHINE_URLS, remoteMachineURLs, e);
+            }
+        return result;
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/FarmConfigurationSource.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/FarmConfigurationSource.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/FarmConfigurationSource.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,15 @@
+package net.jsunit.configuration;
+
+public interface FarmConfigurationSource {
+
+    String port();
+
+    String logsDirectory();
+
+    String logStatus();
+
+    String timeoutSeconds();
+
+    String remoteMachineURLs();
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/PropertiesFileConfigurationSource.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/PropertiesFileConfigurationSource.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/PropertiesFileConfigurationSource.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,80 @@
+package net.jsunit.configuration;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.util.Properties;
+
+public class PropertiesFileConfigurationSource implements ConfigurationSource {
+
+    public static final String PROPERTIES_FILE_NAME = "jsunit.properties";
+
+    private Properties properties;
+    private String propertiesFileName;
+
+    public PropertiesFileConfigurationSource(String propertiesFileName) throws FileNotFoundException {
+        this.propertiesFileName = propertiesFileName;
+        loadProperties();
+    }
+
+    public PropertiesFileConfigurationSource() throws FileNotFoundException {
+        this(PROPERTIES_FILE_NAME);
+    }
+
+    private void loadProperties() throws FileNotFoundException {
+        properties = new Properties();
+        try {
+            FileInputStream fileInputStream = new FileInputStream(propertiesFileName);
+            properties.load(fileInputStream);
+            fileInputStream.close();
+        } catch (FileNotFoundException e) {
+            throw e;
+        } catch (Throwable t) {
+            throw new RuntimeException(t);
+        }
+    }
+
+    private String propertyValue(ConfigurationProperty property) {
+        return properties.getProperty(property.getName());
+    }
+
+    public String resourceBase() {
+        return propertyValue(ConfigurationProperty.RESOURCE_BASE);
+    }
+
+    public String logsDirectory() {
+        return propertyValue(ConfigurationProperty.LOGS_DIRECTORY);
+    }
+
+    public String port() {
+        return propertyValue(ConfigurationProperty.PORT);
+    }
+
+    public String remoteMachineURLs() {
+        return propertyValue(ConfigurationProperty.REMOTE_MACHINE_URLS);
+    }
+
+    public String url() {
+        return propertyValue(ConfigurationProperty.URL);
+    }
+
+    public String ignoreUnresponsiveRemoteMachines() {
+        return propertyValue(ConfigurationProperty.IGNORE_UNRESPONSIVE_REMOTE_MACHINES);
+    }
+
+    public String browserFileNames() {
+        return propertyValue(ConfigurationProperty.BROWSER_FILE_NAMES);
+    }
+
+    public String closeBrowsersAfterTestRuns() {
+        return propertyValue(ConfigurationProperty.CLOSE_BROWSERS_AFTER_TEST_RUNS);
+    }
+
+    public String description() {
+        return propertyValue(ConfigurationProperty.DESCRIPTION);
+    }
+
+    public String timeoutSeconds() {
+        return propertyValue(ConfigurationProperty.TIMEOUT_SECONDS);
+    }
+
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/ServerType.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/ServerType.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/configuration/ServerType.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,129 @@
+package net.jsunit.configuration;
+
+import net.jsunit.utility.StringUtility;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public enum ServerType {
+    STANDARD(
+            "Standard",
+            false,
+            true,
+            false,
+            Arrays.asList(new ConfigurationProperty[]{
+                    ConfigurationProperty.CLOSE_BROWSERS_AFTER_TEST_RUNS,
+                    ConfigurationProperty.LOGS_DIRECTORY,
+                    ConfigurationProperty.PORT,
+                    ConfigurationProperty.RESOURCE_BASE,
+                    ConfigurationProperty.TIMEOUT_SECONDS,
+            }),
+            Arrays.asList(new ConfigurationProperty[]{
+                    ConfigurationProperty.BROWSER_FILE_NAMES,
+                    ConfigurationProperty.DESCRIPTION,
+                    ConfigurationProperty.URL,
+            })
+    ),
+    STANDARD_TEMPORARY(
+            "Standard Temporary",
+            STANDARD.isFarm(),
+            false,
+            true,
+            STANDARD.getRequiredConfigurationProperties(),
+            STANDARD.getOptionalConfigurationProperties()
+    ),
+    FARM(
+            "Farm",
+            true,
+            true,
+            false,
+            Arrays.asList(new ConfigurationProperty[]{
+                    ConfigurationProperty.LOGS_DIRECTORY,
+                    ConfigurationProperty.PORT,
+                    ConfigurationProperty.REMOTE_MACHINE_URLS,
+                    ConfigurationProperty.IGNORE_UNRESPONSIVE_REMOTE_MACHINES,
+            }),
+            Arrays.asList(new ConfigurationProperty []{
+                    ConfigurationProperty.DESCRIPTION,
+                    ConfigurationProperty.RESOURCE_BASE,
+                    ConfigurationProperty.URL,
+            })
+    );
+
+    private List<ConfigurationProperty> requiredProperties;
+    private List<ConfigurationProperty> optionalProperties;
+    private String displayName;
+    private boolean isFarm;
+    private boolean performUpToDateCheck;
+	private boolean isTemporary;
+
+    private ServerType(
+            String displayName,
+            boolean isFarm,
+            boolean performVersionUpToDateCheck,
+            boolean isTemporary,
+            List<ConfigurationProperty> required,
+            List<ConfigurationProperty> optional) {
+        this.performUpToDateCheck = performVersionUpToDateCheck;
+        this.displayName = displayName;
+        this.isFarm = isFarm;
+        this.isTemporary = isTemporary;
+        this.requiredProperties = required;
+        this.optionalProperties = optional;
+    }
+
+    public List<ConfigurationProperty> getRequiredConfigurationProperties() {
+        return requiredProperties;
+    }
+
+    public List<ConfigurationProperty> getOptionalConfigurationProperties() {
+        return optionalProperties;
+    }
+
+    public List<ConfigurationProperty> getPropertiesInvalidFor(Configuration configuration) {
+        List<ConfigurationProperty> result = new ArrayList<ConfigurationProperty>();
+
+        for (ConfigurationProperty property : getRequiredAndOptionalConfigurationProperties()) {
+            try {
+                String valueString = property.getValueString(configuration);
+                if (isPropertyRequired(property) && StringUtility.isEmpty(valueString))
+                    result.add(property);
+            } catch (ConfigurationException e) {
+                result.add(property);
+            }
+        }
+
+        return result;
+
+    }
+
+    private boolean isPropertyRequired(ConfigurationProperty property) {
+        return getRequiredConfigurationProperties().contains(property);
+    }
+
+    public List<ConfigurationProperty> getRequiredAndOptionalConfigurationProperties() {
+        List<ConfigurationProperty> result = new ArrayList<ConfigurationProperty>();
+        result.addAll(getRequiredConfigurationProperties());
+        result.addAll(getOptionalConfigurationProperties());
+        Collections.sort(result, ConfigurationProperty.comparator());
+        return result;
+    }
+
+    public boolean isFarm() {
+        return isFarm;
+    }
+
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    public boolean shouldPerformUpToDateCheck() {
+        return performUpToDateCheck;
+    }
+
+	public boolean isTemporary() {
+		return isTemporary;
+	}
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/logging/BrowserResultRepository.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/logging/BrowserResultRepository.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/logging/BrowserResultRepository.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,12 @@
+package net.jsunit.logging;
+
+import net.jsunit.model.Browser;
+import net.jsunit.model.BrowserResult;
+
+public interface BrowserResultRepository {
+
+    void store(BrowserResult result);
+
+    BrowserResult retrieve(String id, Browser browser);
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/logging/FileBrowserResultRepository.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/logging/FileBrowserResultRepository.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/logging/FileBrowserResultRepository.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,49 @@
+package net.jsunit.logging;
+
+import net.jsunit.model.Browser;
+import net.jsunit.model.BrowserResult;
+import net.jsunit.model.BrowserResultBuilder;
+import net.jsunit.model.BrowserSource;
+import net.jsunit.utility.FileUtility;
+import net.jsunit.utility.XmlUtility;
+
+import java.io.File;
+
+public class FileBrowserResultRepository implements BrowserResultRepository {
+
+    private static final String LOG_PREFIX = "JSTEST-";
+
+    private File logsDirectory;
+
+    public FileBrowserResultRepository(File logsDirectory) {
+        this.logsDirectory = logsDirectory;
+        if (!logsDirectory.exists())
+            logsDirectory.mkdir();
+    }
+
+    private File logFileForId(String id, Browser browser) {
+        return new File(logsDirectory + File.separator + LOG_PREFIX + id + "." + browser.getId() + ".xml");
+    }
+
+    public void deleteDirectory(String directoryName) {
+        File file = new File(directoryName);
+        file.delete();
+    }
+
+    public void store(BrowserResult result) {
+        String xml = XmlUtility.asString(result.asXml());
+        FileUtility.write(logFileForId(result.getId(), result.getBrowser()), xml);
+    }
+
+    public BrowserResult retrieve(String id, final Browser browser) {
+        File logFile = logFileForId(id, browser);
+        if (logFile.exists())
+            return new BrowserResultBuilder(new BrowserSource() {
+                public Browser getBrowserById(int id) {
+                    return browser;
+                }
+            }).build(logFile);
+        return null;
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/logging/StubBrowserResultRepository.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/logging/StubBrowserResultRepository.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/logging/StubBrowserResultRepository.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,13 @@
+package net.jsunit.logging;
+
+import net.jsunit.model.Browser;
+import net.jsunit.model.BrowserResult;
+
+public class StubBrowserResultRepository implements BrowserResultRepository {
+    public void store(BrowserResult result) {
+    }
+
+    public BrowserResult retrieve(String id, Browser browser) {
+        return null;
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/AbstractResult.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/AbstractResult.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/AbstractResult.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,54 @@
+package net.jsunit.model;
+
+import java.util.List;
+
+public abstract class AbstractResult implements Result {
+
+    public ResultType getResultType() {
+        ResultType worstResultType = ResultType.SUCCESS;
+        for (Result childResult : getChildren()) {
+            ResultType childResultType = childResult.getResultType();
+            if (childResultType.isWorseThan(worstResultType))
+                worstResultType = childResultType;
+        }
+        return worstResultType;
+    }
+
+    public int getFailureCount() {
+        int failureCount = 0;
+        for (Result childResult : getChildren())
+            failureCount += childResult.getFailureCount();
+        return failureCount;
+    }
+
+    public int getErrorCount() {
+        int errorCount = 0;
+        for (Result childResult : getChildren())
+            errorCount += childResult.getErrorCount();
+        return errorCount;
+    }
+
+    public int getTestCount() {
+        int result = 0;
+        for (Result childResult : getChildren())
+            result += childResult.getTestCount();
+        return result;
+    }
+
+    public boolean wasSuccessful() {
+        return getResultType() == ResultType.SUCCESS;
+    }
+
+    protected abstract List<? extends Result> getChildren();
+
+    public String displayString() {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("The test run had ");
+        buffer.append(getErrorCount());
+        buffer.append(" error(s) and ");
+        buffer.append(getFailureCount());
+        buffer.append(" failure(s).");
+        return buffer.toString();
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/Browser.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/Browser.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/Browser.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,60 @@
+package net.jsunit.model;
+
+import net.jsunit.utility.StringUtility;
+
+import java.util.List;
+
+public class Browser {
+
+    public static final String DEFAULT_SYSTEM_BROWSER = "default";
+
+    private String fileName;
+    private String killCommand;
+    private int id;
+
+    public Browser(String fullFileName, int id) {
+        this.id = id;
+        List<String> launchAndKill = StringUtility.listFromSemiColonDelimitedString(fullFileName);
+        this.fileName = launchAndKill.size() >= 1 ? launchAndKill.get(0) : null;
+        this.killCommand = launchAndKill.size() >= 2 ? launchAndKill.get(1) : null;
+    }
+
+    public String getFileName() {
+        return fileName;
+    }
+
+    public String getKillCommand() {
+        return killCommand;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public boolean hasId(int anId) {
+        return id == anId;
+    }
+
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        final Browser browser = (Browser) o;
+
+        if (id != browser.id) return false;
+        return !(fileName != null ? !fileName.equals(browser.fileName) : browser.fileName != null);
+
+    }
+
+    public int hashCode() {
+        int result;
+        result = (fileName != null ? fileName.hashCode() : 0);
+        result = 29 * result + id;
+        return result;
+    }
+
+    public boolean isDefault() {
+        return fileName.equals(DEFAULT_SYSTEM_BROWSER);
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/BrowserResult.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/BrowserResult.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/BrowserResult.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,201 @@
+package net.jsunit.model;
+
+import net.jsunit.XmlRenderable;
+import net.jsunit.utility.StringUtility;
+import org.jdom.Document;
+import org.jdom.Element;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BrowserResult extends AbstractResult implements XmlRenderable {
+
+    private Browser browser;
+    private String remoteAddress;
+    private String id;
+    private String jsUnitVersion;
+    private String userAgent;
+    private String baseURL;
+    private double time;
+    private List<TestPageResult> testPageResults = new ArrayList<TestPageResult>();
+    private String serverSideExceptionStackTrace;
+    private ResultType resultType;
+
+    public BrowserResult() {
+        this.id = String.valueOf(System.currentTimeMillis());
+    }
+
+    public Browser getBrowser() {
+        return browser;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        if (id != null)
+            this.id = id;
+    }
+
+    public boolean hasId(String id) {
+        return this.id.equals(id);
+    }
+
+    public String getJsUnitVersion() {
+        return jsUnitVersion;
+    }
+
+    public void setJsUnitVersion(String jsUnitVersion) {
+        this.jsUnitVersion = jsUnitVersion;
+    }
+
+    public String getBaseURL() {
+        return baseURL;
+    }
+
+    public void setBaseURL(String baseURL) {
+        this.baseURL = baseURL;
+    }
+
+    public String getUserAgent() {
+        return userAgent;
+    }
+
+    public void setUserAgent(String userAgent) {
+        this.userAgent = userAgent;
+    }
+
+    public double getTime() {
+        return time;
+    }
+
+    public void setTime(double time) {
+        this.time = time;
+    }
+
+    public List<TestCaseResult> getTestCaseResults() {
+        List<TestCaseResult> result = new ArrayList<TestCaseResult>();
+        for (TestPageResult pageResult : getTestPageResults())
+            result.addAll(pageResult.getTestCaseResults());
+        return result;
+    }
+
+    public void setTestCaseStrings(String[] testCaseResultStrings) {
+        buildTestCaseResults(testCaseResultStrings);
+    }
+
+    public String getRemoteAddress() {
+        return remoteAddress;
+    }
+
+    public void setRemoteAddress(String remoteAddress) {
+        this.remoteAddress = remoteAddress;
+    }
+
+    private void buildTestCaseResults(String[] testCaseResultStrings) {
+        if (testCaseResultStrings == null)
+            return;
+        for (String testCaseResultString : testCaseResultStrings)
+            addTestCaseResult(TestCaseResult.fromString(testCaseResultString));
+    }
+
+    public Element asXml() {
+        return new BrowserResultWriter(this).asXml();
+    }
+
+    public String asXmlFragment() {
+        return new BrowserResultWriter(this).writeXmlFragment();
+    }
+
+    public void addTestCaseResult(TestCaseResult testCaseResult) {
+        String testPageName = testCaseResult.getTestPageName();
+        TestPageResult testPageResult = findTestPageResultForTestPageWithName(testPageName);
+        if (testPageResult == null) {
+            testPageResult = new TestPageResult(testPageName);
+            testPageResults.add(testPageResult);
+        }
+        testPageResult.addTestCaseResult(testCaseResult);
+    }
+
+    private TestPageResult findTestPageResultForTestPageWithName(String testPageName) {
+        for (TestPageResult testPageResult : testPageResults)
+            if (testPageResult.getTestPageName().equals(testPageName))
+                return testPageResult;
+        return null;
+    }
+
+    public ResultType getResultType() {
+        if (resultType == null)
+            return super.getResultType();
+        return resultType;
+    }
+
+    public Document asXmlDocument() {
+        return new Document(asXml());
+    }
+
+    public List<TestPageResult> getTestPageResults() {
+        return testPageResults;
+    }
+
+    public String getDisplayString() {
+        return getResultType().getDisplayString();
+    }
+
+    public boolean completedTestRun() {
+        return getResultType().completedTestRun();
+    }
+
+    public boolean timedOut() {
+        return getResultType().timedOut();
+    }
+
+    public boolean failedToLaunch() {
+        return getResultType().failedToLaunch();
+    }
+
+    public boolean externallyShutDown() {
+        return getResultType().externallyShutDown();
+    }
+
+    public void setServerSideException(Throwable throwable) {
+        serverSideExceptionStackTrace = StringUtility.stackTraceAsString(throwable);
+    }
+
+    public void setFailedToLaunch() {
+        this.resultType = ResultType.FAILED_TO_LAUNCH;
+    }
+
+    public void setTimedOut() {
+        this.resultType = ResultType.TIMED_OUT;
+    }
+
+    public void setExternallyShutDown() {
+        this.resultType = ResultType.EXTERNALLY_SHUT_DOWN;
+    }
+
+    public String getServerSideExceptionStackTrace() {
+        return serverSideExceptionStackTrace;
+    }
+
+    public void setServerSideExceptionStackTrace(String serverSideExceptionStackTrace) {
+        this.serverSideExceptionStackTrace = serverSideExceptionStackTrace;
+    }
+
+    public boolean hasServerSideExceptionStackTrace() {
+        return getServerSideExceptionStackTrace() != null;
+    }
+
+    protected List<? extends Result> getChildren() {
+        return testPageResults;
+    }
+
+    public void setBrowser(Browser browser) {
+        this.browser = browser;
+    }
+
+    public boolean isForBrowser(Browser browser) {
+        return this.browser.equals(browser);
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/BrowserResultBuilder.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/BrowserResultBuilder.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/BrowserResultBuilder.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,118 @@
+package net.jsunit.model;
+
+import net.jsunit.utility.XmlUtility;
+import org.jdom.Attribute;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.input.SAXBuilder;
+
+import java.io.File;
+import java.util.List;
+import java.util.logging.Logger;
+
+public class BrowserResultBuilder {
+
+    private Logger logger = Logger.getLogger("net.jsunit");
+    private BrowserSource browserSource;
+
+    public BrowserResultBuilder(BrowserSource browserSource) {
+        this.browserSource = browserSource;
+    }
+
+    public BrowserResult build(File file) {
+        try {
+            Document document = new SAXBuilder().build(file);
+            return build(document);
+        } catch (Exception e) {
+            logger.severe("Failed to read file " + file + ": " + e.getMessage());
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public BrowserResult build(String string) {
+        Document document = XmlUtility.asXmlDocument(string);
+        return build(document);
+    }
+
+    @SuppressWarnings("unchecked")
+    public BrowserResult build(Document document) {
+        Element root = document.getRootElement();
+        return build(root);
+    }
+
+    @SuppressWarnings("unchecked")
+    public BrowserResult build(Element root) {
+        BrowserResult result = new BrowserResult();
+        if (failedToLaunch(root))
+            result.setFailedToLaunch();
+        else if (timedOut(root))
+            result.setTimedOut();
+        else if (externallyShutDown(root))
+            result.setExternallyShutDown();
+        updateWithHeaders(result, root);
+        updateWithProperties(root.getChild(BrowserResultWriter.PROPERTIES), result);
+        Element testCasesElement = root.getChild(BrowserResultWriter.TEST_CASES);
+        if (testCasesElement != null) {
+            List children = testCasesElement.getChildren(TestCaseResultWriter.TEST_CASE);
+            updateWithTestCaseResults(children, result);
+        }
+        return result;
+    }
+
+    private boolean failedToLaunch(Element root) {
+        Attribute failedToLaunchAttribute = root.getAttribute(BrowserResultWriter.FAILED_TO_LAUNCH);
+        return failedToLaunchAttribute != null && failedToLaunchAttribute.getValue().equals(String.valueOf(true));
+    }
+
+    private boolean timedOut(Element root) {
+        Attribute timedOutAttribute = root.getAttribute(BrowserResultWriter.TIMED_OUT);
+        return timedOutAttribute != null && timedOutAttribute.getValue().equals(String.valueOf(true));
+    }
+
+    private boolean externallyShutDown(Element root) {
+        Attribute externallyShutDownAttribute = root.getAttribute(BrowserResultWriter.EXTERNALLY_SHUT_DOWN);
+        return externallyShutDownAttribute != null && externallyShutDownAttribute.getValue().equals(String.valueOf(true));
+    }
+
+    private void updateWithHeaders(BrowserResult result, Element element) {
+        String id = element.getAttributeValue(BrowserResultWriter.ID);
+        if (id != null)
+            result.setId(id);
+        String time = element.getAttributeValue(BrowserResultWriter.TIME);
+        if (time != null)
+            result.setTime(Double.parseDouble(time));
+    }
+
+    private void updateWithProperties(Element element, BrowserResult result) {
+        for (Object child : element.getChildren()) {
+            Element next = (Element) child;
+            String key = next.getAttributeValue(BrowserResultWriter.PROPERTY_KEY);
+            String value = next.getAttributeValue(BrowserResultWriter.PROPERTY_VALUE);
+
+            if (BrowserResultWriter.JSUNIT_VERSION.equals(key))
+                result.setJsUnitVersion(value);
+            else if (BrowserResultWriter.BROWSER_ID.equals(key)) {
+                int browserId = Integer.valueOf(value);
+                Browser browser = browserSource.getBrowserById(browserId);
+                result.setBrowser(browser);
+            } else if (BrowserResultWriter.USER_AGENT.equals(key))
+                result.setUserAgent(value);
+            else if (BrowserResultWriter.REMOTE_ADDRESS.equals(key))
+                result.setRemoteAddress(value);
+            else if (BrowserResultWriter.URL.equals(key))
+                result.setBaseURL(value);
+            else if (BrowserResultWriter.SERVER_SIDE_EXCEPTION_STACK_TRACE.equals(key)) {
+                String stackTrace = next.getText();
+                result.setServerSideExceptionStackTrace(stackTrace);
+            }
+        }
+    }
+
+    private void updateWithTestCaseResults(List<Element> testCaseElements, BrowserResult result) {
+        TestCaseResultBuilder testCaseBuilder = new TestCaseResultBuilder();
+        for (Element element : testCaseElements) {
+            result.addTestCaseResult(testCaseBuilder.build(element));
+        }
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/BrowserResultWriter.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/BrowserResultWriter.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/BrowserResultWriter.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,122 @@
+package net.jsunit.model;
+
+import org.jdom.CDATA;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.output.XMLOutputter;
+
+public class BrowserResultWriter {
+
+    public static final String
+            ID = "id",
+            BROWSER_RESULT = "browserResult",
+            BROWSER_FILE_NAME = "browserFileName",
+            BROWSER_ID = "browserId",
+            USER_AGENT = "userAgent",
+            TIME = "time",
+            TEST_CASES = "testCases",
+            TEST_CASE = "testCase",
+            TIMED_OUT = "timedOut",
+            FAILED_TO_LAUNCH = "failedToLaunch",
+            EXTERNALLY_SHUT_DOWN = "externallyShutDown",
+            JSUNIT_VERSION = "jsUnitVersion",
+            REMOTE_ADDRESS = "remoteAddress",
+            SERVER_SIDE_EXCEPTION_STACK_TRACE = "serverSideExceptionStackTrace",
+            PROPERTIES = "properties",
+            PROPERTY = "property",
+            PROPERTY_KEY = "name",
+            PROPERTY_VALUE = "value",
+            URL = "url";
+
+    BrowserResult browserResult;
+
+    public BrowserResultWriter(BrowserResult result) {
+        this.browserResult = result;
+    }
+
+    public String writeXml() {
+        Element root = createRootElement();
+        Document document = new Document(root);
+        return new XMLOutputter().outputString(document);
+    }
+
+    public String writeXmlFragment() {
+        return new XMLOutputter().outputString(createRootElement());
+    }
+
+    private Element createRootElement() {
+        Element root = new Element(BROWSER_RESULT);
+        if (browserResult.timedOut())
+            root.setAttribute(TIMED_OUT, String.valueOf(true));
+        if (browserResult.failedToLaunch())
+            root.setAttribute(FAILED_TO_LAUNCH, String.valueOf(true));
+        if (browserResult.externallyShutDown())
+            root.setAttribute(EXTERNALLY_SHUT_DOWN, String.valueOf(true));
+        addPropertiesElementTo(root);
+        if (browserResult.completedTestRun()) {
+            root.setAttribute(ID, browserResult.getId());
+            root.setAttribute(TIME, String.valueOf(browserResult.getTime()));
+            addTestCasesElementTo(root);
+        }
+        return root;
+    }
+
+    private void addPropertiesElementTo(Element element) {
+        Element properties = new Element(PROPERTIES);
+        element.addContent(properties);
+
+        Browser browser = browserResult.getBrowser();
+        if (browser != null) {
+            addProperty(properties, BROWSER_FILE_NAME, browser.getFileName());
+            addProperty(properties, BROWSER_ID, String.valueOf(browserResult.getBrowser().getId()));
+        }
+        if (browserResult.completedTestRun()) {
+            addProperty(properties, JSUNIT_VERSION, browserResult.getJsUnitVersion());
+            addProperty(properties, USER_AGENT, browserResult.getUserAgent());
+            addProperty(properties, REMOTE_ADDRESS, browserResult.getRemoteAddress());
+            addProperty(properties, URL, browserResult.getBaseURL());
+        }
+        if (browserResult.hasServerSideExceptionStackTrace()) {
+            Element stackTrace = createPropertyElement(SERVER_SIDE_EXCEPTION_STACK_TRACE);
+            stackTrace.addContent(new CDATA(browserResult.getServerSideExceptionStackTrace()));
+            properties.addContent(stackTrace);
+        }
+    }
+
+    private void addProperty(Element parent, String name, String value) {
+        Element property = createPropertyElement(name);
+        property.setAttribute(PROPERTY_VALUE, value == null ? "" : value);
+        parent.addContent(property);
+    }
+
+    private Element createPropertyElement(String name) {
+        Element property = new Element(PROPERTY);
+        property.setAttribute(PROPERTY_KEY, name);
+        return property;
+    }
+
+    private void addTestCasesElementTo(Element element) {
+        Element testCasesElement = new Element(TEST_CASES);
+        for (TestCaseResult result : browserResult.getTestCaseResults()) {
+            new TestCaseResultWriter(result).addXmlTo(testCasesElement);
+        }
+        element.addContent(testCasesElement);
+    }
+
+    public String writeProblems() {
+        StringBuffer buffer = new StringBuffer();
+        for (TestCaseResult result : browserResult.getTestCaseResults()) {
+            if (!result.wasSuccessful()) {
+                if (buffer.length() > 0)
+                    buffer.append("\n");
+                String problemMessage = result.getProblemSummary();
+                buffer.append(problemMessage);
+            }
+        }
+        return buffer.toString();
+    }
+
+    public Element asXml() {
+        return createRootElement();
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/BrowserSource.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/BrowserSource.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/BrowserSource.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,6 @@
+package net.jsunit.model;
+
+public interface BrowserSource {
+
+    Browser getBrowserById(int id);
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/DistributedTestRunResult.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/DistributedTestRunResult.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/DistributedTestRunResult.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,37 @@
+package net.jsunit.model;
+
+import net.jsunit.XmlRenderable;
+import org.jdom.Element;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class DistributedTestRunResult extends AbstractResult implements XmlRenderable {
+
+    public static final String NAME = "distributedTestRunResult";
+
+    private List<TestRunResult> testRunResults = new ArrayList<TestRunResult>();
+
+    protected List<? extends Result> getChildren() {
+        return testRunResults;
+    }
+
+    public void addTestRunResult(TestRunResult result) {
+        testRunResults.add(result);
+        Collections.sort(testRunResults);
+    }
+
+    public Element asXml() {
+        Element root = new Element(NAME);
+        root.setAttribute("type", getResultType().name());
+        for (TestRunResult testRunResult : testRunResults)
+            root.addContent(testRunResult.asXml());
+        return root;
+    }
+
+    public List<TestRunResult> getTestRunResults() {
+        return testRunResults;
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/DistributedTestRunResultBuilder.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/DistributedTestRunResultBuilder.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/DistributedTestRunResultBuilder.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,29 @@
+package net.jsunit.model;
+
+import org.jdom.Document;
+import org.jdom.Element;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class DistributedTestRunResultBuilder {
+
+    private BrowserSource browserSource;
+
+    public DistributedTestRunResultBuilder(BrowserSource browserSource) {
+        this.browserSource = browserSource;
+    }
+
+    public DistributedTestRunResult build(Document document) {
+        DistributedTestRunResult result = new DistributedTestRunResult();
+        Element root = document.getRootElement();
+        TestRunResultBuilder individualTestRunResultBuilder = new TestRunResultBuilder(browserSource);
+        for (Element testRunResultElement : new ArrayList<Element>((List<Element>) root.getChildren(TestRunResultBuilder.NAME)))
+        {
+            testRunResultElement.detach();
+            TestRunResult testRunResult = individualTestRunResultBuilder.build(new Document(testRunResultElement));
+            result.addTestRunResult(testRunResult);
+        }
+        return result;
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/Result.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/Result.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/Result.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,17 @@
+package net.jsunit.model;
+
+public interface Result {
+
+    public int getErrorCount();
+
+    public int getFailureCount();
+
+    public int getTestCount();
+
+    public ResultType getResultType();
+
+    public boolean wasSuccessful();
+
+    public String displayString();
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/ResultType.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/ResultType.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/ResultType.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,76 @@
+package net.jsunit.model;
+
+public enum ResultType {
+    UNRESPONSIVE {
+        public String getDisplayString() {
+            return "unresponsive";
+        }
+
+    },
+    FAILED_TO_LAUNCH {
+        public String getDisplayString() {
+            return "failed to launch";
+        }
+
+        public boolean failedToLaunch() {
+            return true;
+        }
+    },
+    TIMED_OUT {
+        public String getDisplayString() {
+            return "timed out";
+        }
+
+        public boolean timedOut() {
+            return true;
+        }
+    },
+    EXTERNALLY_SHUT_DOWN {
+        public String getDisplayString() {
+            return "externally shut down";
+        }
+
+        public boolean externallyShutDown() {
+            return true;
+        }
+
+    },
+    ERROR {
+        public String getDisplayString() {
+            return "error";
+        }
+    },
+    FAILURE {
+        public String getDisplayString() {
+            return "failure";
+        }
+    },
+    SUCCESS {
+        public String getDisplayString() {
+            return "success";
+        }
+    };
+
+    public abstract String getDisplayString();
+
+    public final boolean completedTestRun() {
+        return !timedOut() && !failedToLaunch() && !externallyShutDown();
+    }
+
+    public boolean timedOut() {
+        return false;
+    }
+
+    public boolean failedToLaunch() {
+        return false;
+    }
+
+    public boolean externallyShutDown() {
+        return false;
+    }
+
+    public boolean isWorseThan(ResultType other) {
+        return ordinal() < other.ordinal();
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/TestCaseResult.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/TestCaseResult.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/TestCaseResult.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,147 @@
+package net.jsunit.model;
+
+import org.jdom.Element;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+
+public class TestCaseResult extends AbstractResult {
+
+    public static final String TEST_PAGE_TEST_NAME_DELIMITER = ":";
+    public static final String DELIMITER = "|";
+    public static final String ERROR_INDICATOR = "E";
+    public static final String FAILURE_INDICATOR = "F";
+    private String testPageName;
+    private String name;
+    private double time;
+    private String failure, error;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getError() {
+        return error;
+    }
+
+    public void setError(String error) {
+        this.error = error;
+    }
+
+    public String getFailure() {
+        return failure;
+    }
+
+    public void setFailure(String failure) {
+        this.failure = failure;
+    }
+
+    public double getTime() {
+        return time;
+    }
+
+    public void setTimeTaken(double time) {
+        this.time = time;
+    }
+
+    public boolean hadError() {
+        return error != null;
+    }
+
+    public boolean hadFailure() {
+        return failure != null;
+    }
+
+    public static TestCaseResult fromString(String string) {
+        TestCaseResult result = new TestCaseResult();
+        StringTokenizer toker = new StringTokenizer(string, DELIMITER);
+        try {
+            String fullyQualifiedName;
+            try {
+                fullyQualifiedName = URLDecoder.decode(toker.nextToken(), "UTF-8");
+            } catch (UnsupportedEncodingException e) {
+                throw new RuntimeException(e);
+            }
+            result.setFullyQualifiedName(fullyQualifiedName);
+            result.setTimeTaken(Double.parseDouble(toker.nextToken()));
+            String successString = toker.nextToken();
+            if (successString.equals(ERROR_INDICATOR))
+                result.setError(toker.nextToken());
+            else if (successString.equals(FAILURE_INDICATOR))
+                result.setFailure(toker.nextToken());
+        } catch (NoSuchElementException ex) {
+            result.setError("Malformed test result: '" + string + "'.");
+        }
+        return result;
+    }
+
+    public void setFullyQualifiedName(String fullyQualifiedName) {
+        int colonIndex = fullyQualifiedName.lastIndexOf(TEST_PAGE_TEST_NAME_DELIMITER);
+        setTestPageName(fullyQualifiedName.substring(0, colonIndex));
+        setName(fullyQualifiedName.substring(colonIndex + 1));
+    }
+
+    public static TestCaseResult fromXmlElement(Element testCaseElement) {
+        return new TestCaseResultBuilder().build(testCaseElement);
+    }
+
+    public String getXmlFragment() {
+        return new TestCaseResultWriter(this).getXmlFragment();
+    }
+
+    public String getProblemSummary() {
+        return new TestCaseResultWriter(this).getProblemSummary();
+    }
+
+    public void setTestPageName(String testPageName) {
+        this.testPageName = testPageName;
+    }
+
+    public String getFullyQualifiedName() {
+        return testPageName + TEST_PAGE_TEST_NAME_DELIMITER + name;
+    }
+
+    public String getTestPageName() {
+        return testPageName;
+    }
+
+    public String toString() {
+        return getFullyQualifiedName() + ": " + getResultType().getDisplayString();
+    }
+
+    public int getErrorCount() {
+        return hadError() ? 1 : 0;
+    }
+
+    public int getFailureCount() {
+        return hadFailure() ? 1 : 0;
+    }
+
+    public int getTestCount() {
+        return 1;
+    }
+
+    protected List<? extends Result> getChildren() {
+        return null;
+    }
+
+    public boolean wasSuccessful() {
+        return !hadError() && !hadFailure();
+    }
+
+    public ResultType getResultType() {
+        if (hadError())
+            return ResultType.ERROR;
+        if (hadFailure())
+            return ResultType.FAILURE;
+        return ResultType.SUCCESS;
+    }
+
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/TestCaseResultBuilder.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/TestCaseResultBuilder.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/TestCaseResultBuilder.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,32 @@
+package net.jsunit.model;
+
+import org.jdom.Element;
+
+public class TestCaseResultBuilder {
+
+    public TestCaseResult build(Element element) {
+        TestCaseResult result = new TestCaseResult();
+        updateWithHeaders(result, element);
+        updateWithMessage(result, element);
+        return result;
+    }
+
+    private void updateWithHeaders(TestCaseResult result, Element element) {
+        String fullyQualifiedName = element.getAttributeValue(TestCaseResultWriter.NAME);
+        result.setFullyQualifiedName(fullyQualifiedName);
+        result.setTimeTaken(Double.parseDouble(element.getAttributeValue(TestCaseResultWriter.TIME)));
+    }
+
+    private void updateWithMessage(TestCaseResult result, Element element) {
+        for (Object object : element.getChildren()) {
+            Element next = (Element) object;
+            String type = next.getName();
+            String message = next.getText();
+            if (TestCaseResultWriter.FAILURE.equals(type))
+                result.setFailure(message);
+            else if (TestCaseResultWriter.ERROR.equals(type))
+                result.setError(message);
+        }
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/TestCaseResultWriter.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/TestCaseResultWriter.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/TestCaseResultWriter.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,64 @@
+package net.jsunit.model;
+
+import org.jdom.Element;
+import org.jdom.output.XMLOutputter;
+
+public class TestCaseResultWriter {
+    public static final String
+            TEST_CASE = "testCase",
+            NAME = "name",
+            TIME = "time",
+            FAILURE = "failure",
+            ERROR = "error",
+            MESSAGE = "message";
+
+    private TestCaseResult result;
+
+    public TestCaseResultWriter(TestCaseResult result) {
+        this.result = result;
+    }
+
+    public void addXmlTo(Element element) {
+        element.addContent(createTestCaseElement());
+    }
+
+    public Element createTestCaseElement() {
+        Element testCaseElement = new Element(TEST_CASE);
+        try {
+            testCaseElement.setAttribute(NAME, result.getFullyQualifiedName().replace('\u0000', ' '));
+        } catch (Exception ex) {
+            ex.printStackTrace();
+        }
+        testCaseElement.setAttribute(TIME, String.valueOf(result.getTime()));
+        if (result.hadFailure()) {
+            Element failureElement = new Element(FAILURE);
+            try {
+                failureElement.setText(result.getFailure().replace('\u0000', ' '));
+            } catch (Exception ex) {
+                ex.printStackTrace();
+            }
+            testCaseElement.addContent(failureElement);
+        } else if (result.hadError()) {
+            Element errorElement = new Element(ERROR);
+            try {
+                errorElement.setText(result.getError().replace('\u0000', ' '));
+            } catch (Exception ex) {
+                ex.printStackTrace();
+            }
+            testCaseElement.addContent(errorElement);
+        }
+        return testCaseElement;
+    }
+
+    public String getProblemSummary() {
+        if (result.hadFailure())
+            return result.getFullyQualifiedName() + " failed:\n" + result.getFailure();
+        else if (result.hadError())
+            return result.getFullyQualifiedName() + " had an error:\n" + result.getError();
+        return null;
+    }
+
+    public String getXmlFragment() {
+        return new XMLOutputter().outputString(createTestCaseElement());
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/TestPageResult.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/TestPageResult.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/TestPageResult.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,31 @@
+package net.jsunit.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestPageResult extends AbstractResult {
+
+    private final String testPageName;
+    private List<TestCaseResult> testCaseResults = new ArrayList<TestCaseResult>();
+
+    public TestPageResult(String testPageName) {
+        this.testPageName = testPageName;
+    }
+
+    public void addTestCaseResult(TestCaseResult testCaseResult) {
+        testCaseResults.add(testCaseResult);
+    }
+
+    public String getTestPageName() {
+        return testPageName;
+    }
+
+    public List<TestCaseResult> getTestCaseResults() {
+        return testCaseResults;
+    }
+
+    protected List<? extends Result> getChildren() {
+        return testCaseResults;
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/TestRunResult.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/TestRunResult.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/TestRunResult.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,129 @@
+package net.jsunit.model;
+
+import net.jsunit.XmlRenderable;
+import net.jsunit.utility.SystemUtility;
+import org.jdom.Element;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestRunResult extends AbstractResult implements XmlRenderable, Comparable<TestRunResult> {
+
+    private List<BrowserResult> browserResults = new ArrayList<BrowserResult>();
+    private URL url;
+    private String osString;
+    private String ipAddress;
+    private String hostname;
+    private boolean unresponsive = false;
+
+    public TestRunResult() {
+        this(null);
+    }
+
+    public TestRunResult(URL url) {
+        this.url = url;
+    }
+
+    public void addBrowserResult(BrowserResult browserResult) {
+        browserResults.add(browserResult);
+    }
+
+    public Element asXml() {
+        Element root = new Element("testRunResult");
+        root.setAttribute("type", getResultType().name());
+        if (url != null)
+            root.setAttribute("url", url.toString());
+        if (hasProperties()) {
+            Element properties = new Element("properties");
+            addProperties(properties);
+            root.addContent(properties);
+        }
+        for (BrowserResult browserResult : browserResults)
+            root.addContent(browserResult.asXml());
+        return root;
+    }
+
+    private boolean hasProperties() {
+        return osString != null || ipAddress != null || hostname != null;
+    }
+
+    private void addProperties(Element element) {
+        if (osString != null)
+            addProperty(element, "os", osString);
+        if (ipAddress != null)
+            addProperty(element, "ipAddress", ipAddress);
+        if (hostname != null)
+            addProperty(element, "hostname", hostname);
+    }
+
+    private void addProperty(Element element, String name, String value) {
+        Element property = new Element("property");
+        property.setAttribute("name", name);
+        property.setAttribute("value", value);
+        element.addContent(property);
+    }
+
+    protected List<? extends Result> getChildren() {
+        return browserResults;
+    }
+
+    public void setUnresponsive() {
+        unresponsive = true;
+    }
+
+    public boolean wasUnresponsive() {
+        return unresponsive;
+    }
+
+    public URL getUrl() {
+        return url;
+    }
+
+    public ResultType getResultType() {
+        if (unresponsive)
+            return ResultType.UNRESPONSIVE;
+        else
+            return super.getResultType();
+    }
+
+    public void setOsString(String osString) {
+        this.osString = osString;
+    }
+
+    public void setIpAddress(String ipAddress) {
+        this.ipAddress = ipAddress;
+    }
+
+    public void setHostname(String hostname) {
+        this.hostname = hostname;
+    }
+
+    public void setURL(URL url) {
+        this.url = url;
+    }
+
+    public String getOsString() {
+        return osString;
+    }
+
+    public String getIpAddress() {
+        return ipAddress;
+    }
+
+    public String getHostname() {
+        return hostname;
+    }
+
+    public int compareTo(TestRunResult other) {
+        if (url == null | other.getUrl() == null)
+            return 0;
+        return url.toString().compareTo(other.getUrl().toString());
+    }
+
+    public void initializeProperties() {
+        setOsString(SystemUtility.osString());
+        setHostname(SystemUtility.hostname());
+        setIpAddress(SystemUtility.ipAddress());
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/TestRunResultBuilder.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/TestRunResultBuilder.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/model/TestRunResultBuilder.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,50 @@
+package net.jsunit.model;
+
+import org.jdom.Document;
+import org.jdom.Element;
+
+import java.util.List;
+
+ at SuppressWarnings({"unchecked"})
+public class TestRunResultBuilder {
+
+    public static final String NAME = "testRunResult";
+
+    private BrowserSource browserSource;
+
+    public TestRunResultBuilder(BrowserSource browserSource) {
+        this.browserSource = browserSource;
+    }
+
+    public TestRunResult build(Document document) {
+        TestRunResult result = new TestRunResult();
+        Element propertiesElement = document.getRootElement().getChild("properties");
+        if (propertiesElement != null)
+            updateWithProperties(result, propertiesElement.getChildren());
+        updateWithBrowserResults(document, result);
+        return result;
+    }
+
+    private void updateWithBrowserResults(Document document, TestRunResult result) {
+        BrowserResultBuilder browserBuilder = new BrowserResultBuilder(browserSource);
+        List<Element> children = document.getRootElement().getChildren("browserResult");
+        for (Element element : children) {
+            BrowserResult browserResult = browserBuilder.build(element);
+            result.addBrowserResult(browserResult);
+        }
+    }
+
+    private void updateWithProperties(TestRunResult result, List<Element> properties) {
+        for (Element propertyElement : properties) {
+            String name = propertyElement.getAttribute("name").getValue();
+            String value = propertyElement.getAttribute("value").getValue();
+            if (name.equals("os"))
+                result.setOsString(value);
+            else if (name.equals("ipAddress"))
+                result.setIpAddress(value);
+            else if (name.equals("hostname"))
+                result.setHostname(value);
+        }
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/utility/CollectionUtility.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/utility/CollectionUtility.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/utility/CollectionUtility.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,12 @@
+package net.jsunit.utility;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class CollectionUtility {
+
+    public static List listWith(Object object1, Object object2) {
+        return Arrays.asList(new Object[]{object1, object2});
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/utility/FileUtility.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/utility/FileUtility.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/utility/FileUtility.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,25 @@
+package net.jsunit.utility;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+
+public class FileUtility {
+
+    public static void delete(File file) {
+        if (file.exists())
+            file.delete();
+    }
+
+    public static void write(File file, String contents) {
+        try {
+            if (file.exists())
+                file.delete();
+            BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
+            out.write(contents.getBytes());
+            out.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/utility/StreamUtility.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/utility/StreamUtility.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/utility/StreamUtility.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,18 @@
+package net.jsunit.utility;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class StreamUtility {
+
+    public static String readAllFromStream(InputStream inputStream) throws IOException {
+        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+        int aByte;
+        while ((aByte = inputStream.read()) != -1)
+            outStream.write(aByte);
+        inputStream.close();
+        return outStream.toString();
+
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/utility/StringUtility.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/utility/StringUtility.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/utility/StringUtility.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,59 @@
+package net.jsunit.utility;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+public class StringUtility {
+
+    public static boolean isEmpty(String s) {
+        return s == null || s.trim().equals("");
+    }
+
+    public static List<String> listFromCommaDelimitedString(String string) {
+        return listFromDelimitedString(string, ",");
+    }
+
+    public static List<String> listFromSemiColonDelimitedString(String string) {
+        return listFromDelimitedString(string, ";");
+    }
+
+    private static List<String> listFromDelimitedString(String string, String delimiter) {
+        if (isEmpty(string))
+            return new ArrayList<String>();
+        String[] array = string.split(delimiter);
+        for (int i = 0; i < array.length; i++)
+            array[i] = array[i].trim();
+        return Arrays.asList(array);
+    }
+
+    public static String stackTraceAsString(Throwable throwable) {
+        StringWriter writer = new StringWriter();
+        throwable.printStackTrace(new PrintWriter(writer));
+        return writer.toString();
+    }
+
+    public static String commaSeparatedString(List<? extends Object> strings) {
+        StringBuffer result = new StringBuffer();
+        for (Iterator it = strings.iterator(); it.hasNext();) {
+            result.append(it.next());
+            if (it.hasNext())
+                result.append(",");
+        }
+        return result.toString();
+    }
+
+    public static String unqualify(String string) {
+        int indexOfForwardSlash = string.lastIndexOf("/");
+        if (indexOfForwardSlash >= 0 && indexOfForwardSlash < string.length())
+            string = string.substring(indexOfForwardSlash + 1);
+        int indexOfBackSlash = string.lastIndexOf("\\");
+        if (indexOfBackSlash >= 0 && indexOfBackSlash < string.length())
+            string = string.substring(indexOfBackSlash + 1);
+        return string;
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/utility/SystemUtility.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/utility/SystemUtility.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/utility/SystemUtility.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,53 @@
+package net.jsunit.utility;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+public class SystemUtility {
+    private static String hostname;
+
+    public static String osArchitecture() {
+        return System.getProperty("os.arch");
+    }
+
+    public static String osName() {
+        return System.getProperty("os.name");
+    }
+
+    public static String osString() {
+        StringBuffer result = new StringBuffer();
+        result.append(osArchitecture());
+        result.append(" - ");
+        result.append(osName());
+        return result.toString();
+    }
+
+    public static double jsUnitVersion() {
+        //TODO: get this from jsUnitCore.js
+        return 2.2;
+    }
+
+    public static String hostname() {
+        if (hostname == null) {
+            try {
+                InetAddress addr = InetAddress.getLocalHost();
+                hostname = addr.getCanonicalHostName();
+            } catch (UnknownHostException e) {
+            }
+        }
+        return hostname;
+    }
+
+    public static String ipAddress() {
+        try {
+            InetAddress addr = InetAddress.getLocalHost();
+            return addr.getHostAddress();
+        } catch (UnknownHostException e) {
+            return null;
+        }
+    }
+
+    public static String displayString() {
+        return hostname() + " (" + ipAddress() + "), " + osString();
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/utility/XmlUtility.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/utility/XmlUtility.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/utility/XmlUtility.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,33 @@
+package net.jsunit.utility;
+
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.input.SAXBuilder;
+import org.jdom.output.Format;
+import org.jdom.output.XMLOutputter;
+
+import java.io.StringReader;
+
+public class XmlUtility {
+
+    public static String asString(Element element) {
+        return new XMLOutputter().outputString(element);
+    }
+
+    public static String asPrettyString(Element element) {
+        return new XMLOutputter(Format.getPrettyFormat()).outputString(element);
+    }
+
+    public static String asString(Document document) {
+        return new XMLOutputter().outputString(document);
+    }
+
+    public static Document asXmlDocument(String xmlDocumentString) {
+        try {
+            return new SAXBuilder().build(new StringReader(xmlDocumentString));
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/version/JsUnitWebsiteVersionGrabber.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/version/JsUnitWebsiteVersionGrabber.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/version/JsUnitWebsiteVersionGrabber.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,14 @@
+package net.jsunit.version;
+
+import net.jsunit.utility.StreamUtility;
+
+import java.net.URL;
+
+public class JsUnitWebsiteVersionGrabber implements VersionGrabber {
+
+    public double grabVersion() throws Exception {
+        URL url = new URL("http://www.jsunit.net/version.txt");
+        String string = StreamUtility.readAllFromStream(url.openStream());
+        return Double.parseDouble(string);
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/version/VersionChecker.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/version/VersionChecker.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/version/VersionChecker.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,49 @@
+package net.jsunit.version;
+
+import net.jsunit.utility.SystemUtility;
+
+public class VersionChecker {
+
+    private double installedVersion;
+    private Double latestVersion;
+    private VersionGrabber grabber;
+
+    public static VersionChecker forDefault() {
+        return new VersionChecker(SystemUtility.jsUnitVersion(), new JsUnitWebsiteVersionGrabber());
+    }
+
+    public VersionChecker(double currentVersion, VersionGrabber grabber) {
+        this.installedVersion = currentVersion;
+        this.grabber = grabber;
+    }
+
+    public boolean isUpToDate() {
+        return installedVersion >= getLatestVersion();
+    }
+
+    public double getLatestVersion() {
+        if (latestVersion == null) {
+            try {
+                latestVersion = grabber.grabVersion();
+            } catch (Exception e) {
+                latestVersion = 0d;
+            }
+        }
+        return latestVersion;
+    }
+
+    public void setLatestVersion(double version) {
+        latestVersion = version;
+    }
+
+    public String outOfDateString() {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("*** Your JsUnit version (");
+        buffer.append(installedVersion);
+        buffer.append(") is out of date.  There is a newer version available (");
+        buffer.append(getLatestVersion());
+        buffer.append(") at http://www.jsunit.net ***");
+        return buffer.toString();
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/version/VersionGrabber.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/version/VersionGrabber.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_core/net/jsunit/version/VersionGrabber.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,5 @@
+package net.jsunit.version;
+
+public interface VersionGrabber {
+    double grabVersion() throws Exception;
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/AbstractJsUnitServer.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/AbstractJsUnitServer.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/AbstractJsUnitServer.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,163 @@
+package net.jsunit;
+
+import com.opensymphony.webwork.dispatcher.ServletDispatcher;
+import com.opensymphony.xwork.config.ConfigurationManager;
+import com.opensymphony.xwork.config.providers.XmlConfigurationProvider;
+import net.jsunit.configuration.Configuration;
+import net.jsunit.configuration.ConfigurationException;
+import net.jsunit.configuration.ConfigurationProperty;
+import net.jsunit.configuration.ServerType;
+import net.jsunit.utility.XmlUtility;
+import net.jsunit.version.VersionChecker;
+import org.apache.jasper.servlet.JspServlet;
+import org.jdom.Element;
+import org.mortbay.http.HttpServer;
+import org.mortbay.http.SocketListener;
+import org.mortbay.http.handler.ResourceHandler;
+import org.mortbay.jetty.servlet.ServletHttpContext;
+import org.mortbay.start.Monitor;
+
+import java.util.Date;
+import java.util.List;
+import java.util.logging.Logger;
+
+public abstract class AbstractJsUnitServer implements JsUnitServer {
+
+    private HttpServer server;
+    private Logger logger = Logger.getLogger("net.jsunit");
+    protected Configuration configuration;
+    private final ServerType serverType;
+    private Date startDate;
+    protected int testRunCount = 0;
+
+    protected AbstractJsUnitServer(Configuration configuration, ServerType type) {
+        this.configuration = configuration;
+        this.serverType = type;
+        ensureConfigurationIsValid();
+    }
+
+    protected void ensureConfigurationIsValid() {
+        if (!configuration.isValidFor(serverType)) {
+            ConfigurationProperty property = serverType.getPropertiesInvalidFor(configuration).get(0);
+            throw new ConfigurationException(property, property.getValueString(configuration));
+        }
+    }
+
+    public boolean isFarmServer() {
+        return serverType.isFarm();
+    }
+
+    public boolean isTemporary() {
+        return serverType.isTemporary();
+    }
+
+    public Configuration getConfiguration() {
+        return configuration;
+    }
+
+    public void start() throws Exception {
+        setUpHttpServer();
+        logStatus(startingServerStatusMessage());
+        server.start();
+        startDate = new Date();
+        if (serverType.shouldPerformUpToDateCheck())
+            performUpToDateCheck();
+    }
+
+    private void performUpToDateCheck() {
+        VersionChecker checker = VersionChecker.forDefault();
+        if (!checker.isUpToDate())
+            logger.warning(checker.outOfDateString());
+    }
+
+    private String startingServerStatusMessage() {
+        return "Starting " +
+                serverTypeName() +
+                " Server with configuration:\r\n" +
+                XmlUtility.asPrettyString(configuration.asXml(serverType));
+    }
+
+    protected String serverTypeName() {
+        return serverType.getDisplayName();
+    }
+
+    private void setUpHttpServer() throws Exception {
+        server = new HttpServer();
+        SocketListener listener = new SocketListener();
+        listener.setPort(configuration.getPort());
+        server.addListener(listener);
+
+        ServletHttpContext servletContext = new ServletHttpContext();
+        servletContext.setContextPath("jsunit");
+        servletContext.setResourceBase(configuration.getResourceBase().toString());
+
+        servletContext.addServlet("JSP", "*.jsp", JspServlet.class.getName());
+        servletContext.addHandler(new ResourceHandler());
+
+        ConfigurationManager.clearConfigurationProviders();
+        ConfigurationManager.addConfigurationProvider(new XmlConfigurationProvider(xworkXmlName()));
+        com.opensymphony.webwork.config.Configuration.set("webwork.action.extension", "");
+
+        for (String servletName : servletNames())
+            addWebworkServlet(servletContext, servletName);
+        server.addContext(servletContext);
+
+        if (Monitor.activeCount() == 0)
+            Monitor.monitor();
+    }
+
+    protected abstract String xworkXmlName();
+
+    protected abstract List<String> servletNames();
+
+    private void addWebworkServlet(ServletHttpContext servletContext, String name) throws Exception {
+        servletContext.addServlet(
+                "webwork",
+                "/" + name,
+                ServletDispatcher.class.getName()
+        );
+    }
+
+    public void logStatus(String message) {
+        logger.info(message);
+    }
+
+    public Element asXml() {
+        return configuration.asXml(serverType);
+    }
+
+    public void finalize() throws Throwable {
+        super.finalize();
+        dispose();
+    }
+
+    public void dispose() {
+        logStatus("Stopping server");
+        try {
+            if (server != null)
+                server.stop();
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public boolean isAlive() {
+        return server != null && server.isStarted();
+    }
+
+    public Logger getLogger() {
+        return logger;
+    }
+
+    public ServerType serverType() {
+        return serverType;
+    }
+
+    public Date getStartDate() {
+        return startDate;
+    }
+
+    public long getTestRunCount() {
+        return testRunCount;
+    }
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/BlowingUpProcessStarter.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/BlowingUpProcessStarter.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/BlowingUpProcessStarter.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,12 @@
+package net.jsunit;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+public class BlowingUpProcessStarter implements ProcessStarter {
+
+    public Process execute(String[] command) throws IOException {
+        throw new FileNotFoundException();
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/BrowserResultLogWriter.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/BrowserResultLogWriter.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/BrowserResultLogWriter.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,32 @@
+package net.jsunit;
+
+import net.jsunit.logging.BrowserResultRepository;
+import net.jsunit.model.Browser;
+import net.jsunit.model.BrowserResult;
+
+public class BrowserResultLogWriter implements TestRunListener {
+
+    private BrowserResultRepository repository;
+
+    public BrowserResultLogWriter(BrowserResultRepository repository) {
+        this.repository = repository;
+    }
+
+    public void browserTestRunFinished(Browser browser, BrowserResult result) {
+        repository.store(result);
+    }
+
+    public void browserTestRunStarted(Browser browser) {
+    }
+
+    public boolean isReady() {
+        return true;
+    }
+
+    public void testRunStarted() {
+    }
+
+    public void testRunFinished() {
+    }
+
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/DefaultProcessStarter.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/DefaultProcessStarter.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/DefaultProcessStarter.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,11 @@
+package net.jsunit;
+
+import java.io.IOException;
+
+public class DefaultProcessStarter implements ProcessStarter {
+
+    public Process execute(String[] command) throws IOException {
+        return Runtime.getRuntime().exec(command);
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/DistributedTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/DistributedTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/DistributedTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,107 @@
+package net.jsunit;
+
+import junit.extensions.ActiveTestSuite;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import net.jsunit.configuration.Configuration;
+import net.jsunit.configuration.ConfigurationSource;
+import net.jsunit.model.Browser;
+import net.jsunit.model.DistributedTestRunResult;
+import net.jsunit.utility.XmlUtility;
+import org.mortbay.util.MultiException;
+
+import java.net.BindException;
+import java.util.List;
+
+public class DistributedTest extends TestCase {
+
+    protected DistributedTestRunManager manager;
+    private static JsUnitStandardServer temporaryStandardServer;
+    private static Object blocker = new Object();
+    private static int serverCount = 0;
+
+    public DistributedTest(ConfigurationSource serverSource, ConfigurationSource farmSource) {
+        super(farmSource.remoteMachineURLs());
+        ensureTemporaryStandardServerIsCreated(serverSource);
+        manager = DistributedTestRunManager.forConfiguration(new Configuration(farmSource));
+    }
+
+    private void ensureTemporaryStandardServerIsCreated(ConfigurationSource serverSource) {
+        //noinspection SynchronizeOnNonFinalField
+        synchronized (blocker) {
+            if (temporaryStandardServer == null) {
+                temporaryStandardServer = new JsUnitStandardServer(new Configuration(serverSource), true);
+            }
+        }
+    }
+
+    public void setUp() throws Exception {
+        super.setUp();
+        startServerIfNecessary();
+    }
+
+    private void startServerIfNecessary() throws Exception {
+        serverCount ++;
+        //noinspection SynchronizeOnNonFinalField
+        synchronized (blocker) {
+            if (!temporaryStandardServer.isAlive()) {
+                try {
+                    temporaryStandardServer.start();
+                } catch (MultiException e) {
+                    if (!isMultiExceptionASingleBindException(e))
+                        throw e;
+                    //if a temporaryStandardServer is already running, fine -
+                    //we only need it to serve content to remove machines
+                }
+            }
+        }
+    }
+
+    private boolean isMultiExceptionASingleBindException(MultiException e) {
+        List exceptions = e.getExceptions();
+        return exceptions.size() == 1 && exceptions.get(0) instanceof BindException;
+    }
+
+    public void tearDown() throws Exception {
+        serverCount --;
+        if (serverCount == 0) {
+            if (temporaryStandardServer != null && temporaryStandardServer.isAlive()) {
+                temporaryStandardServer.dispose();
+                temporaryStandardServer = null;
+            }
+        }
+        super.tearDown();
+    }
+
+    public static Test suite(ConfigurationSource source) {
+        TestSuite suite = new ActiveTestSuite();
+        new DistributedTestSuiteBuilder(source).addTestsTo(suite);
+        return suite;
+    }
+
+    public static Test suite() {
+        return suite(Configuration.resolveSource());
+    }
+
+    protected void runTest() throws Throwable {
+        manager.runTests();
+        DistributedTestRunResult result = manager.getDistributedTestRunResult();
+        temporaryStandardServer.logStatus(XmlUtility.asPrettyString(result.asXml()));
+        if (!result.wasSuccessful())
+            fail(result.displayString());
+    }
+
+    public DistributedTestRunManager getDistributedTestRunManager() {
+        return manager;
+    }
+
+    public JsUnitStandardServer getTemporaryStandardServer() {
+        return temporaryStandardServer;
+    }
+
+    public void limitToBrowser(Browser remoteBrowser) {
+        manager.limitToBrowser(remoteBrowser);
+        setName(remoteBrowser.getFileName());
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/DistributedTestRunManager.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/DistributedTestRunManager.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/DistributedTestRunManager.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,128 @@
+package net.jsunit;
+
+import net.jsunit.configuration.Configuration;
+import net.jsunit.model.*;
+import org.jdom.Document;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Logger;
+
+public class DistributedTestRunManager {
+
+    private Logger logger = Logger.getLogger("net.jsunit");
+    private RemoteServerHitter hitter;
+    private Configuration configuration;
+    private String overrideURL;
+    private DistributedTestRunResult distributedTestRunResult = new DistributedTestRunResult();
+    private Browser remoteBrowser;
+
+    public static DistributedTestRunManager forConfiguration(Configuration configuration) {
+        return new DistributedTestRunManager(new RemoteMachineServerHitter(), configuration, null);
+    }
+
+    public static DistributedTestRunManager forConfigurationAndURL(RemoteServerHitter hitter, Configuration configuration, String overrideURL) {
+        return new DistributedTestRunManager(hitter, configuration, overrideURL);
+    }
+
+    protected DistributedTestRunManager(RemoteServerHitter hitter, Configuration configuration, String overrideURL) {
+        this.hitter = hitter;
+        this.configuration = configuration;
+        this.overrideURL = overrideURL;
+    }
+
+    public void runTests() {
+        List<Thread> threads = new ArrayList<Thread>();
+        for (final URL baseURL : configuration.getRemoteMachineURLs())
+            threads.add(new Thread("Run JsUnit tests on " + baseURL) {
+                public void run() {
+                    runTestsOnRemoteMachine(baseURL);
+                }
+            });
+        for (Thread thread : threads)
+            thread.start();
+        for (Thread thread : threads) {
+            try {
+                thread.join();
+            } catch (InterruptedException e) {
+                throw new RuntimeException("One of the test threads was interrupted.");
+            }
+        }
+    }
+
+    private void runTestsOnRemoteMachine(URL baseURL) {
+        List<TestRunResult> results = new ArrayList<TestRunResult>();
+        try {
+            URL fullURL = buildURL(baseURL);
+            logger.info("Requesting run on remove machine URL " + baseURL);
+            Document documentFromRemoteMachine = hitter.hitURL(fullURL);
+            logger.info("Received response from remove machine URL " + baseURL);
+            if (isMultipleTestRunResultsResult(documentFromRemoteMachine)) {
+                DistributedTestRunResult multiple = new DistributedTestRunResultBuilder(configuration).build(documentFromRemoteMachine);
+                results.addAll(multiple.getTestRunResults());
+            } else {
+                TestRunResult single = new TestRunResultBuilder(configuration).build(documentFromRemoteMachine);
+                results.add(single);
+            }
+        } catch (IOException e) {
+            if (configuration.shouldIgnoreUnresponsiveRemoteMachines())
+                logger.info("Ignoring unresponsive machine " + baseURL.toString());
+            else {
+                logger.info("Remote machine URL is unresponsive: " + baseURL.toString());
+                TestRunResult unresponsiveResult = new TestRunResult(baseURL);
+                unresponsiveResult.setUnresponsive();
+                results.add(unresponsiveResult);
+            }
+        }
+        for (TestRunResult result : results) {
+            result.setURL(baseURL);
+            //noinspection SynchronizeOnNonFinalField
+            synchronized (distributedTestRunResult) {
+                distributedTestRunResult.addTestRunResult(result);
+            }
+        }
+    }
+
+    private boolean isMultipleTestRunResultsResult(Document document) {
+        return document.getRootElement().getName().equals(DistributedTestRunResult.NAME);
+    }
+
+    private URL buildURL(URL url) throws UnsupportedEncodingException, MalformedURLException {
+        String fullURLString = url.toString();
+        fullURLString += "/runner";
+        boolean hasFirstParameter = false;
+        if (overrideURL != null) {
+            fullURLString += "?url=" + URLEncoder.encode(overrideURL, "UTF-8");
+            hasFirstParameter = true;
+        } else if (configuration.getTestURL() != null) {
+            fullURLString += "?url=" + URLEncoder.encode(configuration.getTestURL().toString(), "UTF-8");
+            hasFirstParameter = true;
+        }
+        if (remoteBrowser != null) {
+            fullURLString += (hasFirstParameter ? "&" : "?");
+            fullURLString += "browserId=" + remoteBrowser.getId();
+        }
+        return new URL(fullURLString);
+    }
+
+    public DistributedTestRunResult getDistributedTestRunResult() {
+        return distributedTestRunResult;
+    }
+
+    public String getOverrideURL() {
+        return overrideURL;
+    }
+
+    public void setOverrideURL(String overrideURL) {
+        this.overrideURL = overrideURL;
+    }
+
+    public void limitToBrowser(Browser remoteBrowser) {
+        this.remoteBrowser = remoteBrowser;
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/DistributedTestSuiteBuilder.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/DistributedTestSuiteBuilder.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/DistributedTestSuiteBuilder.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,72 @@
+package net.jsunit;
+
+import junit.framework.TestSuite;
+import net.jsunit.configuration.Configuration;
+import net.jsunit.configuration.ConfigurationSource;
+import net.jsunit.configuration.DelegatingConfigurationSource;
+import net.jsunit.model.Browser;
+
+import java.net.URL;
+import java.util.List;
+
+public class DistributedTestSuiteBuilder {
+    private ConfigurationSource localeSource;
+    private RemoteServerHitter hitter;
+    private Configuration localConfiguration;
+    private int browserCount;
+
+    public DistributedTestSuiteBuilder(ConfigurationSource localSource) {
+        this(localSource, new RemoteMachineServerHitter());
+    }
+
+    public DistributedTestSuiteBuilder(ConfigurationSource localSource, RemoteServerHitter hitter) {
+        this.localeSource = localSource;
+        this.hitter = hitter;
+        this.localConfiguration = new Configuration(localeSource);
+    }
+
+    public void addTestsTo(TestSuite suite) {
+        for (final URL remoteMachineURL : localConfiguration.getRemoteMachineURLs()) {
+            ConfigurationSource remoteSource = new RemoteConfigurationSource(hitter, remoteMachineURL.toString());
+            Configuration remoteConfiguration = new Configuration(remoteSource);
+            addTestsForRemoteConfigurationTo(remoteConfiguration, remoteMachineURL, suite);
+        }
+        suite.setName("JsUnit Tests (" + getRemoteMachineURLCount() + " machines, " + getBrowserCount() + " direct browsers)");
+    }
+
+    private void addTestsForRemoteConfigurationTo(Configuration remoteConfiguration, URL remoteMachineURL, TestSuite suite) {
+        List<Browser> browsers = remoteConfiguration.getBrowsers();
+        if (browsers.isEmpty()) {
+            DistributedTest distributedTest = createDistributedTest(localeSource, remoteMachineURL);
+            suite.addTest(distributedTest);
+        } else {
+            TestSuite suiteForRemoteMachine = new TestSuite(remoteMachineURL.toString());
+            for (Browser browser : browsers) {
+                browserCount++;
+                DistributedTest distributedTest = createDistributedTest(localeSource, remoteMachineURL);
+                distributedTest.limitToBrowser(browser);
+                suiteForRemoteMachine.addTest(distributedTest);
+            }
+            suite.addTest(suiteForRemoteMachine);
+        }
+    }
+
+    private DistributedTest createDistributedTest(ConfigurationSource originalSource, final URL remoteMachineURL) {
+        return new DistributedTest(
+                originalSource,
+                new DelegatingConfigurationSource(originalSource) {
+                    public String remoteMachineURLs() {
+                        return remoteMachineURL.toString();
+                    }
+                }
+        );
+    }
+
+    public int getRemoteMachineURLCount() {
+        return localConfiguration.getRemoteMachineURLs().size();
+    }
+
+    public int getBrowserCount() {
+        return browserCount;
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/JsUnitFarmServer.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/JsUnitFarmServer.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/JsUnitFarmServer.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,46 @@
+package net.jsunit;
+
+import net.jsunit.configuration.Configuration;
+import net.jsunit.configuration.ServerType;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class JsUnitFarmServer extends AbstractJsUnitServer {
+
+    public JsUnitFarmServer(Configuration configuration) {
+        super(configuration, ServerType.FARM);
+        ServerRegistry.registerFarmServer(this);
+    }
+
+    protected List<String> servletNames() {
+        return Arrays.asList(new String[]{
+                "index",
+                "config",
+                "latestversion",
+                "runner"
+        });
+    }
+
+    public static void main(String args[]) {
+        try {
+            JsUnitFarmServer server = new JsUnitFarmServer(Configuration.resolve(args));
+            server.start();
+        } catch (Throwable t) {
+            t.printStackTrace();
+        }
+    }
+
+    public String toString() {
+        return "JsUnit Farm Server";
+    }
+
+    protected String xworkXmlName() {
+        return "farm_xwork.xml";
+    }
+
+    public ServerType serverType() {
+        return ServerType.FARM;
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/JsUnitServer.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/JsUnitServer.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/JsUnitServer.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,18 @@
+package net.jsunit;
+
+import net.jsunit.configuration.Configuration;
+import net.jsunit.configuration.ServerType;
+
+import java.util.Date;
+
+public interface JsUnitServer extends XmlRenderable {
+    Configuration getConfiguration();
+
+    ServerType serverType();
+
+    boolean isFarmServer();
+
+    Date getStartDate();
+
+    long getTestRunCount();
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/JsUnitStandardServer.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/JsUnitStandardServer.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/JsUnitStandardServer.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,263 @@
+package net.jsunit;
+
+import net.jsunit.configuration.Configuration;
+import net.jsunit.configuration.ServerType;
+import net.jsunit.logging.BrowserResultRepository;
+import net.jsunit.logging.FileBrowserResultRepository;
+import net.jsunit.model.Browser;
+import net.jsunit.model.BrowserResult;
+import net.jsunit.utility.StringUtility;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class JsUnitStandardServer extends AbstractJsUnitServer implements BrowserTestRunner {
+
+    private List<BrowserResult> results = new ArrayList<BrowserResult>();
+    private List<TestRunListener> browserTestRunListeners = new ArrayList<TestRunListener>();
+
+    private ProcessStarter processStarter = new DefaultProcessStarter();
+    private LaunchTestRunCommand launchTestRunCommand;
+    private TimeoutChecker timeoutChecker;
+    private Process browserProcess;
+    private long timeLastResultReceived;
+
+    private BrowserResultRepository browserResultRepository;
+
+    public JsUnitStandardServer(Configuration configuration, boolean temporary) {
+        this(configuration, new FileBrowserResultRepository(configuration.getLogsDirectory()), temporary);
+    }
+
+    public JsUnitStandardServer(Configuration configuration, BrowserResultRepository browserResultRepository, boolean temporary) {
+        super(configuration, temporary ? ServerType.STANDARD_TEMPORARY : ServerType.STANDARD);
+        this.browserResultRepository = browserResultRepository;
+        addBrowserTestRunListener(new BrowserResultLogWriter(browserResultRepository));
+        ServerRegistry.registerServer(this);
+    }
+
+    public static void main(String args[]) {
+        try {
+            JsUnitStandardServer server = new JsUnitStandardServer(Configuration.resolve(args), false);
+            server.start();
+        } catch (Throwable t) {
+            t.printStackTrace();
+        }
+    }
+
+    protected List<String> servletNames() {
+        return Arrays.asList(new String[]{
+                "acceptor",
+                "config",
+                "displayer",
+                "index",
+                "latestversion",
+                "runner"
+        });
+    }
+
+    public void accept(BrowserResult result) {
+        long timeReceived = System.currentTimeMillis();
+        if (launchTestRunCommand == null)
+            return;
+        Browser submittingBrowser = launchTestRunCommand.getBrowser();
+        endBrowser();
+
+        result.setBrowser(submittingBrowser);
+
+        killTimeoutChecker();
+        BrowserResult existingResultWithSameId = findResultWithId(result.getId(), submittingBrowser);
+        for (TestRunListener listener : browserTestRunListeners)
+            listener.browserTestRunFinished(submittingBrowser, result);
+        if (existingResultWithSameId != null)
+            results.remove(existingResultWithSameId);
+        results.add(result);
+        timeLastResultReceived = timeReceived;
+    }
+
+    private void killTimeoutChecker() {
+        if (timeoutChecker != null) {
+            timeoutChecker.die();
+            timeoutChecker = null;
+        }
+    }
+
+    public List<BrowserResult> getResults() {
+        return results;
+    }
+
+    public void clearResults() {
+        results.clear();
+    }
+
+    public BrowserResult findResultWithId(String id, int browserId) throws InvalidBrowserIdException {
+        Browser browser = configuration.getBrowserById(browserId);
+        if (browser == null)
+            throw new InvalidBrowserIdException(browserId);
+        return findResultWithId(id, browser);
+    }
+
+    private BrowserResult findResultWithId(String id, Browser browser) {
+        BrowserResult result = findResultWithIdInResultList(id, browser);
+        if (result == null)
+            result = browserResultRepository.retrieve(id, browser);
+        return result;
+    }
+
+    private BrowserResult findResultWithIdInResultList(String id, Browser browser) {
+        for (BrowserResult result : getResults()) {
+            if (result.hasId(id) && result.isForBrowser(browser))
+                return result;
+        }
+        return null;
+    }
+
+    public BrowserResult lastResult() {
+        List results = getResults();
+        return results.isEmpty()
+                ? null
+                : (BrowserResult) results.get(results.size() - 1);
+    }
+
+    public int resultsCount() {
+        return getResults().size();
+    }
+
+    public String toString() {
+        return "JsUnit Server";
+    }
+
+    public List<Browser> getBrowsers() {
+        return configuration.getBrowsers();
+    }
+
+    public boolean hasReceivedResultSince(long launchTime) {
+        return timeLastResultReceived >= launchTime;
+    }
+
+    public void addBrowserTestRunListener(TestRunListener listener) {
+        browserTestRunListeners.add(listener);
+    }
+
+    public List<TestRunListener> getBrowserTestRunListeners() {
+        return browserTestRunListeners;
+    }
+
+    private void endBrowser() {
+        if (browserProcess != null && configuration.shouldCloseBrowsersAfterTestRuns()) {
+            if (launchTestRunCommand.getBrowserKillCommand() != null) {
+                try {
+                    processStarter.execute(new String[]{launchTestRunCommand.getBrowserKillCommand()});
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            } else {
+                browserProcess.destroy();
+                try {
+                    browserProcess.waitFor();
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+                waitUntilProcessHasExitValue(browserProcess);
+            }
+        }
+        browserProcess = null;
+        launchTestRunCommand = null;
+        killTimeoutChecker();
+    }
+
+    private void waitUntilProcessHasExitValue(Process browserProcess) {
+        while (true) {
+            try {
+                if (browserProcess != null)
+                    browserProcess.exitValue();
+                return;
+            } catch (IllegalThreadStateException e) {
+            }
+        }
+    }
+
+    public long launchBrowserTestRun(BrowserLaunchSpecification launchSpec) {
+        waitUntilLastReceivedTimeHasPassed();
+        long launchTime = System.currentTimeMillis();
+        launchTestRunCommand = new LaunchTestRunCommand(launchSpec, configuration);
+        Browser browser = launchTestRunCommand.getBrowser();
+        String browserFileName = browser.getFileName();
+        try {
+            logStatus("Launching " + browserFileName + " on " + launchTestRunCommand.getTestURL());
+            for (TestRunListener listener : browserTestRunListeners)
+                listener.browserTestRunStarted(browser);
+            this.browserProcess = processStarter.execute(launchTestRunCommand.generateArray());
+            startTimeoutChecker(launchTime);
+        } catch (Throwable throwable) {
+            handleCrashWhileLaunching(throwable);
+        }
+        return launchTime;
+    }
+
+    private void handleCrashWhileLaunching(Throwable throwable) {
+        Browser browser = launchTestRunCommand.getBrowser();
+        logStatus("Browser " + browser.getFileName() + " failed to launch: " + StringUtility.stackTraceAsString(throwable));
+        BrowserResult failedToLaunchBrowserResult = new BrowserResult();
+        failedToLaunchBrowserResult.setFailedToLaunch();
+        failedToLaunchBrowserResult.setBrowser(browser);
+        failedToLaunchBrowserResult.setServerSideException(throwable);
+        accept(failedToLaunchBrowserResult);
+    }
+
+    private void waitUntilLastReceivedTimeHasPassed() {
+        while (System.currentTimeMillis() == timeLastResultReceived)
+            try {
+                Thread.sleep(1);
+            } catch (InterruptedException e) {
+            }
+    }
+
+    private void startTimeoutChecker(long launchTime) {
+        timeoutChecker = new TimeoutChecker(browserProcess, launchTestRunCommand.getBrowser(), launchTime, this);
+        timeoutChecker.start();
+    }
+
+    void setProcessStarter(ProcessStarter starter) {
+        this.processStarter = starter;
+    }
+
+    public void startTestRun() {
+        for (TestRunListener listener : browserTestRunListeners) {
+            listener.testRunStarted();
+            while (!listener.isReady())
+                try {
+                    Thread.sleep(100);
+                } catch (InterruptedException e) {
+                }
+        }
+    }
+
+    public void finishTestRun() {
+        for (TestRunListener listener : browserTestRunListeners)
+            listener.testRunFinished();
+        testRunCount ++;
+    }
+
+    public Process getBrowserProcess() {
+        return browserProcess;
+    }
+
+    public void dispose() {
+        super.dispose();
+        endBrowser();
+    }
+
+    protected String xworkXmlName() {
+        return "xwork.xml";
+    }
+
+    public int timeoutSeconds() {
+        return configuration.getTimeoutSeconds();
+    }
+
+    public boolean isAwaitingBrowserSubmission() {
+        return launchTestRunCommand != null;
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/LaunchTestRunCommand.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/LaunchTestRunCommand.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/LaunchTestRunCommand.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,78 @@
+package net.jsunit;
+
+import net.jsunit.configuration.Configuration;
+import net.jsunit.model.Browser;
+
+public class LaunchTestRunCommand {
+
+    private Configuration configuration;
+    private BrowserLaunchSpecification launchSpec;
+
+    public LaunchTestRunCommand(BrowserLaunchSpecification launchSpec, Configuration configuration) {
+        this.configuration = configuration;
+        this.launchSpec = launchSpec;
+    }
+
+    public Browser getBrowser() {
+        return launchSpec.getBrowser();
+    }
+
+    public String getBrowserKillCommand() {
+        String killCommand = launchSpec.getBrowser().getKillCommand();
+        if (killCommand == null && launchSpec.isForDefaultBrowser()) {
+            killCommand = PlatformType.resolve().getDefaultBrowserKillCommand();
+        }
+        return killCommand;
+    }
+
+    public String[] generateArray() throws NoUrlSpecifiedException {
+        String[] browserCommandArray = openBrowserCommandArray();
+        String[] commandWithUrl = new String[browserCommandArray.length + 1];
+        System.arraycopy(browserCommandArray, 0, commandWithUrl, 0, browserCommandArray.length);
+        commandWithUrl[browserCommandArray.length] = generateTestUrlString();
+        return commandWithUrl;
+    }
+
+    private String[] openBrowserCommandArray() {
+        if (launchSpec.isForDefaultBrowser()) {
+            PlatformType platformType = PlatformType.resolve();
+            return platformType.getDefaultCommandLineBrowserArray();
+        }
+        return new String[]{launchSpec.getBrowser().getFileName()};
+    }
+
+    private String generateTestUrlString() throws NoUrlSpecifiedException {
+        if (!launchSpec.hasOverrideUrl() && configuration.getTestURL() == null)
+            throw new NoUrlSpecifiedException();
+        String urlString = launchSpec.hasOverrideUrl() ? launchSpec.getOverrideUrl() : configuration.getTestURL().toString();
+        urlString = addAutoRunParameterIfNeeded(urlString);
+        urlString = addSubmitResultsParameterIfNeeded(urlString);
+        return urlString;
+    }
+
+    private String addSubmitResultsParameterIfNeeded(String urlString) {
+        if (urlString.toLowerCase().indexOf("submitresults") == -1)
+            urlString = addParameter(urlString, "submitResults=localhost:" + configuration.getPort() + "/jsunit/acceptor");
+        return urlString;
+    }
+
+    private String addAutoRunParameterIfNeeded(String urlString) {
+        if (urlString.toLowerCase().indexOf("autorun") == -1) {
+            urlString = addParameter(urlString, "autoRun=true");
+        }
+        return urlString;
+    }
+
+    private String addParameter(String urlString, String paramAndValue) {
+        if (urlString.indexOf("?") == -1)
+            urlString += "?";
+        else
+            urlString += "&";
+        urlString += paramAndValue;
+        return urlString;
+    }
+
+    public String getTestURL() throws NoUrlSpecifiedException {
+        return generateTestUrlString();
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/NoUrlSpecifiedException.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/NoUrlSpecifiedException.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/NoUrlSpecifiedException.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,4 @@
+package net.jsunit;
+
+public class NoUrlSpecifiedException extends Exception {
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/PlatformType.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/PlatformType.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/PlatformType.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,53 @@
+package net.jsunit;
+
+import net.jsunit.utility.SystemUtility;
+
+public enum PlatformType {
+
+    WINDOWS(new String[]{"rundll32", "url.dll,FileProtocolHandler"}, null) {
+        public boolean matchesSystem() {
+            String os = SystemUtility.osName();
+            return os != null && os.startsWith("Windows");
+        }
+    },
+    MACINTOSH(new String[]{"bin/mac/start-firefox.sh"}, "bin/mac/stop-firefox.sh") {
+        public boolean matchesSystem() {
+            String os = SystemUtility.osName();
+            return os != null && os.startsWith("Mac");
+        }
+    },
+    UNIX(new String[]{"bin/unix/start-firefox.sh"}, "bin/unix/stop-firefox.sh") {
+        public boolean matchesSystem() {
+            //TODO: uhhh...
+            return false;
+        }
+    };
+
+    public static PlatformType DEFAULT = UNIX;
+
+    private String[] defaultBrowserCommandLineArray;
+    private String defaultBrowserKillCommand;
+
+    private PlatformType(String[] defaultBrowserCommandLineArray, String defaultBrowserKillCommand) {
+        this.defaultBrowserKillCommand = defaultBrowserKillCommand;
+        this.defaultBrowserCommandLineArray = defaultBrowserCommandLineArray;
+    }
+
+    public static PlatformType resolve() {
+        for (PlatformType type : values()) {
+            if (type.matchesSystem())
+                return type;
+        }
+        return DEFAULT;
+    }
+
+    protected abstract boolean matchesSystem();
+
+    public String[] getDefaultCommandLineBrowserArray() {
+        return defaultBrowserCommandLineArray;
+    }
+
+    public String getDefaultBrowserKillCommand() {
+        return defaultBrowserKillCommand;
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/ProcessStarter.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/ProcessStarter.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/ProcessStarter.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,9 @@
+package net.jsunit;
+
+import java.io.IOException;
+
+public interface ProcessStarter {
+
+    Process execute(String[] command) throws IOException;
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/RemoteConfigurationSource.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/RemoteConfigurationSource.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/RemoteConfigurationSource.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,94 @@
+package net.jsunit;
+
+import net.jsunit.configuration.ConfigurationProperty;
+import net.jsunit.configuration.ConfigurationSource;
+import org.jdom.Document;
+import org.jdom.Element;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Iterator;
+import java.util.List;
+import java.util.logging.Logger;
+
+public class RemoteConfigurationSource implements ConfigurationSource {
+
+    private Logger logger = Logger.getLogger("net.jsunit");
+
+    private Document document;
+
+    public RemoteConfigurationSource(RemoteServerHitter hitter, String remoteMachineURL) {
+        try {
+            document = hitter.hitURL(new URL(remoteMachineURL + "/config"));
+        } catch (IOException e) {
+            logger.severe("Could not retrieve configuration from remoteMachine URL " + remoteMachineURL);
+        }
+    }
+
+    public boolean isInitialized() {
+        return document != null;
+    }
+
+    public String browserFileNames() {
+        return commaSeparatedTextOfChildrenOfElement(ConfigurationProperty.BROWSER_FILE_NAMES);
+    }
+
+    public String closeBrowsersAfterTestRuns() {
+        return textOfElement(ConfigurationProperty.CLOSE_BROWSERS_AFTER_TEST_RUNS);
+    }
+
+    public String description() {
+        return textOfElement(ConfigurationProperty.DESCRIPTION);
+    }
+
+    public String logsDirectory() {
+        return textOfElement(ConfigurationProperty.LOGS_DIRECTORY);
+    }
+
+    public String port() {
+        return textOfElement(ConfigurationProperty.PORT);
+    }
+
+    public String remoteMachineURLs() {
+        return commaSeparatedTextOfChildrenOfElement(ConfigurationProperty.REMOTE_MACHINE_URLS);
+    }
+
+    public String resourceBase() {
+        return textOfElement(ConfigurationProperty.RESOURCE_BASE);
+    }
+
+    public String timeoutSeconds() {
+        return textOfElement(ConfigurationProperty.TIMEOUT_SECONDS);
+    }
+
+    public String url() {
+        return textOfElement(ConfigurationProperty.URL);
+    }
+
+    public String ignoreUnresponsiveRemoteMachines() {
+        return textOfElement(ConfigurationProperty.IGNORE_UNRESPONSIVE_REMOTE_MACHINES);
+    }
+
+    private String textOfElement(ConfigurationProperty property) {
+        Element element = document.getRootElement().getChild(property.getName());
+        if (element == null)
+            return "";
+        return element.getTextTrim();
+    }
+
+    private String commaSeparatedTextOfChildrenOfElement(ConfigurationProperty property) {
+        Element parent = document.getRootElement().getChild(property.getName());
+        if (parent == null)
+            return "";
+        List<Element> children = parent.getChildren();
+        StringBuffer buffer = new StringBuffer();
+        for (Iterator<Element> it = children.iterator(); it.hasNext();) {
+            Element child = it.next();
+            buffer.append(child.getTextTrim());
+            if (it.hasNext())
+                buffer.append(",");
+        }
+        return buffer.toString();
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/RemoteMachineServerHitter.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/RemoteMachineServerHitter.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/RemoteMachineServerHitter.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,23 @@
+package net.jsunit;
+
+import net.jsunit.utility.StreamUtility;
+import net.jsunit.utility.XmlUtility;
+import org.jdom.Document;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+
+public class RemoteMachineServerHitter implements RemoteServerHitter {
+
+    public Document hitURL(URL url) throws IOException {
+        String xmlResultString = submitRequestTo(url);
+        return XmlUtility.asXmlDocument(xmlResultString);
+    }
+
+    private String submitRequestTo(URL url) throws IOException {
+        URLConnection connection = url.openConnection();
+        return StreamUtility.readAllFromStream(connection.getInputStream());
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/RemoteServerHitter.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/RemoteServerHitter.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/RemoteServerHitter.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,12 @@
+package net.jsunit;
+
+import org.jdom.Document;
+
+import java.io.IOException;
+import java.net.URL;
+
+public interface RemoteServerHitter {
+
+    public Document hitURL(URL url) throws IOException;
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/ServerRegistry.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/ServerRegistry.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/ServerRegistry.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,26 @@
+package net.jsunit;
+
+public class ServerRegistry {
+    private static JsUnitStandardServer standardServer;
+    private static JsUnitFarmServer farmServer;
+
+    public static void registerServer(JsUnitStandardServer server) {
+        standardServer = server;
+    }
+
+    public static void registerFarmServer(JsUnitFarmServer server) {
+        farmServer = server;
+    }
+
+    public static JsUnitStandardServer getStandardServer() {
+        return standardServer;
+    }
+
+    public static JsUnitFarmServer getFarmServer() {
+        return farmServer;
+    }
+
+    public static JsUnitServer getServer() {
+        return standardServer != null ? standardServer : farmServer;
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/StandaloneTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/StandaloneTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/StandaloneTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,88 @@
+package net.jsunit;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import net.jsunit.configuration.Configuration;
+import net.jsunit.configuration.ConfigurationSource;
+import net.jsunit.configuration.DelegatingConfigurationSource;
+import net.jsunit.model.Browser;
+import net.jsunit.model.TestRunResult;
+import net.jsunit.utility.XmlUtility;
+
+public class StandaloneTest extends TestCase {
+
+    protected JsUnitStandardServer server;
+    private TestRunManager testRunManager;
+    private ConfigurationSource configurationSource;
+    private String overrideURL;
+
+    public StandaloneTest(String name) {
+        super(name);
+        this.configurationSource = configurationSource();
+    }
+
+    public StandaloneTest(ConfigurationSource source) {
+        super(source.browserFileNames());
+        this.configurationSource = source;
+    }
+
+    public static Test suite() {
+        TestSuite suite = new TestSuite();
+        ConfigurationSource originalSource = Configuration.resolveSource();
+        Configuration configuration = new Configuration(originalSource);
+        for (final Browser browser : configuration.getBrowsers())
+            suite.addTest(new StandaloneTest(new DelegatingConfigurationSource(originalSource) {
+                public String browserFileNames() {
+                    return browser.getFileName();
+                }
+            }));
+        return suite;
+    }
+
+    public void setUp() throws Exception {
+        super.setUp();
+        server = new JsUnitStandardServer(new Configuration(configurationSource), false);
+        server.start();
+        testRunManager = createTestRunManager();
+    }
+
+    protected ConfigurationSource configurationSource() {
+        return Configuration.resolveSource();
+    }
+
+    protected TestRunManager createTestRunManager() {
+        return new TestRunManager(server, overrideURL);
+    }
+
+    public void tearDown() throws Exception {
+        if (server != null)
+            server.dispose();
+        super.tearDown();
+    }
+
+    public void runTest() throws Exception {
+        testStandaloneRun();
+    }
+
+    public void testStandaloneRun() throws Exception {
+        testRunManager.runTests();
+        TestRunResult testRunResult = testRunManager.getTestRunResult();
+        if (!testRunResult.wasSuccessful()) {
+            StringBuffer buffer = new StringBuffer();
+            buffer.append(testRunResult.displayString());
+            buffer.append("\n");
+            String xml = XmlUtility.asPrettyString(testRunManager.getTestRunResult().asXml());
+            buffer.append(xml);
+            fail(buffer.toString());
+        }
+    }
+
+    public JsUnitStandardServer getServer() {
+        return server;
+    }
+
+    public void setOverrideURL(String url) {
+        this.overrideURL = url;
+    }
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/TestRunManager.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/TestRunManager.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/TestRunManager.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,108 @@
+package net.jsunit;
+
+import net.jsunit.configuration.Configuration;
+import net.jsunit.model.Browser;
+import net.jsunit.model.TestRunResult;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class TestRunManager {
+
+    private BrowserTestRunner testRunner;
+    private TestRunResult testRunResult;
+    private final String overrideUrl;
+    private List<Browser> browsers;
+
+    public static void main(String[] args) throws Exception {
+        JsUnitStandardServer server = new JsUnitStandardServer(Configuration.resolve(args), true);
+        int port = Integer.parseInt(args[args.length - 1]);
+        if (noLogging(args))
+            shutOffAllLogging();
+        server.addBrowserTestRunListener(new TestRunNotifierServer(server, port));
+        server.start();
+        TestRunManager manager = new TestRunManager(server);
+        manager.runTests();
+        if (server.isAlive())
+            server.dispose();
+    }
+
+    private static void shutOffAllLogging() {
+        Logger.getLogger("net.jsunit").setLevel(Level.OFF);
+        Logger.getLogger("org.mortbay").setLevel(Level.OFF);
+        Logger.getLogger("com.opensymphony").setLevel(Level.OFF);
+    }
+
+    private static boolean noLogging(String[] arguments) {
+        for (String string : arguments)
+            if (string.equals("-noLogging"))
+                return true;
+        return false;
+    }
+
+    public TestRunManager(BrowserTestRunner testRunner) {
+        this(testRunner, null);
+    }
+
+    public TestRunManager(BrowserTestRunner testRunner, String overrideUrl) {
+        this.testRunner = testRunner;
+        this.overrideUrl = overrideUrl;
+        browsers = testRunner.getBrowsers();
+    }
+
+    public void runTests() {
+        initializeTestRunResult();
+        testRunner.logStatus("Starting Test Run");
+        testRunner.startTestRun();
+        try {
+            for (Browser browser : browsers) {
+                BrowserLaunchSpecification launchSpec = new BrowserLaunchSpecification(browser, overrideUrl);
+                long launchTime = testRunner.launchBrowserTestRun(launchSpec);
+                waitForResultToBeSubmitted(browser, launchTime);
+                if (testRunner.isAlive())
+                    testRunResult.addBrowserResult(testRunner.lastResult());
+                else
+                    return;
+            }
+        } finally {
+            testRunner.finishTestRun();
+        }
+        testRunner.logStatus("Test Run Completed");
+    }
+
+    private void initializeTestRunResult() {
+        testRunResult = new TestRunResult();
+        testRunResult.initializeProperties();
+    }
+
+    private void waitForResultToBeSubmitted(Browser browser, long launchTime) {
+        testRunner.logStatus("Waiting for " + browser.getFileName() + " to submit result");
+        long secondsWaited = 0;
+        while (testRunner.isAlive() && !testRunner.hasReceivedResultSince(launchTime)) {
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+            }
+            secondsWaited++;
+            if (secondsWaited > (testRunner.timeoutSeconds()) + 3)
+                throw new RuntimeException("Server not responding");
+        }
+    }
+
+    public TestRunResult getTestRunResult() {
+        return testRunResult;
+    }
+
+    public void limitToBrowserWithId(int chosenBrowserId) throws InvalidBrowserIdException {
+        Browser chosenBrowser = null;
+        for (Browser browser : browsers) {
+            if (browser.hasId(chosenBrowserId))
+                chosenBrowser = browser;
+        }
+        if (chosenBrowser == null)
+            throw new InvalidBrowserIdException(chosenBrowserId);
+        browsers = Arrays.asList(chosenBrowser);
+    }
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/TimeoutChecker.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/TimeoutChecker.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/TimeoutChecker.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,93 @@
+package net.jsunit;
+
+import net.jsunit.model.Browser;
+import net.jsunit.model.BrowserResult;
+
+public class TimeoutChecker extends Thread {
+
+    private final BrowserTestRunner runner;
+    private long launchTime;
+    private final Browser browser;
+    private boolean alive;
+    private long checkInterval;
+    private Process browserProcess;
+
+    public TimeoutChecker(Process browserProcess, Browser browser, long launchTime, BrowserTestRunner runner) {
+        this(browserProcess, browser, launchTime, runner, 100);
+    }
+
+    public TimeoutChecker(Process browserProcess, Browser browser, long launchTime, BrowserTestRunner runner, long checkInterval) {
+        this.browser = browser;
+        this.runner = runner;
+        this.launchTime = launchTime;
+        this.checkInterval = checkInterval;
+        this.browserProcess = browserProcess;
+        alive = true;
+    }
+
+    public void run() {
+
+        while (alive && !runner.hasReceivedResultSince(launchTime)) {
+            if (waitedTooLong()) {
+                runner.logStatus("Browser " + browser.getFileName() + " timed out after " + runner.timeoutSeconds() + " seconds");
+                runner.accept(createTimedOutBrowserResult());
+                return;
+            }
+//			else if (!isBrowserProcessAlive()) {
+//				if (!runner.hasReceivedResultSince(launchTime)) {
+//					runner.logStatus("Browser " + browserFileName + " was shutdown externally");
+//					runner.accept(createExternallyShutdownBrowserResult());
+//					return;
+//				}
+//			}
+            else
+                try {
+                    Thread.sleep(checkInterval);
+                } catch (InterruptedException e) {
+                }
+        }
+    }
+
+    //TODO: finish implementing external shutdown
+    @SuppressWarnings("unused")
+    private BrowserResult createExternallyShutdownBrowserResult() {
+        BrowserResult result = createRawBrowserResult();
+        result.setExternallyShutDown();
+        return result;
+    }
+
+    private BrowserResult createTimedOutBrowserResult() {
+        BrowserResult result = createRawBrowserResult();
+        result.setTimedOut();
+        return result;
+    }
+
+    private BrowserResult createRawBrowserResult() {
+        BrowserResult result = new BrowserResult();
+        result.setBrowser(browser);
+        return result;
+    }
+
+    //TODO: finish implementing external shutdown
+    @SuppressWarnings("unused")
+    private boolean isBrowserProcessAlive() {
+        try {
+            if (browserProcess == null)
+                return false;
+            browserProcess.exitValue();
+            return false;
+        } catch (IllegalThreadStateException e) {
+            return true;
+        }
+    }
+
+    public void die() {
+        alive = false;
+    }
+
+    private boolean waitedTooLong() {
+        long secondsWaited = (System.currentTimeMillis() - launchTime) / 1000;
+        return secondsWaited > runner.timeoutSeconds();
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/BrowserResultAware.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/BrowserResultAware.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/BrowserResultAware.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,9 @@
+package net.jsunit.action;
+
+import net.jsunit.model.BrowserResult;
+
+public interface BrowserResultAware {
+
+    public void setBrowserResult(BrowserResult result);
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/BrowserTestRunnerConfigurationAction.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/BrowserTestRunnerConfigurationAction.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/BrowserTestRunnerConfigurationAction.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,13 @@
+package net.jsunit.action;
+
+import net.jsunit.XmlRenderable;
+
+public class BrowserTestRunnerConfigurationAction extends JsUnitBrowserTestRunnerAction {
+    public String execute() throws Exception {
+        return SUCCESS;
+    }
+
+    public XmlRenderable getXmlRenderable() {
+        return runner;
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/DistributedTestRunnerAction.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/DistributedTestRunnerAction.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/DistributedTestRunnerAction.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,36 @@
+package net.jsunit.action;
+
+import net.jsunit.DistributedTestRunManager;
+import net.jsunit.XmlRenderable;
+
+public class DistributedTestRunnerAction extends JsUnitFarmServerAction {
+
+    private DistributedTestRunManager manager;
+    private String overrideURL;
+
+    public String execute() throws Exception {
+        String message = "Received request to run farm tests";
+        if (overrideURL != null)
+            message += " with URL " + overrideURL;
+        server.logStatus(message);
+        //noinspection SynchronizeOnNonFinalField
+        synchronized (server) {
+            manager = DistributedTestRunManager.forConfigurationAndURL(hitter, server.getConfiguration(), overrideURL);
+            manager.runTests();
+        }
+        server.logStatus("Done running farm tests");
+        return SUCCESS;
+    }
+
+    public XmlRenderable getXmlRenderable() {
+        return manager.getDistributedTestRunResult();
+    }
+
+    public DistributedTestRunManager getTestRunManager() {
+        return manager;
+    }
+
+    public void setUrl(String overrideURL) {
+        this.overrideURL = overrideURL;
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/ErrorXmlRenderable.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/ErrorXmlRenderable.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/ErrorXmlRenderable.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,16 @@
+package net.jsunit.action;
+
+import net.jsunit.XmlRenderable;
+import org.jdom.Element;
+
+public class ErrorXmlRenderable implements XmlRenderable {
+    private String message;
+
+    public ErrorXmlRenderable(String message) {
+        this.message = message;
+    }
+
+    public Element asXml() {
+        return new Element("error").setText(message);
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/FarmServerConfigurationAction.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/FarmServerConfigurationAction.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/FarmServerConfigurationAction.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,52 @@
+package net.jsunit.action;
+
+import net.jsunit.XmlRenderable;
+import org.jdom.CDATA;
+import org.jdom.Document;
+import org.jdom.Element;
+
+import java.io.IOException;
+import java.net.URL;
+
+public class FarmServerConfigurationAction extends JsUnitFarmServerAction {
+
+    private Element result;
+
+    public String execute() throws Exception {
+        result = new Element("remoteConfigurations");
+        for (URL url : server.getConfiguration().getRemoteMachineURLs()) {
+            URL configurationURL = new URL(url.toString() + "/config");
+            Element configurationElement;
+            try {
+                Document document = hitter.hitURL(configurationURL);
+                configurationElement = document.getRootElement();
+                configurationElement.detach();
+            } catch (IOException e) {
+                configurationElement = new Element("configuration");
+                configurationElement.setAttribute("failedToConnect", String.valueOf(true));
+                configurationElement.addContent(new CDATA(e.toString()));
+            }
+
+            addRemoteConfigurationElementToResult(url, configurationElement);
+        }
+        return SUCCESS;
+    }
+
+    private void addRemoteConfigurationElementToResult(URL remoteMachineURL, Element configurationElement) {
+        Element remoteConfigurationElement = new Element("remoteConfiguration");
+        remoteConfigurationElement.setAttribute("remoteMachineURL", remoteMachineURL.toString());
+        remoteConfigurationElement.addContent(configurationElement);
+        result.addContent(remoteConfigurationElement);
+    }
+
+    public XmlRenderable getXmlRenderable() {
+        return new XmlRenderable() {
+
+            public Element asXml() {
+                return result;
+            }
+
+        };
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/IndexAction.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/IndexAction.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/IndexAction.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,9 @@
+package net.jsunit.action;
+
+import com.opensymphony.xwork.Action;
+
+public class IndexAction implements Action {
+    public String execute() throws Exception {
+        return SUCCESS;
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/JsUnitBrowserTestRunnerAction.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/JsUnitBrowserTestRunnerAction.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/JsUnitBrowserTestRunnerAction.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,18 @@
+package net.jsunit.action;
+
+import com.opensymphony.xwork.Action;
+import net.jsunit.BrowserTestRunner;
+
+public abstract class JsUnitBrowserTestRunnerAction implements Action, XmlProducer {
+
+    protected BrowserTestRunner runner;
+
+    public void setBrowserTestRunner(BrowserTestRunner runner) {
+        this.runner = runner;
+    }
+
+    public BrowserTestRunner getBrowserTestRunner() {
+        return runner;
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/JsUnitFarmServerAction.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/JsUnitFarmServerAction.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/JsUnitFarmServerAction.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,24 @@
+package net.jsunit.action;
+
+import com.opensymphony.xwork.Action;
+import net.jsunit.JsUnitFarmServer;
+import net.jsunit.RemoteServerHitter;
+
+public abstract class JsUnitFarmServerAction
+        implements Action,
+        XmlProducer,
+        RemoteRunnerHitterAware,
+        JsUnitServerAware {
+
+    protected JsUnitFarmServer server;
+    protected RemoteServerHitter hitter;
+
+    public void setFarmServer(JsUnitFarmServer server) {
+        this.server = server;
+    }
+
+    public void setRemoteRunnerHitter(RemoteServerHitter hitter) {
+        this.hitter = hitter;
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/JsUnitServerAware.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/JsUnitServerAware.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/JsUnitServerAware.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,7 @@
+package net.jsunit.action;
+
+import net.jsunit.JsUnitFarmServer;
+
+public interface JsUnitServerAware {
+    void setFarmServer(JsUnitFarmServer farmServer);
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/LatestVersionAction.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/LatestVersionAction.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/LatestVersionAction.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,26 @@
+package net.jsunit.action;
+
+import com.opensymphony.xwork.Action;
+import net.jsunit.version.VersionGrabber;
+
+public class LatestVersionAction implements Action, LatestVersionSource, VersionGrabberAware {
+    private VersionGrabber versionGrabber;
+    private double latestVersion;
+
+    public String execute() throws Exception {
+        try {
+            latestVersion = versionGrabber.grabVersion();
+            return SUCCESS;
+        } catch (Exception e) {
+            return ERROR;
+        }
+    }
+
+    public double getLatestVersion() {
+        return latestVersion;
+    }
+
+    public void setVersionGrabber(VersionGrabber versionGrabber) {
+        this.versionGrabber = versionGrabber;
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/LatestVersionResult.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/LatestVersionResult.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/LatestVersionResult.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,22 @@
+package net.jsunit.action;
+
+import com.opensymphony.webwork.ServletActionContext;
+import com.opensymphony.xwork.ActionInvocation;
+import com.opensymphony.xwork.Result;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.OutputStream;
+
+public class LatestVersionResult implements Result {
+
+    public void execute(ActionInvocation invocation) throws Exception {
+        LatestVersionSource source = (LatestVersionSource) invocation.getAction();
+        double latestVersion = source.getLatestVersion();
+        HttpServletResponse response = ServletActionContext.getResponse();
+        response.setContentType("text/xml");
+        OutputStream out = response.getOutputStream();
+        out.write(String.valueOf(latestVersion).getBytes());
+        out.close();
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/LatestVersionSource.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/LatestVersionSource.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/LatestVersionSource.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,5 @@
+package net.jsunit.action;
+
+public interface LatestVersionSource {
+    double getLatestVersion();
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/RemoteRunnerHitterAware.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/RemoteRunnerHitterAware.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/RemoteRunnerHitterAware.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,9 @@
+package net.jsunit.action;
+
+import net.jsunit.RemoteServerHitter;
+
+public interface RemoteRunnerHitterAware {
+
+    public void setRemoteRunnerHitter(RemoteServerHitter hitter);
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/RequestSourceAware.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/RequestSourceAware.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/RequestSourceAware.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,8 @@
+package net.jsunit.action;
+
+public interface RequestSourceAware {
+
+    void setRequestIPAddress(String ipAddress);
+
+    void setRequestHost(String host);
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/ResultAcceptorAction.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/ResultAcceptorAction.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/ResultAcceptorAction.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,28 @@
+package net.jsunit.action;
+
+import net.jsunit.XmlRenderable;
+import net.jsunit.model.BrowserResult;
+
+public class ResultAcceptorAction extends JsUnitBrowserTestRunnerAction implements BrowserResultAware {
+
+    protected BrowserResult result;
+
+    public String execute() throws Exception {
+        runner.logStatus("Received submission");
+        runner.accept(result);
+        return SUCCESS;
+    }
+
+    public void setBrowserResult(BrowserResult result) {
+        this.result = result;
+    }
+
+    public BrowserResult getResult() {
+        return result;
+    }
+
+    public XmlRenderable getXmlRenderable() {
+        return getResult();
+    }
+
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/ResultDisplayerAction.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/ResultDisplayerAction.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/ResultDisplayerAction.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,47 @@
+package net.jsunit.action;
+
+import net.jsunit.InvalidBrowserIdException;
+import net.jsunit.XmlRenderable;
+import net.jsunit.model.BrowserResult;
+
+public class ResultDisplayerAction extends JsUnitBrowserTestRunnerAction {
+
+    private String id;
+    private BrowserResult result;
+    private Integer browserId;
+    private boolean browserIdInvalid;
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public void setBrowserId(Integer browserId) {
+        this.browserId = browserId;
+    }
+
+    public String execute() throws Exception {
+        if (id == null || browserId == null)
+            return ERROR;
+        try {
+            result = runner.findResultWithId(id, browserId);
+        } catch (InvalidBrowserIdException e) {
+            browserIdInvalid = true;
+            return ERROR;
+        }
+        return SUCCESS;
+    }
+
+    public XmlRenderable getXmlRenderable() {
+        if (result != null)
+            return result;
+        String message;
+        if (browserIdInvalid)
+            message = "Invalid Browser ID '" + browserId + "'";
+        else if (id != null && browserId != null)
+            message = "No Test Result has been submitted with ID '" + id + "' for browser ID '" + browserId + "'";
+        else
+            message = "A Test Result ID and a browser ID must both be given";
+        return new ErrorXmlRenderable(message);
+    }
+
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/StandaloneTestAware.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/StandaloneTestAware.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/StandaloneTestAware.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,9 @@
+package net.jsunit.action;
+
+import net.jsunit.StandaloneTest;
+
+public interface StandaloneTestAware {
+
+    public void setStandaloneTest(StandaloneTest test);
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/TestRunnerAction.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/TestRunnerAction.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/TestRunnerAction.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,76 @@
+package net.jsunit.action;
+
+import net.jsunit.InvalidBrowserIdException;
+import net.jsunit.TestRunManager;
+import net.jsunit.XmlRenderable;
+import net.jsunit.utility.StringUtility;
+
+public class TestRunnerAction extends JsUnitBrowserTestRunnerAction implements RequestSourceAware {
+
+    private TestRunManager manager;
+    private String url;
+    private String remoteAddress;
+    private String remoteHost;
+    private String browserId;
+    private boolean badBrowserId = false;
+
+    public String execute() throws Exception {
+        runner.logStatus(requestReceivedMessage());
+        //noinspection SynchronizeOnNonFinalField
+        synchronized (runner) {
+            manager = new TestRunManager(runner, url);
+            if (!StringUtility.isEmpty(browserId)) {
+                try {
+                    manager.limitToBrowserWithId(Integer.parseInt(browserId));
+                } catch (InvalidBrowserIdException e) {
+                    badBrowserId = true;
+                    return ERROR;
+                } catch (NumberFormatException e) {
+                    badBrowserId = true;
+                    return ERROR;
+                }
+            }
+            manager.runTests();
+        }
+        runner.logStatus("Done running tests");
+        return SUCCESS;
+    }
+
+    private String requestReceivedMessage() {
+        String message = "Received request to run tests";
+        if (!StringUtility.isEmpty(remoteAddress) || !StringUtility.isEmpty(remoteHost)) {
+            message += " from ";
+            if (!StringUtility.isEmpty(remoteHost)) {
+                message += remoteHost;
+                if (!StringUtility.isEmpty(remoteAddress) && !remoteAddress.equals(remoteHost))
+                    message += " (" + remoteAddress + ")";
+            } else {
+                message += remoteAddress;
+            }
+        }
+        return message;
+    }
+
+    public XmlRenderable getXmlRenderable() {
+        if (badBrowserId) {
+            return new ErrorXmlRenderable("Invalid browser ID: " + browserId);
+        }
+        return manager.getTestRunResult();
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public void setRequestIPAddress(String ipAddress) {
+        remoteAddress = ipAddress;
+    }
+
+    public void setRequestHost(String host) {
+        remoteHost = host;
+    }
+
+    public void setBrowserId(String browserId) {
+        this.browserId = browserId;
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/VersionGrabberAware.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/VersionGrabberAware.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/VersionGrabberAware.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,7 @@
+package net.jsunit.action;
+
+import net.jsunit.version.VersionGrabber;
+
+public interface VersionGrabberAware {
+    void setVersionGrabber(VersionGrabber versionGrabber);    
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/XmlProducer.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/XmlProducer.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/XmlProducer.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,9 @@
+package net.jsunit.action;
+
+import net.jsunit.XmlRenderable;
+
+public interface XmlProducer {
+
+    public XmlRenderable getXmlRenderable();
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/XmlResult.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/XmlResult.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/action/XmlResult.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,39 @@
+package net.jsunit.action;
+
+import com.opensymphony.webwork.ServletActionContext;
+import com.opensymphony.xwork.ActionInvocation;
+import com.opensymphony.xwork.Result;
+import net.jsunit.XmlRenderable;
+import net.jsunit.utility.XmlUtility;
+import org.jdom.Document;
+import org.jdom.Element;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.logging.Logger;
+
+public class XmlResult implements Result {
+
+	private Logger logger = Logger.getLogger(XmlResult.class.getName());
+	
+    public void execute(ActionInvocation invocation) throws Exception {
+        XmlProducer producer = (XmlProducer) invocation.getAction();
+        XmlRenderable xmlRenderable = producer.getXmlRenderable();
+        Element element = xmlRenderable.asXml();
+        Document document = new Document(element);
+        String xmlString = XmlUtility.asString(document);
+        HttpServletResponse response = ServletActionContext.getResponse();
+        response.setContentType("text/xml");
+        try {
+	        OutputStream out = response.getOutputStream();
+	        BufferedOutputStream bufferedOut = new BufferedOutputStream(out);
+	        bufferedOut.write(xmlString.getBytes());
+	        bufferedOut.close();
+        } catch (IOException e) {
+        	logger.warning("Failed to write result XML response to browser: " + e.toString());
+        }
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/BrowserResultInterceptor.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/BrowserResultInterceptor.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/BrowserResultInterceptor.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,37 @@
+package net.jsunit.interceptor;
+
+import com.opensymphony.webwork.ServletActionContext;
+import com.opensymphony.xwork.Action;
+import net.jsunit.action.BrowserResultAware;
+import net.jsunit.model.BrowserResult;
+import net.jsunit.model.BrowserResultWriter;
+import net.jsunit.utility.StringUtility;
+
+import javax.servlet.http.HttpServletRequest;
+
+public class BrowserResultInterceptor extends JsUnitInterceptor {
+
+    protected void execute(Action targetAction) {
+        HttpServletRequest request = ServletActionContext.getRequest();
+        BrowserResult result = build(request);
+        BrowserResultAware aware = (BrowserResultAware) targetAction;
+        aware.setBrowserResult(result);
+    }
+
+    public BrowserResult build(HttpServletRequest request) {
+        BrowserResult result = new BrowserResult();
+        String testId = request.getParameter(BrowserResultWriter.ID);
+        if (!StringUtility.isEmpty(testId))
+            result.setId(testId);
+        result.setRemoteAddress(request.getRemoteAddr());
+        result.setUserAgent(request.getParameter(BrowserResultWriter.USER_AGENT));
+        result.setBaseURL(request.getParameter(BrowserResultWriter.URL));
+        String time = request.getParameter(BrowserResultWriter.TIME);
+        if (!StringUtility.isEmpty(time))
+            result.setTime(Double.parseDouble(time));
+        result.setJsUnitVersion(request.getParameter(BrowserResultWriter.JSUNIT_VERSION));
+        result.setTestCaseStrings(request.getParameterValues(BrowserResultWriter.TEST_CASES));
+        return result;
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/BrowserTestRunnerInterceptor.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/BrowserTestRunnerInterceptor.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/BrowserTestRunnerInterceptor.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,21 @@
+package net.jsunit.interceptor;
+
+import com.opensymphony.xwork.Action;
+import net.jsunit.BrowserTestRunner;
+import net.jsunit.action.JsUnitBrowserTestRunnerAction;
+
+public class BrowserTestRunnerInterceptor extends JsUnitInterceptor {
+
+    private static BrowserTestRunnerSource source = new DefaultBrowserTestRunnerSource();
+
+    public static void setBrowserTestRunnerSource(BrowserTestRunnerSource aSource) {
+        source = aSource;
+    }
+
+    protected void execute(Action action) {
+        JsUnitBrowserTestRunnerAction jsUnitAction = ((JsUnitBrowserTestRunnerAction) action);
+        BrowserTestRunner runner = source.getRunner();
+        jsUnitAction.setBrowserTestRunner(runner);
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/BrowserTestRunnerSource.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/BrowserTestRunnerSource.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/BrowserTestRunnerSource.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,9 @@
+package net.jsunit.interceptor;
+
+import net.jsunit.BrowserTestRunner;
+
+public interface BrowserTestRunnerSource {
+
+    BrowserTestRunner getRunner();
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/DefaultBrowserTestRunnerSource.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/DefaultBrowserTestRunnerSource.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/DefaultBrowserTestRunnerSource.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,12 @@
+package net.jsunit.interceptor;
+
+import net.jsunit.BrowserTestRunner;
+import net.jsunit.ServerRegistry;
+
+public class DefaultBrowserTestRunnerSource implements BrowserTestRunnerSource {
+
+    public BrowserTestRunner getRunner() {
+        return ServerRegistry.getStandardServer();
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/FarmServerInterceptor.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/FarmServerInterceptor.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/FarmServerInterceptor.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,14 @@
+package net.jsunit.interceptor;
+
+import com.opensymphony.xwork.Action;
+import net.jsunit.ServerRegistry;
+import net.jsunit.action.JsUnitServerAware;
+
+public class FarmServerInterceptor extends JsUnitInterceptor {
+
+    protected void execute(Action targetAction) {
+        JsUnitServerAware action = (JsUnitServerAware) targetAction;
+        action.setFarmServer(ServerRegistry.getFarmServer());
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/JsUnitInterceptor.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/JsUnitInterceptor.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/JsUnitInterceptor.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,22 @@
+package net.jsunit.interceptor;
+
+import com.opensymphony.xwork.Action;
+import com.opensymphony.xwork.ActionInvocation;
+import com.opensymphony.xwork.interceptor.Interceptor;
+
+public abstract class JsUnitInterceptor implements Interceptor {
+
+    public void destroy() {
+    }
+
+    public void init() {
+    }
+
+    public String intercept(ActionInvocation invocation) throws Exception {
+        execute((Action) invocation.getAction());
+        return invocation.invoke();
+    }
+
+    protected abstract void execute(Action targetAction);
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/RemoteRunnerHitterInterceptor.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/RemoteRunnerHitterInterceptor.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/RemoteRunnerHitterInterceptor.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,14 @@
+package net.jsunit.interceptor;
+
+import com.opensymphony.xwork.Action;
+import net.jsunit.RemoteMachineServerHitter;
+import net.jsunit.action.RemoteRunnerHitterAware;
+
+public class RemoteRunnerHitterInterceptor extends JsUnitInterceptor {
+
+    protected void execute(Action targetAction) {
+        RemoteRunnerHitterAware aware = ((RemoteRunnerHitterAware) targetAction);
+        aware.setRemoteRunnerHitter(new RemoteMachineServerHitter());
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/RequestSourceInterceptor.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/RequestSourceInterceptor.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/RequestSourceInterceptor.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,15 @@
+package net.jsunit.interceptor;
+
+import com.opensymphony.webwork.ServletActionContext;
+import com.opensymphony.xwork.Action;
+import net.jsunit.action.RequestSourceAware;
+
+public class RequestSourceInterceptor extends JsUnitInterceptor {
+
+    protected void execute(Action targetAction) {
+        RequestSourceAware aware = ((RequestSourceAware) targetAction);
+        aware.setRequestIPAddress(ServletActionContext.getRequest().getRemoteAddr());
+        aware.setRequestHost(ServletActionContext.getRequest().getRemoteHost());
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/VersionGrabberInterceptor.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/VersionGrabberInterceptor.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/source_server/net/jsunit/interceptor/VersionGrabberInterceptor.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,12 @@
+package net.jsunit.interceptor;
+
+import com.opensymphony.xwork.Action;
+import net.jsunit.version.JsUnitWebsiteVersionGrabber;
+import net.jsunit.action.VersionGrabberAware;
+
+public class VersionGrabberInterceptor extends JsUnitInterceptor {
+    protected void execute(Action targetAction) {
+        VersionGrabberAware aware = ((VersionGrabberAware) targetAction);
+        aware.setVersionGrabber(new JsUnitWebsiteVersionGrabber());
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/testlib/ashcroft.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/testlib/ashcroft.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/testlib/httpunit-1.5.4.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/testlib/httpunit-1.5.4.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/testlib/js-1.5R4.1.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/testlib/js-1.5R4.1.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/testlib/jwebunit-1.2.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/testlib/jwebunit-1.2.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/testlib/nekohtml-0.8.1.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/testlib/nekohtml-0.8.1.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/testlib/xml-apis-1.0.b2.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/testlib/xml-apis-1.0.b2.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/BrowserLaunchSpecificationTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/BrowserLaunchSpecificationTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/BrowserLaunchSpecificationTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,26 @@
+package net.jsunit;
+
+import junit.framework.TestCase;
+import net.jsunit.model.Browser;
+
+public class BrowserLaunchSpecificationTest extends TestCase {
+
+    public void testNoOverride() {
+        BrowserLaunchSpecification spec = new BrowserLaunchSpecification(new Browser("mybrowser.exe", 0));
+        assertFalse(spec.hasOverrideUrl());
+        assertNull(spec.getOverrideUrl());
+
+        spec = new BrowserLaunchSpecification(new Browser("mybrowser.exe", 0), " ");
+        assertFalse(spec.hasOverrideUrl());
+    }
+
+    public void testOverride() {
+        BrowserLaunchSpecification spec = new BrowserLaunchSpecification(
+                new Browser("mybrowser.exe", 0),
+                "http://www.example.com"
+        );
+        assertTrue(spec.hasOverrideUrl());
+        assertEquals("http://www.example.com", spec.getOverrideUrl());
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/ClientServerConnectionTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/ClientServerConnectionTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/ClientServerConnectionTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,43 @@
+package net.jsunit;
+
+import junit.framework.TestCase;
+
+public class ClientServerConnectionTest extends TestCase {
+
+    private ServerSideConnection serverSideConnection;
+    private ClientSideConnection clientSideConnection;
+    private MockMessageReceiver mockReceiver1;
+    private MockMessageReceiver mockReceiver2;
+
+    public void setUp() throws Exception {
+        super.setUp();
+        mockReceiver1 = new MockMessageReceiver();
+        mockReceiver2 = new MockMessageReceiver();
+        serverSideConnection = new ServerSideConnection(mockReceiver1, 8083);
+        clientSideConnection = new ClientSideConnection(mockReceiver2, 8083);
+        clientSideConnection.start();
+        serverSideConnection.connect();
+
+        while (!serverSideConnection.isConnected() || !clientSideConnection.isRunning())
+            Thread.sleep(3);
+    }
+
+    public void tearDown() throws Exception {
+        serverSideConnection.shutDown();
+        clientSideConnection.shutdown();
+        super.tearDown();
+    }
+
+    public void testSimple() throws InterruptedException {
+        serverSideConnection.sendMessage("hello");
+        while (mockReceiver2.message == null)
+            Thread.sleep(3);
+        assertEquals("hello", mockReceiver2.message);
+
+        clientSideConnection.sendMessage("bonjour");
+        while (mockReceiver1.message == null)
+            Thread.sleep(3);
+        assertEquals("bonjour", mockReceiver1.message);
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/ClientServerInteractionTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/ClientServerInteractionTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/ClientServerInteractionTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,36 @@
+package net.jsunit;
+
+import junit.framework.TestCase;
+import net.jsunit.model.Browser;
+import net.jsunit.model.DummyBrowserSource;
+
+public class ClientServerInteractionTest extends TestCase {
+
+    private RemoteTestRunClient client;
+    private TestRunNotifierServer server;
+    private MockTestRunListener mockTestRunListener;
+
+    public void setUp() throws Exception {
+        super.setUp();
+        mockTestRunListener = new MockTestRunListener();
+        client = new RemoteTestRunClient(new DummyBrowserSource("mybrowser.exe", 4), mockTestRunListener, 8083);
+        client.startListening();
+        server = new TestRunNotifierServer(new MockBrowserTestRunner(), 8083);
+        server.testRunStarted();
+    }
+
+    public void tearDown() throws Exception {
+        server.testRunFinished();
+        client.stopListening();
+        super.tearDown();
+    }
+
+    public void testSimple() throws InterruptedException {
+
+        server.browserTestRunStarted(new Browser("mybrowser.exe", 4));
+        while (!mockTestRunListener.browserTestRunStartedCalled)
+            Thread.sleep(3);
+        assertEquals(new Browser("mybrowser.exe", 4), mockTestRunListener.browser);
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/DistributedTestRunResultTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/DistributedTestRunResultTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/DistributedTestRunResultTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,94 @@
+package net.jsunit;
+
+import junit.framework.TestCase;
+import net.jsunit.model.BrowserResult;
+import net.jsunit.model.DistributedTestRunResult;
+import net.jsunit.model.ResultType;
+import net.jsunit.model.TestRunResult;
+import net.jsunit.utility.XmlUtility;
+
+import java.net.URL;
+
+public class DistributedTestRunResultTest extends TestCase {
+
+    public void testSimple() throws Exception {
+        DistributedTestRunResult distributedResult = new DistributedTestRunResult();
+
+        TestRunResult result1 = new TestRunResult();
+        result1.addBrowserResult(successResult());
+        result1.addBrowserResult(successResult());
+        distributedResult.addTestRunResult(result1);
+
+        assertEquals(ResultType.SUCCESS, distributedResult.getResultType());
+        assertTrue(distributedResult.wasSuccessful());
+
+        TestRunResult result2 = new TestRunResult();
+        result2.addBrowserResult(failureResult());
+        result2.addBrowserResult(errorResult());
+        distributedResult.addTestRunResult(result2);
+
+        assertEquals(ResultType.ERROR, distributedResult.getResultType());
+        assertFalse(distributedResult.wasSuccessful());
+        assertEquals(1, distributedResult.getFailureCount());
+        assertEquals(1, distributedResult.getErrorCount());
+    }
+
+    public void testUnresponsiveRemoteURL() throws Exception {
+        DistributedTestRunResult distributedResult = new DistributedTestRunResult();
+
+        TestRunResult result1 = new TestRunResult();
+        result1.addBrowserResult(successResult());
+        result1.addBrowserResult(successResult());
+        distributedResult.addTestRunResult(result1);
+
+        TestRunResult result2 = new TestRunResult(new URL("http://my.domain.com:8201"));
+        result2.setUnresponsive();
+        distributedResult.addTestRunResult(result2);
+
+        TestRunResult result3 = new TestRunResult(new URL("http://my.domain.com:8201"));
+        result3.setUnresponsive();
+        distributedResult.addTestRunResult(result3);
+
+        assertEquals(ResultType.UNRESPONSIVE, distributedResult.getResultType());
+    }
+
+    public void testAsXml() throws Exception {
+        DistributedTestRunResult distributedResult = new DistributedTestRunResult();
+
+        TestRunResult result1 = new TestRunResult();
+        result1.addBrowserResult(successResult());
+        result1.addBrowserResult(successResult());
+        distributedResult.addTestRunResult(result1);
+
+        TestRunResult result2 = new TestRunResult();
+        result2.addBrowserResult(failureResult());
+        result2.addBrowserResult(errorResult());
+        distributedResult.addTestRunResult(result2);
+
+        TestRunResult result3 = new TestRunResult(new URL("http://my.domain.com:4732"));
+        result3.setUnresponsive();
+        distributedResult.addTestRunResult(result3);
+
+        assertEquals(
+                "<distributedTestRunResult type=\"UNRESPONSIVE\">" +
+                        XmlUtility.asString(result1.asXml()) +
+                        XmlUtility.asString(result2.asXml()) +
+                        "<testRunResult type=\"UNRESPONSIVE\" url=\"http://my.domain.com:4732\" />" +
+                        "</distributedTestRunResult>",
+                XmlUtility.asString(distributedResult.asXml())
+        );
+    }
+
+    private BrowserResult successResult() {
+        return new BrowserResult();
+    }
+
+    private BrowserResult failureResult() {
+        return new DummyBrowserResult(false, 1, 0);
+    }
+
+    private BrowserResult errorResult() {
+        return new DummyBrowserResult(false, 0, 1);
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/DummyBrowserResult.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/DummyBrowserResult.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/DummyBrowserResult.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,43 @@
+package net.jsunit;
+
+import net.jsunit.model.BrowserResult;
+import net.jsunit.model.ResultType;
+import org.jdom.Document;
+
+public class DummyBrowserResult extends BrowserResult {
+
+    private final boolean success;
+    private final int failureCount;
+    private final int errorCount;
+
+    public DummyBrowserResult(boolean success, int failureCount, int errorCount) {
+        this.success = success;
+        this.failureCount = failureCount;
+        this.errorCount = errorCount;
+    }
+
+    public boolean wasSuccessful() {
+        return success;
+    }
+
+    public int getFailureCount() {
+        return failureCount;
+    }
+
+    public int getErrorCount() {
+        return errorCount;
+    }
+
+    public ResultType getResultType() {
+        if (getErrorCount() > 0)
+            return ResultType.ERROR;
+        if (getFailureCount() > 0)
+            return ResultType.FAILURE;
+        return ResultType.SUCCESS;
+    }
+
+    public Document asXmlDocument() {
+        return new Document(asXml());
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/MockBrowserTestRunner.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/MockBrowserTestRunner.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/MockBrowserTestRunner.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,77 @@
+package net.jsunit;
+
+import net.jsunit.model.Browser;
+import net.jsunit.model.BrowserResult;
+import org.jdom.Element;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class MockBrowserTestRunner implements BrowserTestRunner {
+
+    public boolean disposeCalled;
+    public BrowserResult acceptedResult;
+    public BrowserResult resultToReturn;
+    public boolean shouldSucceed;
+    public String idPassed;
+    public Integer browserIdPassed;
+    public int timeoutSeconds;
+    public boolean hasReceivedResult;
+    public List<String> logMessages = new ArrayList<String>();
+    public List<BrowserLaunchSpecification> launchSpecs = new ArrayList<BrowserLaunchSpecification>();
+
+    public void startTestRun() {
+    }
+
+    public void finishTestRun() {
+    }
+
+    public long launchBrowserTestRun(BrowserLaunchSpecification launchSpec) {
+        launchSpecs.add(launchSpec);
+        return 0;
+    }
+
+    public void accept(BrowserResult result) {
+        this.acceptedResult = result;
+    }
+
+    public boolean hasReceivedResultSince(long launchTime) {
+        return hasReceivedResult;
+    }
+
+    public BrowserResult lastResult() {
+        return new DummyBrowserResult(shouldSucceed, shouldSucceed ? 0 : 1, 0);
+    }
+
+    public void dispose() {
+        disposeCalled = true;
+    }
+
+    public BrowserResult findResultWithId(String id, int browserId) throws InvalidBrowserIdException {
+        idPassed = id;
+        browserIdPassed = browserId;
+        return resultToReturn;
+    }
+
+    public void logStatus(String message) {
+        logMessages.add(message);
+    }
+
+    public List<Browser> getBrowsers() {
+        return Arrays.asList(new Browser[]{new Browser("mybrowser1.exe", 0), new Browser("mybrowser2.exe", 1)});
+    }
+
+    public int timeoutSeconds() {
+        return timeoutSeconds;
+    }
+
+    public Element asXml() {
+        return null;
+    }
+
+    public boolean isAlive() {
+        return true;
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/MockMessageReceiver.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/MockMessageReceiver.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/MockMessageReceiver.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,14 @@
+/**
+ * 
+ */
+package net.jsunit;
+
+class MockMessageReceiver implements MessageReceiver {
+
+    public String message;
+
+    public void messageReceived(String message) {
+        this.message = message;
+    }
+
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/MockTestRunListener.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/MockTestRunListener.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/MockTestRunListener.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,49 @@
+package net.jsunit;
+
+import net.jsunit.model.Browser;
+import net.jsunit.model.BrowserResult;
+
+public class MockTestRunListener implements TestRunListener {
+
+    public boolean testRunStartedCalled;
+    public boolean testRunFinishedCalled;
+    public boolean browserTestRunStartedCalled;
+    public boolean browserTestRunFinishedCalled;
+    public Browser browser;
+    public boolean isReady;
+    public BrowserResult result;
+
+    public void browserTestRunFinished(Browser browser, BrowserResult result) {
+        browserTestRunFinishedCalled = true;
+        this.browser = browser;
+        this.result = result;
+    }
+
+    public void browserTestRunStarted(Browser browser) {
+        browserTestRunStartedCalled = true;
+        this.browser = browser;
+    }
+
+    public boolean isReady() {
+        return isReady;
+    }
+
+    public void testRunStarted() {
+        testRunStartedCalled = true;
+    }
+
+    public void testRunFinished() {
+        testRunFinishedCalled = true;
+    }
+
+    public void reset() {
+        testRunStartedCalled = false;
+        testRunFinishedCalled = false;
+        browserTestRunStartedCalled = false;
+        browserTestRunFinishedCalled = false;
+        browser = null;
+        isReady = false;
+        result = null;
+    }
+
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/RemoteTestRunClientTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/RemoteTestRunClientTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/RemoteTestRunClientTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,58 @@
+package net.jsunit;
+
+import junit.framework.TestCase;
+import net.jsunit.model.Browser;
+import net.jsunit.model.BrowserResult;
+import net.jsunit.model.DummyBrowserSource;
+import net.jsunit.utility.XmlUtility;
+
+public class RemoteTestRunClientTest extends TestCase {
+
+    private MockTestRunListener listener;
+    private RemoteTestRunClient client;
+
+    public void setUp() throws Exception {
+        super.setUp();
+        listener = new MockTestRunListener();
+        client = new RemoteTestRunClient(new DummyBrowserSource("mybrowser.exe", 3), listener, -1);
+    }
+
+    public void testTestRunStartedMessage() {
+        client.messageReceived("testRunStarted");
+        assertTrue(listener.testRunStartedCalled);
+    }
+
+    public void testTestRunFinishedMessage() {
+        client.messageReceived("testRunFinished");
+        assertTrue(listener.testRunFinishedCalled);
+    }
+
+    public void testBrowserTestRunStartedMessage() {
+        client.messageReceived("browserTestRunStarted");
+        client.messageReceived("3");
+        assertTrue(listener.browserTestRunStartedCalled);
+        assertEquals(new Browser("mybrowser.exe", 3), listener.browser);
+    }
+
+    public void testBrowserTestRunFinishedMessage() {
+        BrowserResult result = new BrowserResult();
+        result.setBaseURL("http://www.example.com");
+        result.setId("1234329439824");
+        result.setJsUnitVersion("905.43");
+        result.setRemoteAddress("http://123.45.67.89");
+        result.setTime(123.45);
+        result.setUserAgent("my browser version 5.6");
+        result.setTestCaseStrings(new String[]{"file:///dummy/path/dummyPage.html:testFoo|1.3|S||"});
+        client.messageReceived("browserTestRunFinished");
+        client.messageReceived("3");
+        String xml = XmlUtility.asString(result.asXmlDocument());
+        String[] lines = xml.split("\r\n");
+        for (String line : lines)
+            client.messageReceived(line);
+        client.messageReceived("endXml");
+        assertTrue(listener.browserTestRunFinishedCalled);
+        assertEquals(new Browser("mybrowser.exe", 3), listener.browser);
+        assertEquals(xml, XmlUtility.asString(listener.result.asXmlDocument()));
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/StubConfigurationSource.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/StubConfigurationSource.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/StubConfigurationSource.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,51 @@
+package net.jsunit;
+
+import net.jsunit.configuration.ConfigurationSource;
+
+public class StubConfigurationSource implements ConfigurationSource {
+
+    public String browserFileNames() {
+        return null;
+    }
+
+    public String closeBrowsersAfterTestRuns() {
+        return null;
+    }
+
+    public String description() {
+        return null;
+    }
+
+    public String logsDirectory() {
+        return null;
+    }
+
+    public String logStatus() {
+        return null;
+    }
+
+    public String port() {
+        return null;
+    }
+
+    public String remoteMachineURLs() {
+        return null;
+    }
+
+    public String resourceBase() {
+        return null;
+    }
+
+    public String timeoutSeconds() {
+        return null;
+    }
+
+    public String url() {
+        return null;
+    }
+
+    public String ignoreUnresponsiveRemoteMachines() {
+        return null;
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/TestRunNotifierServerTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/TestRunNotifierServerTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/TestRunNotifierServerTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,84 @@
+package net.jsunit;
+
+import junit.framework.TestCase;
+import net.jsunit.model.Browser;
+import net.jsunit.utility.XmlUtility;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestRunNotifierServerTest extends TestCase implements MessageReceiver {
+
+    private TestRunNotifierServer server;
+    private ClientSideConnection clientSideConnection;
+    private List<String> messages = new ArrayList<String>();
+    private MockBrowserTestRunner mockRunner;
+
+    public void setUp() throws Exception {
+        super.setUp();
+        mockRunner = new MockBrowserTestRunner();
+        server = new TestRunNotifierServer(mockRunner, 8083);
+        clientSideConnection = new ClientSideConnection(this, 8083);
+        new Thread() {
+            public void run() {
+                server.testRunStarted();
+            }
+        }.start();
+
+        clientSideConnection.start();
+        waitForServerConnectionToStartRunning();
+    }
+
+    public void testMessagesSentAsTestRunProceeds() throws InterruptedException {
+        while (messages.size() < 1)
+            Thread.sleep(10);
+
+        assertEquals(1, messages.size());
+        assertEquals("testRunStarted", messages.get(0));
+
+        server.browserTestRunStarted(new Browser("mybrowser1.exe", 0));
+        while (messages.size() < 3)
+            Thread.sleep(10);
+
+        assertEquals("browserTestRunStarted", messages.get(1));
+        assertEquals("0", messages.get(2));
+
+        DummyBrowserResult browserResult = new DummyBrowserResult(false, 2, 3);
+        server.browserTestRunFinished(new Browser("mybrowser2.exe", 1), browserResult);
+        while (messages.size() < 8)
+            Thread.sleep(10);
+
+        assertEquals("browserTestRunFinished", messages.get(3));
+        assertEquals("1", messages.get(4));
+        String line1 = messages.get(5);
+        String line2 = messages.get(6);
+        String line3 = messages.get(7);
+        assertEquals(XmlUtility.asString(browserResult.asXmlDocument()), line1 + "\r\n" + line2 + "\r\n" + line3);
+
+        assertEquals("endXml", messages.get(8));
+    }
+
+    public void testStopRunner() throws InterruptedException {
+        assertFalse(mockRunner.disposeCalled);
+        clientSideConnection.sendMessage("foo");
+        assertFalse(mockRunner.disposeCalled);
+        clientSideConnection.sendMessage("stop");
+        while (!mockRunner.disposeCalled)
+            Thread.sleep(10);
+    }
+
+    private void waitForServerConnectionToStartRunning() throws InterruptedException {
+        while (!clientSideConnection.isRunning() || !server.isReady())
+            Thread.sleep(10);
+    }
+
+    public void messageReceived(String message) {
+        messages.add(message);
+    }
+
+    public void tearDown() throws Exception {
+        server.testRunFinished();
+        clientSideConnection.shutdown();
+        super.tearDown();
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/TestRunResultTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/TestRunResultTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/TestRunResultTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,101 @@
+package net.jsunit;
+
+import junit.framework.TestCase;
+import net.jsunit.model.BrowserResult;
+import net.jsunit.model.ResultType;
+import net.jsunit.model.TestRunResult;
+import net.jsunit.utility.XmlUtility;
+
+import java.net.URL;
+
+public class TestRunResultTest extends TestCase {
+    private TestRunResult testRunResult;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        testRunResult = new TestRunResult(new URL("http://www.example.com"));
+    }
+
+    public void testSuccess() throws Exception {
+        testRunResult.addBrowserResult(successResult());
+        testRunResult.addBrowserResult(successResult());
+        assertTrue(testRunResult.wasSuccessful());
+        assertEquals(0, testRunResult.getErrorCount());
+        assertEquals(0, testRunResult.getFailureCount());
+        assertFalse(testRunResult.wasUnresponsive());
+    }
+
+    public void testFailuresAndErrors() throws Exception {
+        testRunResult.addBrowserResult(failureResult());
+        assertFalse(testRunResult.wasSuccessful());
+        assertEquals(0, testRunResult.getErrorCount());
+        assertEquals(1, testRunResult.getFailureCount());
+
+        testRunResult.addBrowserResult(failureResult());
+        assertFalse(testRunResult.wasSuccessful());
+        assertEquals(0, testRunResult.getErrorCount());
+        assertEquals(2, testRunResult.getFailureCount());
+
+        testRunResult.addBrowserResult(errorResult());
+        assertFalse(testRunResult.wasSuccessful());
+        assertEquals(1, testRunResult.getErrorCount());
+        assertEquals(2, testRunResult.getFailureCount());
+    }
+
+    public void testAsXml() throws Exception {
+        testRunResult.addBrowserResult(successResult());
+        testRunResult.addBrowserResult(failureResult());
+        testRunResult.addBrowserResult(errorResult());
+        testRunResult.setOsString("my cool os");
+        testRunResult.setIpAddress("127.0.0.1");
+        testRunResult.setHostname("machine.example.com");
+        testRunResult.setURL(new URL("http://www.example.com"));
+        assertEquals(
+                "<testRunResult type=\"ERROR\" url=\"http://www.example.com\">" +
+                        "<properties>" +
+                        "<property name=\"os\" value=\"my cool os\" />" +
+                        "<property name=\"ipAddress\" value=\"127.0.0.1\" />" +
+                        "<property name=\"hostname\" value=\"machine.example.com\" />" +
+                        "</properties>" +
+                        successResult().asXmlFragment() +
+                        failureResult().asXmlFragment() +
+                        errorResult().asXmlFragment() +
+                        "</testRunResult>",
+                XmlUtility.asString(testRunResult.asXml())
+        );
+    }
+
+    public void testUnresponsive() throws Exception {
+        testRunResult.setUnresponsive();
+        assertTrue(testRunResult.wasUnresponsive());
+        assertEquals(ResultType.UNRESPONSIVE, testRunResult.getResultType());
+        assertEquals(
+                "<testRunResult type=\"UNRESPONSIVE\" url=\"http://www.example.com\" />",
+                XmlUtility.asString(testRunResult.asXml())
+        );
+    }
+
+    public void testAsXmlWithNoUrl() throws Exception {
+        TestRunResult result = new TestRunResult();
+        assertEquals("<testRunResult type=\"SUCCESS\" />", XmlUtility.asString(result.asXml()));
+    }
+
+    private BrowserResult successResult() {
+        BrowserResult browserResult = new BrowserResult();
+        browserResult.setId("foo");
+        return browserResult;
+    }
+
+    private BrowserResult failureResult() {
+        DummyBrowserResult dummyBrowserResult = new DummyBrowserResult(false, 1, 0);
+        dummyBrowserResult.setId("foo");
+        return dummyBrowserResult;
+    }
+
+    private BrowserResult errorResult() {
+        DummyBrowserResult dummyBrowserResult = new DummyBrowserResult(false, 0, 1);
+        dummyBrowserResult.setId("foo");
+        return dummyBrowserResult;
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/configuration/ArgumentsConfigurationSourceTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/configuration/ArgumentsConfigurationSourceTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/configuration/ArgumentsConfigurationSourceTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,59 @@
+package net.jsunit.configuration;
+
+import junit.framework.TestCase;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class ArgumentsConfigurationSourceTest extends TestCase {
+    public ArgumentsConfigurationSourceTest(String name) {
+        super(name);
+    }
+
+    public void testSimple() throws Exception {
+        List<String> args = Arrays.asList(new String[]{
+                "-browserFileNames", "aaa",
+                "-closeBrowsersAfterTestRuns", "bbb",
+                "-logsDirectory", "ccc",
+                "-logStatus", "ddd",
+                "-port", "eee",
+                "-remoteMachineURLs", "fff",
+                "-resourceBase", "ggg",
+                "-timeoutSeconds", "hhh",
+                "-url", "iii",
+        });
+        ArgumentsConfigurationSource source = new ArgumentsConfigurationSource(args);
+        assertEquals("aaa", source.browserFileNames());
+        assertEquals("bbb", source.closeBrowsersAfterTestRuns());
+        assertEquals("ccc", source.logsDirectory());
+        assertEquals("eee", source.port());
+        assertEquals("fff", source.remoteMachineURLs());
+        assertEquals("ggg", source.resourceBase());
+        assertEquals("hhh", source.timeoutSeconds());
+        assertEquals("iii", source.url());
+    }
+
+    public void testIncomplete() {
+        List<String> args = Arrays.asList(new String[]{
+                "-browserFileNames",
+                "-closeBrowsersAfterTestRuns",
+                "-logsDirectory", "ccc",
+                "-logStatus", "ddd",
+                "-port", "eee",
+                "-remoteMachineURLs",
+                "-resourceBase", "ggg",
+                "-timeoutSeconds", "hhh",
+                "-url", "iii",
+        });
+        ArgumentsConfigurationSource source = new ArgumentsConfigurationSource(args);
+        assertEquals("", source.browserFileNames());
+        assertEquals("", source.closeBrowsersAfterTestRuns());
+        assertEquals("ccc", source.logsDirectory());
+        assertEquals("eee", source.port());
+        assertEquals("", source.remoteMachineURLs());
+        assertEquals("ggg", source.resourceBase());
+        assertEquals("hhh", source.timeoutSeconds());
+        assertEquals("iii", source.url());
+    }
+
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/configuration/CompositeConfigurationSourceTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/configuration/CompositeConfigurationSourceTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/configuration/CompositeConfigurationSourceTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,38 @@
+package net.jsunit.configuration;
+
+import junit.framework.TestCase;
+import net.jsunit.StubConfigurationSource;
+
+import java.io.FileNotFoundException;
+
+public class CompositeConfigurationSourceTest extends TestCase {
+
+    public void testSingleSource() throws FileNotFoundException {
+        CompositeConfigurationSource compositeSource = new CompositeConfigurationSource(new Source1());
+        assertEquals("foo", compositeSource.url());
+    }
+
+    public void testPrecedence() {
+        CompositeConfigurationSource compositeSource = new CompositeConfigurationSource(
+            new Source1(),
+            new Source2());
+        assertEquals("foo", compositeSource.url());
+        assertEquals("1234", compositeSource.port());
+    }
+    
+    public static class Source1 extends StubConfigurationSource {
+        public String url() {
+            return "foo";
+        }
+    }
+
+    public static class Source2 extends StubConfigurationSource {
+        public String url() {
+            return "bar";
+        }
+
+        public String port() {
+            return "1234";
+        }
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/configuration/ConfigurationSourceResolutionTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/configuration/ConfigurationSourceResolutionTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/configuration/ConfigurationSourceResolutionTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,38 @@
+package net.jsunit.configuration;
+
+import junit.framework.TestCase;
+import net.jsunit.utility.FileUtility;
+
+import java.io.File;
+
+public class ConfigurationSourceResolutionTest extends TestCase {
+
+    public void testResolveArgumentsConfiguration() {
+        ConfigurationSource source = Configuration.resolveSource(new String[]{"-url", "foo"});
+        assertEquals("foo", source.url());
+    }
+
+    public void testResolveEnvironmentVariablesConfiguration() {
+        System.setProperty(ConfigurationProperty.URL.getName(), "http://localhost:8080/");
+        ConfigurationSource source = Configuration.resolveSource(new String[]{});
+        assertEquals("http://localhost:8080/", source.url());
+    }
+
+    public void testResolvePropertiesConfiguration() {
+        writePropertiesFile(PropertiesFileConfigurationSource.PROPERTIES_FILE_NAME,
+                            ConfigurationProperty.BROWSER_FILE_NAMES.getName() + "=aaa");
+        ConfigurationSource source = Configuration.resolveSource(new String[]{});
+        assertEquals("aaa", source.browserFileNames());
+    }
+
+    private void writePropertiesFile(String fileName, String contents) {
+        FileUtility.write(new File(fileName), contents);
+    }
+
+    protected void tearDown() throws Exception {
+        System.getProperties().remove(ConfigurationProperty.URL.getName());
+        FileUtility.delete(new File(PropertiesFileConfigurationSource.PROPERTIES_FILE_NAME));
+        super.tearDown();
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/configuration/ConfigurationTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/configuration/ConfigurationTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/configuration/ConfigurationTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,315 @@
+package net.jsunit.configuration;
+
+import junit.framework.TestCase;
+import net.jsunit.StubConfigurationSource;
+import net.jsunit.model.Browser;
+import net.jsunit.utility.SystemUtility;
+import net.jsunit.utility.XmlUtility;
+
+import java.io.File;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ConfigurationTest extends TestCase {
+
+    public void testFull() throws Exception {
+        Configuration configuration = new Configuration(new FullValidForBothConfigurationSource());
+        List<Browser> expectedBrowsers = new ArrayList<Browser>();
+        expectedBrowsers.add(new Browser("browser1.exe", 0));
+        expectedBrowsers.add(new Browser("browser2.exe", 1));
+        assertEquals(expectedBrowsers, configuration.getBrowsers());
+        assertEquals(new File("logs" + File.separator + "directory"), configuration.getLogsDirectory());
+        assertEquals(1234, configuration.getPort());
+        assertEquals(new File("resource" + File.separator + "base"), configuration.getResourceBase());
+        assertEquals("http://www.example.com:1234/", configuration.getTestURL().toString());
+        assertTrue(configuration.shouldCloseBrowsersAfterTestRuns());
+        assertEquals(76, configuration.getTimeoutSeconds());
+        List<URL> expectedRemoteMachineURLs = new ArrayList<URL>();
+        expectedRemoteMachineURLs.add(new URL("http://localhost:8081/jsunit"));
+        expectedRemoteMachineURLs.add(new URL("http://127.0.0.1:8082/jsunit"));
+        assertEquals(expectedRemoteMachineURLs, configuration.getRemoteMachineURLs());
+        assertTrue(configuration.shouldIgnoreUnresponsiveRemoteMachines());
+
+        assertTrue(configuration.isValidFor(ServerType.STANDARD));
+        assertTrue(configuration.isValidFor(ServerType.FARM));
+    }
+
+    public void testMinimal() throws Exception {
+        Configuration configuration = new Configuration(new MinimalValidForBothConfigurationSource());
+        assertEquals(new File("."), configuration.getResourceBase());
+        assertEquals(new File("logs"), configuration.getLogsDirectory());
+        assertTrue(configuration.shouldCloseBrowsersAfterTestRuns());
+        assertEquals(60, configuration.getTimeoutSeconds());
+        assertFalse(configuration.shouldIgnoreUnresponsiveRemoteMachines());
+
+        assertTrue(configuration.isValidFor(ServerType.STANDARD));
+        assertTrue(configuration.isValidFor(ServerType.FARM));
+    }
+
+    public void testBadRemoteMachineURLs() throws Exception {
+        try {
+            new Configuration(new StubConfigurationSource() {
+                public String remoteMachineURLs() {
+                    return "invalid url";
+                }
+            });
+            fail();
+        } catch (ConfigurationException e) {
+        }
+    }
+
+    public void testBadURL() throws Exception {
+        try {
+            new Configuration(new StubConfigurationSource() {
+                public String url() {
+                    return "invalid url";
+                }
+            });
+            fail();
+        } catch (ConfigurationException e) {
+        }
+    }
+
+    public void testBadPort() throws Exception {
+        try {
+            new Configuration(new StubConfigurationSource() {
+                public String port() {
+                    return "invalid number";
+                }
+            });
+            fail();
+        } catch (ConfigurationException e) {
+        }
+    }
+
+    public void testBadTimeoutSeconds() throws Exception {
+        try {
+            new Configuration(new StubConfigurationSource() {
+                public String timeoutSeconds() {
+                    return "invalid number";
+                }
+            });
+            fail();
+        } catch (ConfigurationException e) {
+        }
+    }
+
+    public void testValidForStandardInvalidForFarm() throws Exception {
+        Configuration configuration = new Configuration(new ValidForStandardInvalidForFarmConfigurationSource());
+        assertTrue(configuration.isValidFor(ServerType.STANDARD));
+        assertFalse(configuration.isValidFor(ServerType.FARM));
+        List<ConfigurationProperty> invalidProperties = ServerType.FARM.getPropertiesInvalidFor(configuration);
+        assertEquals(1, invalidProperties.size());
+        assertEquals(ConfigurationProperty.REMOTE_MACHINE_URLS, invalidProperties.get(0));
+    }
+
+    public void testAsXmlForStandardConfiguration() throws Exception {
+        FullValidForBothConfigurationSource source = new FullValidForBothConfigurationSource();
+        Configuration configuration = new Configuration(source);
+        File logsDirectory = new File(source.logsDirectory());
+        File resourceBase = new File(source.resourceBase());
+        String expectedXML = "<configuration type=\"" + ServerType.STANDARD.name() + "\">" +
+                "<os>" + SystemUtility.osString() + "</os>" +
+                "<ipAddress>" + SystemUtility.ipAddress() + "</ipAddress>" +
+                "<hostname>" + SystemUtility.hostname() + "</hostname>" +
+                "<browserFileNames>" +
+                "<browserFileName id=\"0\">browser1.exe</browserFileName>" +
+                "<browserFileName id=\"1\">browser2.exe</browserFileName>" +
+                "</browserFileNames>" +
+                "<closeBrowsersAfterTestRuns>true</closeBrowsersAfterTestRuns>" +
+                "<description>This is the best server ever</description>" +
+                "<logsDirectory>" + logsDirectory.getAbsolutePath() + "</logsDirectory>" +
+                "<port>1234</port>" +
+                "<resourceBase>" + resourceBase.getAbsolutePath() + "</resourceBase>" +
+                "<timeoutSeconds>76</timeoutSeconds>" +
+                "<url>http://www.example.com:1234/</url>" +
+                "</configuration>";
+        assertEquals(expectedXML, XmlUtility.asString(configuration.asXml(ServerType.STANDARD)));
+    }
+
+    public void testAsXmlForStandardTemporaryConfiguration() throws Exception {
+        FullValidForBothConfigurationSource source = new FullValidForBothConfigurationSource();
+        Configuration configuration = new Configuration(source);
+        File logsDirectory = new File(source.logsDirectory());
+        File resourceBase = new File(source.resourceBase());
+        String expectedXML = "<configuration type=\"" + ServerType.STANDARD_TEMPORARY.name() + "\">" +
+                "<os>" + SystemUtility.osString() + "</os>" +
+                "<ipAddress>" + SystemUtility.ipAddress() + "</ipAddress>" +
+                "<hostname>" + SystemUtility.hostname() + "</hostname>" +
+                "<browserFileNames>" +
+                "<browserFileName id=\"0\">browser1.exe</browserFileName>" +
+                "<browserFileName id=\"1\">browser2.exe</browserFileName>" +
+                "</browserFileNames>" +
+                "<closeBrowsersAfterTestRuns>true</closeBrowsersAfterTestRuns>" +
+                "<description>This is the best server ever</description>" +
+                "<logsDirectory>" + logsDirectory.getAbsolutePath() + "</logsDirectory>" +
+                "<port>1234</port>" +
+                "<resourceBase>" + resourceBase.getAbsolutePath() + "</resourceBase>" +
+                "<timeoutSeconds>76</timeoutSeconds>" +
+                "<url>http://www.example.com:1234/</url>" +
+                "</configuration>";
+        assertEquals(expectedXML, XmlUtility.asString(configuration.asXml(ServerType.STANDARD_TEMPORARY)));
+    }
+
+    public void testAsXmlForFarmConfiguration() throws Exception {
+        FullValidForBothConfigurationSource source = new FullValidForBothConfigurationSource();
+        Configuration configuration = new Configuration(source);
+        File logsDirectory = new File(source.logsDirectory());
+        File resourceBase = new File(source.resourceBase());
+        assertEquals(
+                "<configuration type=\"" + ServerType.FARM.name() + "\">" +
+                        "<os>" + SystemUtility.osString() + "</os>" +
+                        "<ipAddress>" + SystemUtility.ipAddress() + "</ipAddress>" +
+                        "<hostname>" + SystemUtility.hostname() + "</hostname>" +
+                        "<description>This is the best server ever</description>" +
+                        "<ignoreUnresponsiveRemoteMachines>true</ignoreUnresponsiveRemoteMachines>" +
+                        "<logsDirectory>" + logsDirectory.getAbsolutePath() + "</logsDirectory>" +
+                        "<port>1234</port>" +
+                        "<remoteMachineURLs>" +
+                        "<remoteMachineURL id=\"0\">http://localhost:8081/jsunit</remoteMachineURL>" +
+                        "<remoteMachineURL id=\"1\">http://127.0.0.1:8082/jsunit</remoteMachineURL>" +
+                        "</remoteMachineURLs>" +
+                        "<resourceBase>" + resourceBase.getAbsolutePath() + "</resourceBase>" +
+                        "<url>http://www.example.com:1234/</url>" +
+                        "</configuration>",
+                XmlUtility.asString(configuration.asXml(ServerType.FARM))
+        );
+    }
+
+    public void testGetBrowserById() throws Exception {
+        Configuration configuration = new Configuration(new FullValidForBothConfigurationSource());
+        assertEquals(new Browser("browser1.exe", 0), configuration.getBrowserById(0));
+        assertEquals(new Browser("browser2.exe", 1), configuration.getBrowserById(1));
+        assertNull(configuration.getBrowserById(900));
+    }
+
+    public void testGetRemoteMachineURLById() throws Exception {
+        Configuration configuration = new Configuration(new FullValidForBothConfigurationSource());
+        assertEquals(
+                "http://localhost:8081/jsunit",
+                configuration.getRemoteMachineURLById(0).toString()
+        );
+        assertEquals(
+                "http://127.0.0.1:8082/jsunit",
+                configuration.getRemoteMachineURLById(1).toString()
+        );
+    }
+
+    public void testAsArgumentsArray() throws Exception {
+        Configuration configuration = new Configuration(new FullValidForBothConfigurationSource());
+        String[] arguments = configuration.asArgumentsArray();
+
+        assertEquals(20, arguments.length);
+        int index = 0;
+
+        assertEquals("-browserFileNames", arguments[index++]);
+        assertEquals("browser1.exe,browser2.exe", arguments[index++]);
+
+        assertEquals("-closeBrowsersAfterTestRuns", arguments[index++]);
+        assertEquals("true", arguments[index++]);
+
+        assertEquals("-description", arguments[index++]);
+        assertEquals("This is the best server ever", arguments[index++]);
+
+        assertEquals("-ignoreUnresponsiveRemoteMachines", arguments[index++]);
+        assertEquals("true", arguments[index++]);
+
+        assertEquals("-logsDirectory", arguments[index++]);
+        assertEquals(new File("logs" + File.separator + "directory").getAbsolutePath(), arguments[index++]);
+
+        assertEquals("-port", arguments[index++]);
+        assertEquals("1234", arguments[index++]);
+
+        assertEquals("-remoteMachineURLs", arguments[index++]);
+        assertEquals("http://localhost:8081/jsunit,http://127.0.0.1:8082/jsunit", arguments[index++]);
+
+        assertEquals("-resourceBase", arguments[index++]);
+        assertEquals(new File("resource/base").getAbsolutePath(), arguments[index++]);
+
+        assertEquals("-timeoutSeconds", arguments[index++]);
+        assertEquals("76", arguments[index++]);
+
+        assertEquals("-url", arguments[index++]);
+        assertEquals("http://www.example.com:1234/", arguments[index]);
+    }
+
+    public void testDuplicateBrowserFileNamesAndRemoteMachineURLs() throws Exception {
+        Configuration configuration = new Configuration(new DuplicatesConfigurationSource());
+        List<Browser> browsers = configuration.getBrowsers();
+        assertEquals(3, browsers.size());
+        assertEquals(new Browser("browser1.exe", 0), browsers.get(0));
+        assertEquals(new Browser("browser2.exe", 1), browsers.get(1));
+        assertEquals(new Browser("browser3.exe", 2), browsers.get(2));
+
+        List<URL> remoteMachineURLs = configuration.getRemoteMachineURLs();
+        assertEquals(4, remoteMachineURLs.size());
+        assertEquals("http://machine1:8080/jsunit", remoteMachineURLs.get(0).toString());
+        assertEquals("http://machine2:9090/jsunit", remoteMachineURLs.get(1).toString());
+        assertEquals("http://machine1:8081/jsunit", remoteMachineURLs.get(2).toString());
+        assertEquals("http://machine3:9090/jsunit", remoteMachineURLs.get(3).toString());
+    }
+
+    static class FullValidForBothConfigurationSource implements ConfigurationSource {
+
+        public String resourceBase() {
+            return "resource" + File.separator + "base";
+        }
+
+        public String port() {
+            return "1234";
+        }
+
+        public String logsDirectory() {
+            return "logs" + File.separator + "directory";
+        }
+
+        public String browserFileNames() {
+            return "browser1.exe,browser2.exe";
+        }
+
+        public String url() {
+            return "http://www.example.com:1234/";
+        }
+
+        public String ignoreUnresponsiveRemoteMachines() {
+            return "true";
+        }
+
+        public String closeBrowsersAfterTestRuns() {
+            return "true";
+        }
+
+        public String description() {
+            return "This is the best server ever";
+        }
+
+        public String timeoutSeconds() {
+            return "76";
+        }
+
+        public String remoteMachineURLs() {
+            return "http://localhost:8081,http://127.0.0.1:8082";
+        }
+    }
+
+    static class MinimalValidForBothConfigurationSource extends StubConfigurationSource {
+        public String remoteMachineURLs() {
+            return "http://localhost:8081,http://127.0.0.1:8082";
+        }
+
+    }
+
+    static class ValidForStandardInvalidForFarmConfigurationSource extends StubConfigurationSource {
+    }
+
+    static class DuplicatesConfigurationSource extends StubConfigurationSource {
+        public String browserFileNames() {
+            return "browser1.exe,browser2.exe,browser1.exe,browser1.exe,browser3.exe";
+        }
+
+        public String remoteMachineURLs() {
+            return "http://machine1:8080,http://machine2:9090/jsunit,http://machine1:8081,http://machine1:8080,http://machine1:8080/jsunit,http://machine3:9090";
+        }
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/configuration/EnvironmentVariablesConfigurationSourceTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/configuration/EnvironmentVariablesConfigurationSourceTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/configuration/EnvironmentVariablesConfigurationSourceTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,38 @@
+package net.jsunit.configuration;
+
+import junit.framework.TestCase;
+
+public class EnvironmentVariablesConfigurationSourceTest extends TestCase {
+    private EnvironmentVariablesConfigurationSource source;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        source = new EnvironmentVariablesConfigurationSource();
+    }
+
+    public void testSimple() {
+        System.setProperty(ConfigurationProperty.BROWSER_FILE_NAMES.getName(), "aaa");
+        System.setProperty(ConfigurationProperty.CLOSE_BROWSERS_AFTER_TEST_RUNS.getName(), "bbb");
+        System.setProperty(ConfigurationProperty.LOGS_DIRECTORY.getName(), "ddd");
+        System.setProperty(ConfigurationProperty.PORT.getName(), "eee");
+        System.setProperty(ConfigurationProperty.REMOTE_MACHINE_URLS.getName(), "fff");
+        System.setProperty(ConfigurationProperty.RESOURCE_BASE.getName(), "ggg");
+        System.setProperty(ConfigurationProperty.TIMEOUT_SECONDS.getName(), "hhh");
+        System.setProperty(ConfigurationProperty.URL.getName(), "iii");
+        assertEquals("aaa", source.browserFileNames());
+        assertEquals("bbb", source.closeBrowsersAfterTestRuns());
+        assertEquals("ddd", source.logsDirectory());
+        assertEquals("eee", source.port());
+        assertEquals("fff", source.remoteMachineURLs());
+        assertEquals("ggg", source.resourceBase());
+        assertEquals("hhh", source.timeoutSeconds());
+        assertEquals("iii", source.url());
+    }
+
+    public void tearDown() throws Exception {
+        for (ConfigurationProperty property : ConfigurationProperty.values())
+            System.getProperties().remove(property.getName());
+        super.tearDown();
+    }
+
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/configuration/PropertiesConfigurationSourceTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/configuration/PropertiesConfigurationSourceTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/configuration/PropertiesConfigurationSourceTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,50 @@
+package net.jsunit.configuration;
+
+import junit.framework.TestCase;
+import net.jsunit.utility.FileUtility;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+
+public class PropertiesConfigurationSourceTest extends TestCase {
+
+    public void testNoFile() throws Exception {
+        try {
+            new PropertiesFileConfigurationSource("nosuch.file");
+            fail("Should have thrown a RuntimeException because no properties file exists");
+        } catch (FileNotFoundException e) {
+        }
+    }
+
+    public void testSimple() throws Exception {
+        writePropertiesFile("temp.file");
+        PropertiesFileConfigurationSource configuration = new PropertiesFileConfigurationSource("temp.file");
+        assertEquals("aaa", configuration.browserFileNames());
+        assertEquals("bbb", configuration.closeBrowsersAfterTestRuns());
+        assertEquals("ccc", configuration.logsDirectory());
+        assertEquals("eee", configuration.port());
+        assertEquals("fff", configuration.remoteMachineURLs());
+        assertEquals("ggg", configuration.resourceBase());
+        assertEquals("hhh", configuration.timeoutSeconds());
+        assertEquals("iii", configuration.url());
+    }
+
+    public void tearDown() throws Exception {
+        FileUtility.delete(new File("temp.file"));
+        super.tearDown();
+    }
+
+    private void writePropertiesFile(String fileName) {
+        String contents =
+                ConfigurationProperty.BROWSER_FILE_NAMES.getName() + "=aaa\n" +
+                        ConfigurationProperty.CLOSE_BROWSERS_AFTER_TEST_RUNS.getName() + "=bbb\n" +
+                        ConfigurationProperty.LOGS_DIRECTORY.getName() + "=ccc\n" +
+                        ConfigurationProperty.PORT.getName() + "=eee\n" +
+                        ConfigurationProperty.REMOTE_MACHINE_URLS.getName() + "=fff\n" +
+                        ConfigurationProperty.RESOURCE_BASE.getName() + "=ggg\n" +
+                        ConfigurationProperty.TIMEOUT_SECONDS.getName() + "=hhh\n" +
+                        ConfigurationProperty.URL.getName() + "=iii\n";
+        FileUtility.write(new File(fileName), contents);
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/BrowserResultTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/BrowserResultTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/BrowserResultTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,158 @@
+package net.jsunit.model;
+
+import junit.framework.TestCase;
+import net.jsunit.utility.FileUtility;
+
+import java.io.File;
+import java.util.List;
+
+public class BrowserResultTest extends TestCase {
+    private BrowserResult result;
+
+    private String expectedXmlFragment =
+            "<browserResult id=\"An ID\" time=\"4.3\">" +
+                    "<properties>" +
+                    "<property name=\"browserFileName\" value=\"c:\\Program Files\\Internet Explorer\\iexplore.exe\" />" +
+                    "<property name=\"browserId\" value=\"7\" />" +
+                    "<property name=\"jsUnitVersion\" value=\"2.5\" />" +
+                    "<property name=\"userAgent\" value=\"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\" />" +
+                    "<property name=\"remoteAddress\" value=\"Dummy Remote Address\" />" +
+                    "<property name=\"url\" value=\"http://www.example.com/\" />" +
+                    "</properties>" +
+                    "<testCases>" +
+                    "<testCase name=\"page1.html:testFoo\" time=\"1.3\" />" +
+                    "<testCase name=\"page1.html:testFoo\" time=\"1.3\">" +
+                    "<error>Test Error Message</error>" +
+                    "</testCase>" +
+                    "<testCase name=\"page2.html:testFoo\" time=\"1.3\">" +
+                    "<failure>Test Failure Message</failure>" +
+                    "</testCase>" +
+                    "</testCases>" +
+                    "</browserResult>";
+
+    private BrowserSource browserSource = new DummyBrowserSource("c:\\Program Files\\Internet Explorer\\iexplore.exe", 7);
+
+    public void setUp() throws Exception {
+        super.setUp();
+        result = createBrowserResult();
+        result.setTestCaseStrings(new String[]{
+                "page1.html:testFoo|1.3|S||",
+                "page1.html:testFoo|1.3|E|Test Error Message|",
+                "page2.html:testFoo|1.3|F|Test Failure Message|"}
+        );
+    }
+
+    public void testId() {
+        assertNotNull(result.getId());
+        result = new BrowserResult();
+        result.setId("foo");
+        assertEquals("foo", result.getId());
+    }
+
+    public void testFields() {
+        assertFields(result);
+    }
+
+    public void testXml() {
+        assertEquals(expectedXmlFragment, result.asXmlFragment());
+    }
+
+    public void testResultType() {
+        assertFalse(result.wasSuccessful());
+        assertEquals(ResultType.ERROR, result.getResultType());
+    }
+
+    public void testDisplayString() {
+        assertEquals(ResultType.ERROR.getDisplayString(), result.getDisplayString());
+    }
+
+    public void testBuildFromXmlFile() {
+        File file = null;
+        try {
+            FileUtility.write(new File("resultXml.xml"), expectedXmlFragment);
+            file = new File("resultXml.xml");
+            BrowserResult reconstitutedResult = new BrowserResultBuilder(browserSource).build(file);
+            assertEquals(BrowserResult.class, reconstitutedResult.getClass());
+            assertFields(reconstitutedResult);
+        } finally {
+            if (file != null)
+                file.delete();
+        }
+    }
+
+    public void testBuildFromXmlDocument() {
+        BrowserResult reconstitutedResult = new BrowserResultBuilder(browserSource).build(result.asXmlDocument());
+        assertFields(reconstitutedResult);
+    }
+
+    public void testFailure() {
+        BrowserResult result = createBrowserResult();
+        result.setTestCaseStrings(new String[]{
+                "page.html:testFoo|1.3|S||",
+                "page.html:testBar|1.3|F|Test Failure Message|"
+        });
+        assertFalse(result.wasSuccessful());
+        assertEquals(ResultType.FAILURE, result.getResultType());
+        assertEquals("The test run had 0 error(s) and 1 failure(s).", result.displayString());
+    }
+
+    public void testSuccess() {
+        BrowserResult result = createBrowserResult();
+        result.setTestCaseStrings(new String[]{
+                "page.html:testFoo|1.3|S||",
+                "page.html:testBar|1.3|S||"
+        });
+        assertTrue(result.wasSuccessful());
+        assertEquals(ResultType.SUCCESS, result.getResultType());
+    }
+
+    public void testGetTestPageResults() {
+        List<TestPageResult> testPageResults = result.getTestPageResults();
+        assertEquals(2, testPageResults.size());
+        TestPageResult result1 = testPageResults.get(0);
+        assertEquals("page1.html", result1.getTestPageName());
+        assertEquals(2, result1.getTestCaseResults().size());
+        TestPageResult result2 = testPageResults.get(1);
+        assertEquals("page2.html", result2.getTestPageName());
+        assertEquals(1, result2.getTestCaseResults().size());
+    }
+
+    public void testCompleted() {
+        assertTrue(result.completedTestRun());
+        assertFalse(result.timedOut());
+        assertFalse(result.failedToLaunch());
+        assertFalse(result.externallyShutDown());
+    }
+
+    public void testIsForBrowser() throws Exception {
+        assertFalse(result.isForBrowser(new Browser("mybrowser.exe", 9)));
+        assertFalse(result.isForBrowser(new Browser("c:\\Program Files\\Internet Explorer\\iexplore.exe", 9)));
+        assertFalse(result.isForBrowser(new Browser("mybrowser.exe", 7)));
+        assertTrue(result.isForBrowser(new Browser("c:\\Program Files\\Internet Explorer\\iexplore.exe", 7)));
+    }
+
+    private BrowserResult createBrowserResult() {
+        BrowserResult browserResult = new BrowserResult();
+        browserResult.setBrowser(new Browser("c:\\Program Files\\Internet Explorer\\iexplore.exe", 7));
+        browserResult.setJsUnitVersion("2.5");
+        browserResult.setId("An ID");
+        browserResult.setUserAgent("Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
+        browserResult.setRemoteAddress("Dummy Remote Address");
+        browserResult.setBaseURL("http://www.example.com/");
+        browserResult.setTime(4.3);
+        return browserResult;
+    }
+
+    private void assertFields(BrowserResult aResult) {
+        assertEquals("2.5", aResult.getJsUnitVersion());
+        assertEquals("An ID", aResult.getId());
+        assertEquals("Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)", aResult.getUserAgent());
+        assertEquals("Dummy Remote Address", aResult.getRemoteAddress());
+        assertEquals(4.3d, aResult.getTime(), 0.001d);
+        assertEquals(3, aResult.getTestCaseResults().size());
+        for (TestCaseResult testCaseResult : aResult.getTestCaseResults()) {
+            assertNotNull(testCaseResult);
+        }
+    }
+
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/BrowserTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/BrowserTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/BrowserTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,29 @@
+package net.jsunit.model;
+
+import junit.framework.TestCase;
+
+public class BrowserTest extends TestCase {
+
+    public void testSimple() throws Exception {
+        Browser browser = new Browser("c:\\program files\\internet explorer\\iexplore.exe", 4);
+        assertEquals("c:\\program files\\internet explorer\\iexplore.exe", browser.getFileName());
+        assertEquals(4, browser.getId());
+        assertTrue(browser.hasId(4));
+        assertFalse(browser.hasId(2));
+    }
+
+    public void testKillCommand() throws Exception {
+        Browser browser = new Browser("mybrowser.exe", 0);
+        assertEquals("mybrowser.exe", browser.getFileName());
+        assertNull(browser.getKillCommand());
+
+        browser = new Browser("mybrowser.exe;", 0);
+        assertEquals("mybrowser.exe", browser.getFileName());
+        assertNull(browser.getKillCommand());
+
+        browser = new Browser("mybrowser.exe;kill-mybrowser.bat", 0);
+        assertEquals("mybrowser.exe", browser.getFileName());
+        assertEquals("kill-mybrowser.bat", browser.getKillCommand());
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/DistributedTestRunResultBuilderTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/DistributedTestRunResultBuilderTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/DistributedTestRunResultBuilderTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,43 @@
+package net.jsunit.model;
+
+import junit.framework.TestCase;
+import net.jsunit.DummyBrowserResult;
+import net.jsunit.utility.XmlUtility;
+
+public class DistributedTestRunResultBuilderTest extends TestCase {
+
+    public void testSimple() throws Exception {
+        DistributedTestRunResultBuilder builder = new DistributedTestRunResultBuilder(new DummyBrowserSource("mybrowser.exe", 0));
+        DistributedTestRunResult result = builder.build(XmlUtility.asXmlDocument(distributedTestRunResultString()));
+        assertEquals(2, result.getTestRunResults().size());
+    }
+
+    private String distributedTestRunResultString() {
+        return "<distributedTestRunResult>" +
+                testRunResultString() +
+                testRunResultString() +
+                "</distributedTestRunResult>";
+    }
+
+    private String testRunResultString() {
+        return
+                "<testRunResult>" +
+                        "<properties>" +
+                        "<property name=\"os\" value=\"my cool os\"></property>" +
+                        "<property name=\"ipAddress\" value=\"127.0.0.1\"></property>" +
+                        "<property name=\"hostname\" value=\"machine.example.com\"></property>" +
+                        "</properties>" +
+                        successResult().asXmlFragment() +
+                        errorResult().asXmlFragment() +
+                        "</testRunResult>";
+    }
+
+    private BrowserResult successResult() {
+        return new DummyBrowserResult(true, 0, 0);
+    }
+
+    private BrowserResult errorResult() {
+        return new DummyBrowserResult(false, 1, 2);
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/DummyBrowserSource.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/DummyBrowserSource.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/DummyBrowserSource.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,16 @@
+package net.jsunit.model;
+
+public class DummyBrowserSource implements BrowserSource {
+
+    private String fileName;
+    private int id;
+
+    public DummyBrowserSource(String fileName, int id) {
+        this.fileName = fileName;
+        this.id = id;
+    }
+
+    public Browser getBrowserById(int requestedId) {
+        return requestedId == id ? new Browser(fileName, id) : null;
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/ExternallyShutDownBrowserResultTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/ExternallyShutDownBrowserResultTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/ExternallyShutDownBrowserResultTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,52 @@
+package net.jsunit.model;
+
+import junit.framework.TestCase;
+
+public class ExternallyShutDownBrowserResultTest extends TestCase {
+
+    private String xml =
+            "<browserResult externallyShutDown=\"true\">" +
+                    "<properties>" +
+                    "<property name=\"browserFileName\" value=\"c:\\Program Files\\Internet Explorer\\iexplore.exe\" />" +
+                    "<property name=\"browserId\" value=\"17\" />" +
+                    "</properties>" +
+                    "</browserResult>";
+
+    private BrowserResult result;
+
+    public void setUp() throws Exception {
+        super.setUp();
+        result = new BrowserResult();
+        result.setExternallyShutDown();
+        result.setBrowser(new Browser("c:\\Program Files\\Internet Explorer\\iexplore.exe", 17));
+    }
+
+    public void testSimple() {
+        assertEquals("c:\\Program Files\\Internet Explorer\\iexplore.exe", result.getBrowser().getFileName());
+        assertEquals(0d, result.getTime());
+        assertEquals(ResultType.EXTERNALLY_SHUT_DOWN.getDisplayString(), result.getDisplayString());
+        assertEquals(0, result.getTestCount());
+        assertEquals(ResultType.EXTERNALLY_SHUT_DOWN, result.getResultType());
+        assertEquals(0, result.getTestPageResults().size());
+    }
+
+    public void testCompleted() {
+        assertFalse(result.completedTestRun());
+        assertFalse(result.timedOut());
+        assertFalse(result.failedToLaunch());
+        assertTrue(result.externallyShutDown());
+    }
+
+    public void testXml() {
+        assertEquals(xml, result.asXmlFragment());
+    }
+
+    public void testReconstituteFromXml() {
+        BrowserResultBuilder builder = new BrowserResultBuilder(new DummyBrowserSource("c:\\Program Files\\Internet Explorer\\iexplore.exe", 17));
+        BrowserResult reconstitutedResult = builder.build(xml);
+        assertEquals("c:\\Program Files\\Internet Explorer\\iexplore.exe", reconstitutedResult.getBrowser().getFileName());
+        assertTrue(reconstitutedResult.externallyShutDown());
+        assertEquals(ResultType.EXTERNALLY_SHUT_DOWN, reconstitutedResult.getResultType());
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/FailedToLaunchBrowserResultTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/FailedToLaunchBrowserResultTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/FailedToLaunchBrowserResultTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,63 @@
+package net.jsunit.model;
+
+import junit.framework.TestCase;
+import net.jsunit.utility.StringUtility;
+
+import java.io.FileNotFoundException;
+
+public class FailedToLaunchBrowserResultTest extends TestCase {
+
+    private Throwable exception = new FileNotFoundException();
+    private String xml =
+            "<browserResult failedToLaunch=\"true\">" +
+                    "<properties>" +
+                    "<property name=\"browserFileName\" value=\"c:\\Program Files\\Internet Explorer\\iexplore.exe\" />" +
+                    "<property name=\"browserId\" value=\"3\" />" +
+                    "<property name=\"serverSideExceptionStackTrace\"><![CDATA[" +
+                    StringUtility.stackTraceAsString(exception) +
+                    "]]></property>" +
+                    "</properties>" +
+                    "</browserResult>";
+
+    private BrowserResult result;
+
+    public void setUp() throws Exception {
+        super.setUp();
+        result = new BrowserResult();
+        result.setFailedToLaunch();
+        result.setBrowser(new Browser("c:\\Program Files\\Internet Explorer\\iexplore.exe", 3));
+        result.setServerSideException(exception);
+    }
+
+    public void testSimple() {
+        assertEquals("c:\\Program Files\\Internet Explorer\\iexplore.exe", result.getBrowser().getFileName());
+        assertEquals(0d, result.getTime());
+        assertEquals(ResultType.FAILED_TO_LAUNCH.getDisplayString(), result.getDisplayString());
+        assertEquals(0, result.getTestCount());
+        assertEquals(ResultType.FAILED_TO_LAUNCH, result.getResultType());
+        assertEquals(0, result.getTestPageResults().size());
+        assertEquals(StringUtility.stackTraceAsString(exception), result.getServerSideExceptionStackTrace());
+    }
+
+    public void testCompleted() {
+        assertFalse(result.completedTestRun());
+        assertFalse(result.timedOut());
+        assertFalse(result.externallyShutDown());
+        assertTrue(result.failedToLaunch());
+    }
+
+    public void testXml() {
+        assertEquals(xml, result.asXmlFragment());
+    }
+
+    public void testReconstituteFromXml() {
+        BrowserResultBuilder builder = new BrowserResultBuilder(new DummyBrowserSource("c:\\Program Files\\Internet Explorer\\iexplore.exe", 3));
+        BrowserResult reconstitutedResult = builder.build(xml);
+        assertEquals("c:\\Program Files\\Internet Explorer\\iexplore.exe", reconstitutedResult.getBrowser().getFileName());
+        assertTrue(reconstitutedResult.failedToLaunch());
+        assertEquals(ResultType.FAILED_TO_LAUNCH, reconstitutedResult.getResultType());
+        //TODO: somehow they're not quite equal
+        //assertEquals(Utility.stackTraceAsString(exception), reconstitutedResult.getServerSideExceptionStackTrace());
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/TestCaseResultTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/TestCaseResultTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/TestCaseResultTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,56 @@
+package net.jsunit.model;
+
+import junit.framework.TestCase;
+
+public class TestCaseResultTest extends TestCase {
+    public TestCaseResultTest(String name) {
+        super(name);
+    }
+
+    public void testBuildSuccessfulResultFromString() {
+        TestCaseResult result = TestCaseResult.fromString("file:///dummy%20path/dummyPage.html:testFoo|1.3|S||");
+        assertEquals("file:///dummy path/dummyPage.html", result.getTestPageName());
+        assertEquals("testFoo", result.getName());
+        assertEquals("file:///dummy path/dummyPage.html:testFoo", result.getFullyQualifiedName());
+        assertEquals(1.3d, result.getTime(), 0.1d);
+        assertFalse(result.hadError());
+        assertFalse(result.hadFailure());
+        assertTrue(result.wasSuccessful());
+        assertNull(result.getError());
+        assertNull(result.getFailure());
+        assertEquals(ResultType.SUCCESS, result.getResultType());
+        assertEquals("<testCase name=\"file:///dummy path/dummyPage.html:testFoo\" time=\"1.3\" />", result.getXmlFragment());
+    }
+
+    public void testProblemSummary() {
+        TestCaseResult result = TestCaseResult.fromString("file:///dummy/path/dummyPage.html:testFoo|1.3|E|Test Error Message|");
+        assertEquals("file:///dummy/path/dummyPage.html:testFoo had an error:\nTest Error Message", result.getProblemSummary());
+    }
+
+    public void testBuildErrorResultFromString() {
+        TestCaseResult result = TestCaseResult.fromString("file:///dummy/path/dummyPage.html:testFoo|1.3|E|Test Error Message|");
+        assertEquals("file:///dummy/path/dummyPage.html:testFoo", result.getFullyQualifiedName());
+        assertEquals(1.3d, result.getTime());
+        assertTrue(result.hadError());
+        assertFalse(result.hadFailure());
+        assertFalse(result.wasSuccessful());
+        assertEquals("Test Error Message", result.getError());
+        assertNull(result.getFailure());
+        assertEquals(ResultType.ERROR, result.getResultType());
+        assertEquals("<testCase name=\"file:///dummy/path/dummyPage.html:testFoo\" time=\"1.3\"><error>Test Error Message</error></testCase>", result.getXmlFragment());
+    }
+
+    public void testBuildFailureResultFromString() {
+        TestCaseResult result = TestCaseResult.fromString("file:///dummy/path/dummyPage.html:testFoo|1.3|F|Test Failure Message|");
+        assertEquals("file:///dummy/path/dummyPage.html:testFoo", result.getFullyQualifiedName());
+        assertEquals(1.3d, result.getTime());
+        assertFalse(result.hadError());
+        assertTrue(result.hadFailure());
+        assertFalse(result.wasSuccessful());
+        assertNull(result.getError());
+        assertEquals("Test Failure Message", result.getFailure());
+        assertEquals(ResultType.FAILURE, result.getResultType());
+        assertEquals("<testCase name=\"file:///dummy/path/dummyPage.html:testFoo\" time=\"1.3\"><failure>Test Failure Message</failure></testCase>", result.getXmlFragment());
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/TestPageResultTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/TestPageResultTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/TestPageResultTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,38 @@
+package net.jsunit.model;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestPageResultTest extends TestCase {
+
+    public void testSimple() {
+        TestPageResult result = new TestPageResult("mypage.html");
+        assertEquals("mypage.html", result.getTestPageName());
+        TestCaseResult testCase1 = new TestCaseResult();
+        TestCaseResult testCase2 = new TestCaseResult();
+        result.addTestCaseResult(testCase1);
+        result.addTestCaseResult(testCase2);
+        List<TestCaseResult> expected = new ArrayList<TestCaseResult>();
+        expected.add(testCase1);
+        expected.add(testCase2);
+        assertEquals(expected, result.getTestCaseResults());
+    }
+
+    public void testResultType() {
+        TestPageResult result = new TestPageResult("mypage.html");
+        TestCaseResult success = new TestCaseResult();
+        result.addTestCaseResult(success);
+        assertEquals(ResultType.SUCCESS, result.getResultType());
+        TestCaseResult failure = new TestCaseResult();
+        failure.setFailure("not right");
+        result.addTestCaseResult(failure);
+        assertEquals(ResultType.FAILURE, result.getResultType());
+        TestCaseResult error = new TestCaseResult();
+        error.setError("disaster");
+        result.addTestCaseResult(error);
+        assertEquals(ResultType.ERROR, result.getResultType());
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/TestRunResultBuilderTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/TestRunResultBuilderTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/TestRunResultBuilderTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,37 @@
+package net.jsunit.model;
+
+import junit.framework.TestCase;
+import net.jsunit.DummyBrowserResult;
+import net.jsunit.utility.XmlUtility;
+
+public class TestRunResultBuilderTest extends TestCase {
+
+    public void testSimple() throws Exception {
+        TestRunResultBuilder builder = new TestRunResultBuilder(new DummyBrowserSource("mybrowser.exe", 1));
+        TestRunResult result = builder.build(XmlUtility.asXmlDocument(fullValidResult()));
+        assertEquals(ResultType.SUCCESS, result.getResultType());
+        assertEquals(2, result.getChildren().size());
+        assertEquals("my cool os", result.getOsString());
+        assertEquals("127.0.0.1", result.getIpAddress());
+        assertEquals("machine.example.com", result.getHostname());
+    }
+
+    private String fullValidResult() {
+        return
+                "<testRunResult>" +
+                        "<properties>" +
+                        "<property name=\"os\" value=\"my cool os\"></property>" +
+                        "<property name=\"ipAddress\" value=\"127.0.0.1\"></property>" +
+                        "<property name=\"hostname\" value=\"machine.example.com\"></property>" +
+                        "</properties>" +
+                        successResult().asXmlFragment() +
+                        successResult().asXmlFragment() +
+                        "</testRunResult>";
+    }
+
+    private BrowserResult successResult() {
+        return new DummyBrowserResult(true, 0, 0);
+    }
+
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/TimedOutBrowerResultTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/TimedOutBrowerResultTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/model/TimedOutBrowerResultTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,49 @@
+package net.jsunit.model;
+
+import junit.framework.TestCase;
+
+public class TimedOutBrowerResultTest extends TestCase {
+
+    private String xml =
+            "<browserResult timedOut=\"true\">" +
+                    "<properties>" +
+                    "<property name=\"browserFileName\" value=\"c:\\Program Files\\Internet Explorer\\iexplore.exe\" />" +
+                    "<property name=\"browserId\" value=\"3\" />" +
+                    "</properties>" +
+                    "</browserResult>";
+
+    private BrowserResult browserResult;
+
+    public void setUp() throws Exception {
+        super.setUp();
+        browserResult = new BrowserResult();
+        browserResult.setTimedOut();
+        browserResult.setBrowser(new Browser("c:\\Program Files\\Internet Explorer\\iexplore.exe", 3));
+    }
+
+    public void testSimple() {
+        assertEquals("c:\\Program Files\\Internet Explorer\\iexplore.exe", browserResult.getBrowser().getFileName());
+        assertEquals(ResultType.TIMED_OUT, browserResult.getResultType());
+    }
+
+    public void testCompleted() {
+        assertFalse(browserResult.completedTestRun());
+        assertTrue(browserResult.timedOut());
+        assertFalse(browserResult.failedToLaunch());
+        assertFalse(browserResult.externallyShutDown());
+    }
+
+    public void testAsXml() {
+        assertEquals(xml, browserResult.asXmlFragment());
+    }
+
+    public void testReconstituteFromXml() {
+        BrowserResultBuilder builder = new BrowserResultBuilder(new DummyBrowserSource("c:\\Program Files\\Internet Explorer\\iexplore.exe", 3));
+        BrowserResult reconstitutedResult = builder.build(xml);
+        assertEquals("c:\\Program Files\\Internet Explorer\\iexplore.exe", reconstitutedResult.getBrowser().getFileName());
+        assertTrue(reconstitutedResult.timedOut());
+        assertEquals(ResultType.TIMED_OUT, reconstitutedResult.getResultType());
+
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/version/BlowingUpVersionGrabber.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/version/BlowingUpVersionGrabber.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/version/BlowingUpVersionGrabber.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,7 @@
+package net.jsunit.version;
+
+public class BlowingUpVersionGrabber implements VersionGrabber {
+    public double grabVersion() throws Exception {
+        throw new Exception();
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/version/MockVersionGrabber.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/version/MockVersionGrabber.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/version/MockVersionGrabber.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,14 @@
+package net.jsunit.version;
+
+public class MockVersionGrabber implements VersionGrabber {
+
+    public double version;
+
+    public MockVersionGrabber(double version) {
+        this.version = version;
+    }
+
+    public double grabVersion() {
+        return version;
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/version/VersionCheckerTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/version/VersionCheckerTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_core/net/jsunit/version/VersionCheckerTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,22 @@
+package net.jsunit.version;
+
+import junit.framework.TestCase;
+
+public class VersionCheckerTest extends TestCase {
+
+    public void testOutOfDate() throws Exception {
+        VersionChecker checker = new VersionChecker(1.1, new MockVersionGrabber(1.2));
+        assertFalse(checker.isUpToDate());
+    }
+
+    public void testUpToDate() throws Exception {
+        VersionChecker checker = new VersionChecker(1.1, new MockVersionGrabber(1.1));
+        assertTrue(checker.isUpToDate());
+    }
+
+    public void testBlowsUp() throws Exception {
+        VersionChecker checker = new VersionChecker(1.1, new BlowingUpVersionGrabber());
+        assertTrue(checker.isUpToDate());
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/AcceptorFunctionalTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/AcceptorFunctionalTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/AcceptorFunctionalTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,45 @@
+package net.jsunit;
+
+import net.jsunit.model.Browser;
+import net.jsunit.model.BrowserResult;
+import net.jsunit.model.BrowserResultWriter;
+import net.jsunit.utility.XmlUtility;
+import org.jdom.Document;
+
+public class AcceptorFunctionalTest extends FunctionalTestCase {
+
+    public void testSubmission() throws Exception {
+        server.launchBrowserTestRun(new BrowserLaunchSpecification(new Browser(Browser.DEFAULT_SYSTEM_BROWSER, 0)));
+
+        StringBuffer buffer = new StringBuffer();
+        addParameter(buffer, BrowserResultWriter.ID, "ID_foo", true);
+        addParameter(buffer, BrowserResultWriter.USER_AGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)", false);
+        addParameter(buffer, BrowserResultWriter.TIME, "4.3", false);
+        addParameter(buffer, BrowserResultWriter.JSUNIT_VERSION, "12.5", false);
+        addParameter(buffer, BrowserResultWriter.TEST_CASES, "/dummy/path/dummyPage.html:testFoo|1.3|S||", false);
+
+        webTester.beginAt("acceptor" + buffer.toString());
+
+        BrowserResult result = new BrowserResult();
+        result.setId("ID_foo");
+        result.setBrowser(new Browser(Browser.DEFAULT_SYSTEM_BROWSER, 0));
+        result.setUserAgent("Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
+        result.setTime(4.3);
+        result.setJsUnitVersion("12.5");
+        result.setTestCaseStrings(new String[]{"/dummy/path/dummyPage.html:testFoo|1.3|S||"});
+        result.setRemoteAddress("127.0.0.1");
+
+        assertEquals(XmlUtility.asString(new Document(result.asXml())), webTester.getDialog().getResponseText());
+    }
+
+    private void addParameter(StringBuffer buffer, String key, String value, boolean isFirst) {
+        if (isFirst)
+            buffer.append("?");
+        else
+            buffer.append("&");
+        buffer.append(key);
+        buffer.append("=");
+        buffer.append(value);
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/BlowingUpRemoteServerHitter.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/BlowingUpRemoteServerHitter.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/BlowingUpRemoteServerHitter.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,16 @@
+/**
+ * 
+ */
+package net.jsunit;
+
+import org.jdom.Document;
+
+import java.io.IOException;
+import java.net.URL;
+
+public class BlowingUpRemoteServerHitter implements RemoteServerHitter {
+
+    public Document hitURL(URL url) throws IOException {
+        throw new IOException();
+    }
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/BrowserResultLogWriterTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/BrowserResultLogWriterTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/BrowserResultLogWriterTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,12 @@
+package net.jsunit;
+
+import junit.framework.TestCase;
+import net.jsunit.logging.StubBrowserResultRepository;
+
+public class BrowserResultLogWriterTest extends TestCase {
+
+    public void testSimple() {
+        assertTrue(new BrowserResultLogWriter(new StubBrowserResultRepository()).isReady());
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/ConfigurationFunctionalTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/ConfigurationFunctionalTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/ConfigurationFunctionalTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,10 @@
+package net.jsunit;
+
+public class ConfigurationFunctionalTest extends FunctionalTestCase {
+
+    public void testSimple() throws Exception {
+        webTester.beginAt("config");
+        assertConfigXml();
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/DisplayerFunctionalTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/DisplayerFunctionalTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/DisplayerFunctionalTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,47 @@
+package net.jsunit;
+
+import net.jsunit.model.Browser;
+import net.jsunit.model.BrowserResult;
+import net.jsunit.utility.XmlUtility;
+import org.jdom.Document;
+import org.jdom.Element;
+
+public class DisplayerFunctionalTest extends FunctionalTestCase {
+
+    public void testNoId() throws Exception {
+        webTester.beginAt("displayer");
+        Document responseDocument = responseXmlDocument();
+
+        Element rootElement = responseDocument.getRootElement();
+        assertErrorResponse(rootElement, "A Test Result ID and a browser ID must both be given");
+    }
+
+    public void testInvalidId() throws Exception {
+        String id = String.valueOf(System.currentTimeMillis());
+        webTester.beginAt("displayer?id=" + id + "&browserId=0");
+        Document responseDocument = responseXmlDocument();
+
+        Element rootElement = responseDocument.getRootElement();
+        assertErrorResponse(rootElement, "No Test Result has been submitted with ID '" + id + "' for browser ID '0'");
+    }
+
+    public void testInvalidBrowserId() throws Exception {
+        String id = String.valueOf(System.currentTimeMillis());
+        webTester.beginAt("displayer?id=" + id + "&browserId=1000");
+        Document responseDocument = responseXmlDocument();
+
+        Element rootElement = responseDocument.getRootElement();
+        assertErrorResponse(rootElement, "Invalid Browser ID '1000'");
+    }
+
+    public void testValid() throws Exception {
+        server.launchBrowserTestRun(new BrowserLaunchSpecification(new Browser(Browser.DEFAULT_SYSTEM_BROWSER, 0)));
+        BrowserResult browserResult = new BrowserResult();
+        String id = String.valueOf(System.currentTimeMillis());
+        browserResult.setId(id);
+        server.accept(browserResult);
+        webTester.beginAt("displayer?id=" + id + "&browserId=0");
+        assertEquals(XmlUtility.asString(new Document(browserResult.asXml())), webTester.getDialog().getResponseText());
+    }
+
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/DistributedTestRunManagerTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/DistributedTestRunManagerTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/DistributedTestRunManagerTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,175 @@
+package net.jsunit;
+
+import junit.framework.TestCase;
+import net.jsunit.configuration.Configuration;
+import net.jsunit.model.*;
+import net.jsunit.utility.XmlUtility;
+import org.jdom.Document;
+
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.util.List;
+
+public class DistributedTestRunManagerTest extends TestCase {
+
+    private Configuration configuration;
+
+    public void setUp() throws Exception {
+        super.setUp();
+        configuration = new Configuration(new DummyConfigurationSource());
+    }
+
+    public void testSimple() throws MalformedURLException, UnsupportedEncodingException {
+        String encodedURL = URLEncoder.encode(DummyConfigurationSource.DUMMY_URL, "UTF-8");
+        String url1 = DummyConfigurationSource.REMOTE_URL_1 + "/runner?url=" + encodedURL;
+        String url2 = DummyConfigurationSource.REMOTE_URL_2 + "/runner?url=" + encodedURL;
+        MockRemoteServerHitter hitter = createMockHitter(url1, url2);
+        DistributedTestRunManager manager = new DistributedTestRunManager(hitter, configuration, null);
+        manager.runTests();
+        assertEquals(2, hitter.urlsPassed.size());
+        assertTrue(hitter.urlsPassed.contains(url1));
+        assertTrue(hitter.urlsPassed.contains(url2));
+        DistributedTestRunResult result = manager.getDistributedTestRunResult();
+
+        DistributedTestRunResult expectedResult = new DistributedTestRunResult();
+        expectedResult.addTestRunResult(createResult1());
+        expectedResult.addTestRunResult(createResult2());
+
+        assertEquals(XmlUtility.asString(expectedResult.asXml()), XmlUtility.asString(result.asXml()));
+    }
+
+    public void testRemoteURLBlowsUp() {
+        DistributedTestRunManager manager = new DistributedTestRunManager(new BlowingUpRemoteServerHitter(), configuration, null);
+        assertFalse(configuration.shouldIgnoreUnresponsiveRemoteMachines());
+        manager.runTests();
+        DistributedTestRunResult result = manager.getDistributedTestRunResult();
+        assertFalse(result.wasSuccessful());
+        List<TestRunResult> testRunResults = result.getTestRunResults();
+        assertEquals(2, testRunResults.size());
+        assertEquals(ResultType.UNRESPONSIVE, testRunResults.get(0).getResultType());
+        assertEquals(DummyConfigurationSource.REMOTE_URL_1, testRunResults.get(0).getUrl().toString());
+        assertEquals(DummyConfigurationSource.REMOTE_URL_2, testRunResults.get(1).getUrl().toString());
+        assertEquals(ResultType.UNRESPONSIVE, testRunResults.get(1).getResultType());
+    }
+
+    public void testRemoteURLBlowsUpButIgnored() {
+        configuration = new Configuration(new DummyConfigurationSource() {
+            public String ignoreUnresponsiveRemoteMachines() {
+                return "true";
+            }
+        });
+        assertTrue(configuration.shouldIgnoreUnresponsiveRemoteMachines());
+        DistributedTestRunManager manager = new DistributedTestRunManager(new BlowingUpRemoteServerHitter(), configuration, null);
+        manager.runTests();
+        DistributedTestRunResult result = manager.getDistributedTestRunResult();
+        assertTrue(result.wasSuccessful());
+        assertEquals(0, result.getTestRunResults().size());
+    }
+
+    public void testOverrideURL() throws Exception {
+        String overrideURL = "http://my.override.com:1234?foo=bar&bar=foo";
+        String encodedOverrideURL = URLEncoder.encode(overrideURL, "UTF-8");
+        String url1 = DummyConfigurationSource.REMOTE_URL_1 + "/runner?url=" + encodedOverrideURL;
+        String url2 = DummyConfigurationSource.REMOTE_URL_2 + "/runner?url=" + encodedOverrideURL;
+        MockRemoteServerHitter hitter = createMockHitter(url1, url2);
+        DistributedTestRunManager manager = new DistributedTestRunManager(hitter, configuration, overrideURL);
+        manager.runTests();
+        assertEquals(2, hitter.urlsPassed.size());
+        assertTrue(hitter.urlsPassed.contains(url1));
+        assertTrue(hitter.urlsPassed.contains(url2));
+    }
+
+    public void testNoURL() throws Exception {
+        configuration = new Configuration(new DummyConfigurationSource() {
+            public String url() {
+                return null;
+            }
+        });
+        String url1 = DummyConfigurationSource.REMOTE_URL_1 + "/runner";
+        String url2 = DummyConfigurationSource.REMOTE_URL_2 + "/runner";
+        MockRemoteServerHitter hitter = createMockHitter(url1, url2);
+
+        DistributedTestRunManager manager = new DistributedTestRunManager(hitter, configuration, null);
+        manager.runTests();
+        assertEquals(2, hitter.urlsPassed.size());
+        assertTrue(hitter.urlsPassed.contains(url1));
+        assertTrue(hitter.urlsPassed.contains(url2));
+        DistributedTestRunResult result = manager.getDistributedTestRunResult();
+
+        DistributedTestRunResult expectedResult = new DistributedTestRunResult();
+        expectedResult.addTestRunResult(createResult1());
+        expectedResult.addTestRunResult(createResult2());
+
+        assertEquals(XmlUtility.asString(expectedResult.asXml()), XmlUtility.asString(result.asXml()));
+    }
+
+    public void testDistributedResultReturned() throws Exception {
+        String encodedURL = URLEncoder.encode(DummyConfigurationSource.DUMMY_URL, "UTF-8");
+        String url1 = DummyConfigurationSource.REMOTE_URL_1 + "/runner?url=" + encodedURL;
+        String url2 = DummyConfigurationSource.REMOTE_URL_2 + "/runner?url=" + encodedURL;
+        MockRemoteServerHitter hitter = createMockHitterWithDistributedResults(url1, url2);
+        DistributedTestRunManager manager = new DistributedTestRunManager(hitter, configuration, null);
+        manager.runTests();
+        DistributedTestRunResult result = manager.getDistributedTestRunResult();
+        assertEquals(4, result.getTestRunResults().size());
+    }
+
+    private MockRemoteServerHitter createMockHitter(String url1, String url2) throws MalformedURLException {
+        MockRemoteServerHitter hitter = new MockRemoteServerHitter();
+        hitter.urlToDocument.put(url1, new Document(createResult1().asXml()));
+        hitter.urlToDocument.put(url2, new Document(createResult2().asXml()));
+        return hitter;
+    }
+
+    private MockRemoteServerHitter createMockHitterWithDistributedResults(String url1, String url2) throws MalformedURLException {
+        MockRemoteServerHitter hitter = new MockRemoteServerHitter();
+        DistributedTestRunResult distributedResult = new DistributedTestRunResult();
+        distributedResult.addTestRunResult(createResult1());
+        distributedResult.addTestRunResult(createResult2());
+        hitter.urlToDocument.put(url1, new Document(distributedResult.asXml()));
+        hitter.urlToDocument.put(url2, new Document(distributedResult.asXml()));
+        return hitter;
+    }
+
+    private TestRunResult createResult1() throws MalformedURLException {
+        TestRunResult result = new TestRunResult(new URL(DummyConfigurationSource.REMOTE_URL_1));
+        result.setOsString("my os");
+        BrowserResult browserResult1 = new BrowserResult();
+        browserResult1.setId("1");
+        browserResult1.setBrowser(new Browser("mybrowser.exe", 0));
+        browserResult1.setTime(123.45);
+        result.addBrowserResult(browserResult1);
+
+        BrowserResult browserResult2 = new BrowserResult();
+        browserResult2.setId("2");
+        browserResult2.setBrowser(new Browser("mybrowser.exe", 0));
+        browserResult2.setFailedToLaunch();
+        result.addBrowserResult(browserResult2);
+
+        return result;
+    }
+
+    private TestRunResult createResult2() throws MalformedURLException {
+        TestRunResult result = new TestRunResult(new URL(DummyConfigurationSource.REMOTE_URL_2));
+        result.setOsString("my other os");
+        BrowserResult browserResult1 = new BrowserResult();
+        browserResult1.setBrowser(new Browser("mybrowser.exe", 0));
+        browserResult1.setId("a");
+        browserResult1.setTime(123.45);
+        browserResult1.setBaseURL("http://www.example.com");
+        browserResult1.setId("12345");
+        browserResult1.setUserAgent("foo bar");
+        result.addBrowserResult(browserResult1);
+
+        BrowserResult browserResult2 = new BrowserResult();
+        browserResult1.setId("b");
+        browserResult2.setBrowser(new Browser("mybrowser.exe", 0));
+        browserResult2.setTimedOut();
+        result.addBrowserResult(browserResult2);
+
+        return result;
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/DistributedTestSuiteBuilderTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/DistributedTestSuiteBuilderTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/DistributedTestSuiteBuilderTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,61 @@
+package net.jsunit;
+
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import net.jsunit.configuration.Configuration;
+import net.jsunit.configuration.ServerType;
+import org.jdom.Document;
+
+public class DistributedTestSuiteBuilderTest extends TestCase {
+    private DummyConfigurationSource originalSource;
+    private MockRemoteServerHitter mockHitter;
+    private DistributedTestSuiteBuilder builder;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        originalSource = new DummyConfigurationSource();
+        mockHitter = new MockRemoteServerHitter();
+        originalSource.setNeeds3rdRemoteMachineURL();
+        mockHitter.urlToDocument.put(DummyConfigurationSource.REMOTE_URL_1 + "/config", remoteConfiguration1XmlDocument());
+        mockHitter.urlToDocument.put(DummyConfigurationSource.REMOTE_URL_2 + "/config", remoteConfiguration2XmlDocument());
+        mockHitter.urlToDocument.put(DummyConfigurationSource.REMOTE_URL_3 + "/config", remoteConfiguration3XmlDocument());
+        builder = new DistributedTestSuiteBuilder(originalSource, mockHitter);
+    }
+
+    public void testSimple() throws Exception {
+        TestSuite aSuite = new TestSuite();
+        builder.addTestsTo(aSuite);
+
+        assertEquals(3, builder.getRemoteMachineURLCount());
+        assertEquals(5, builder.getBrowserCount());
+        assertEquals("JsUnit Tests (3 machines, 5 direct browsers)", aSuite.getName());
+    }
+
+    private Document remoteConfiguration1XmlDocument() {
+        Configuration configuration = new Configuration(new StubConfigurationSource() {
+            public String browserFileNames() {
+                return "browser1.exe,browser2.exe";
+            }
+        });
+        return new Document(configuration.asXml(ServerType.STANDARD));
+    }
+
+    private Document remoteConfiguration2XmlDocument() {
+        Configuration configuration = new Configuration(new StubConfigurationSource() {
+            public String browserFileNames() {
+                return "browser3.exe,browser4.exe,browser5";
+            }
+        });
+        return new Document(configuration.asXml(ServerType.STANDARD));
+    }
+
+    private Document remoteConfiguration3XmlDocument() {
+        Configuration configuration = new Configuration(new StubConfigurationSource() {
+            public String remoteMachineURLs() {
+                return "http://machine4:6060/jsunit";
+            }
+        });
+        return new Document(configuration.asXml(ServerType.FARM));
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/DummyConfigurationSource.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/DummyConfigurationSource.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/DummyConfigurationSource.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,65 @@
+package net.jsunit;
+
+import net.jsunit.configuration.ConfigurationSource;
+
+public class DummyConfigurationSource implements ConfigurationSource {
+
+    public static final String DUMMY_URL = "http://www.example.com:1234/jsunit/runner?autoRun=true&submitResults=true";
+    public static final String REMOTE_URL_1 = "http://my.machine.com:8080/jsunit";
+    public static final String REMOTE_URL_2 = "http://your.machine.com:9090/jsunit";
+    public static final String REMOTE_URL_3 = "http://his.machine.com:7070/jsunit";
+    public static final String BROWSER_FILE_NAME = "mybrowser.exe";
+    private boolean needs3rdRemoteMachineURL;
+
+    public String resourceBase() {
+        return ".";
+    }
+
+    public String port() {
+        return "1234";
+    }
+
+    public String logsDirectory() {
+        return "";
+    }
+
+    public String browserFileNames() {
+        return BROWSER_FILE_NAME;
+    }
+
+    public String url() {
+        return DUMMY_URL;
+    }
+
+    public String ignoreUnresponsiveRemoteMachines() {
+        return "";
+    }
+
+    public String closeBrowsersAfterTestRuns() {
+        return "true";
+    }
+
+    public String description() {
+        return "This is my server!";
+    }
+
+    public String logStatus() {
+        return "false";
+    }
+
+    public String timeoutSeconds() {
+        return "60";
+    }
+
+    public String remoteMachineURLs() {
+        String result = REMOTE_URL_1 + "," + REMOTE_URL_2;
+        if (needs3rdRemoteMachineURL)
+            result += ("," + REMOTE_URL_3);
+        return result;
+    }
+
+    public void setNeeds3rdRemoteMachineURL() {
+        this.needs3rdRemoteMachineURL = true;
+    }
+
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/DummyFarmConfigurationSource.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/DummyFarmConfigurationSource.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/DummyFarmConfigurationSource.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,51 @@
+package net.jsunit;
+
+import net.jsunit.configuration.ConfigurationSource;
+
+public class DummyFarmConfigurationSource implements ConfigurationSource {
+
+    public String resourceBase() {
+        return ".";
+    }
+
+    public String port() {
+        return "1234";
+    }
+
+    public String logsDirectory() {
+        return "c:\\logs";
+    }
+
+    public String browserFileNames() {
+        return null;
+    }
+
+    public String url() {
+        return null;
+    }
+
+    public String ignoreUnresponsiveRemoteMachines() {
+        return null;
+    }
+
+    public String closeBrowsersAfterTestRuns() {
+        return null;
+    }
+
+    public String description() {
+        return "This is a cool server";
+    }
+
+    public String logStatus() {
+        return "true";
+    }
+
+    public String timeoutSeconds() {
+        return "25";
+    }
+
+    public String remoteMachineURLs() {
+        return "http://www.example.com:8081,http://www.example.com:8082";
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/DummyHttpRequest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/DummyHttpRequest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/DummyHttpRequest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,251 @@
+package net.jsunit;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.Principal;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Map;
+
+public class DummyHttpRequest implements HttpServletRequest {
+    protected Map parametersToValues;
+    private String ipAddress;
+    private String host;
+
+    public DummyHttpRequest(Map parametersToValues) {
+        this.parametersToValues = parametersToValues;
+    }
+
+    public String getAuthType() {
+        return null;
+    }
+
+    public Cookie[] getCookies() {
+        return null;
+    }
+
+    public long getDateHeader(String name) {
+        return 0;
+    }
+
+    public String getHeader(String name) {
+        return null;
+    }
+
+    public Enumeration getHeaders(String name) {
+        return null;
+    }
+
+    public Enumeration getHeaderNames() {
+        return null;
+    }
+
+    public int getIntHeader(String name) {
+        return 0;
+    }
+
+    public String getMethod() {
+        return null;
+    }
+
+    public String getPathInfo() {
+        return null;
+    }
+
+    public String getPathTranslated() {
+        return null;
+    }
+
+    public String getContextPath() {
+        return null;
+    }
+
+    public String getQueryString() {
+        return null;
+    }
+
+    public String getRemoteUser() {
+        return null;
+    }
+
+    public boolean isUserInRole(String role) {
+        return false;
+    }
+
+    public Principal getUserPrincipal() {
+        return null;
+    }
+
+    public String getRequestedSessionId() {
+        return null;
+    }
+
+    public String getRequestURI() {
+        return null;
+    }
+
+    public StringBuffer getRequestURL() {
+        return null;
+    }
+
+    public String getServletPath() {
+        return null;
+    }
+
+    public HttpSession getSession(boolean create) {
+        return null;
+    }
+
+    public HttpSession getSession() {
+        return null;
+    }
+
+    public boolean isRequestedSessionIdValid() {
+        return false;
+    }
+
+    public boolean isRequestedSessionIdFromCookie() {
+        return false;
+    }
+
+    public boolean isRequestedSessionIdFromURL() {
+        return false;
+    }
+
+    public Object getAttribute(String name) {
+        return null;
+    }
+
+    public Enumeration getAttributeNames() {
+        return null;
+    }
+
+    public String getCharacterEncoding() {
+        return null;
+    }
+
+    public void setCharacterEncoding(String env) throws UnsupportedEncodingException {
+    }
+
+    public int getContentLength() {
+        return 0;
+    }
+
+    public String getContentType() {
+        return null;
+    }
+
+    public ServletInputStream getInputStream() throws IOException {
+        return null;
+    }
+
+    public String getParameter(String name) {
+        Object object = parametersToValues.get(name);
+        if (object instanceof String) return (String) object;
+        if (object instanceof String[]) return ((String[]) object)[0];
+        return null;
+    }
+
+    public Enumeration getParameterNames() {
+        return null;
+    }
+
+    public String[] getParameterValues(String name) {
+        Object object = parametersToValues.get(name);
+        if (object instanceof String) return new String[]{(String) object};
+        if (object instanceof String[]) return (String[]) object;
+        return null;
+    }
+
+    public Map getParameterMap() {
+        return null;
+    }
+
+    public String getProtocol() {
+        return null;
+    }
+
+    public String getScheme() {
+        return null;
+    }
+
+    public String getServerName() {
+        return null;
+    }
+
+    public int getServerPort() {
+        return 0;
+    }
+
+    public BufferedReader getReader() throws IOException {
+        return null;
+    }
+
+    public String getRemoteAddr() {
+        return ipAddress;
+    }
+
+    public String getRemoteHost() {
+        return host;
+    }
+
+    public void setAttribute(String name, Object o) {
+    }
+
+    public void removeAttribute(String name) {
+    }
+
+    public Locale getLocale() {
+        return null;
+    }
+
+    public Enumeration getLocales() {
+        return null;
+    }
+
+    public boolean isSecure() {
+        return false;
+    }
+
+    public RequestDispatcher getRequestDispatcher(String path) {
+        return null;
+    }
+
+    public String getRealPath(String path) {
+        return null;
+    }
+
+    public boolean isRequestedSessionIdFromUrl() {
+        return false;
+    }
+
+    public int getRemotePort() {
+        return 0;
+    }
+
+    public String getLocalName() {
+        return null;
+    }
+
+    public String getLocalAddr() {
+        return null;
+    }
+
+    public int getLocalPort() {
+        return 0;
+    }
+
+    public void setIpAddress(String ipAddress) {
+        this.ipAddress = ipAddress;
+    }
+
+    public void setHost(String host) {
+        this.host = host;
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/EndToEndTestCase.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/EndToEndTestCase.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/EndToEndTestCase.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,14 @@
+package net.jsunit;
+
+import junit.framework.TestCase;
+
+public abstract class EndToEndTestCase extends TestCase {
+
+	protected int port;
+
+	public void setUp() throws Exception {
+		super.setUp();
+		port = new TestPortManager().newPort();
+	}
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/ExternallyShutDownStandaloneTestTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/ExternallyShutDownStandaloneTestTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/ExternallyShutDownStandaloneTestTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,58 @@
+package net.jsunit;
+
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+import net.jsunit.configuration.ConfigurationSource;
+import net.jsunit.model.Browser;
+import net.jsunit.model.ResultType;
+
+public class ExternallyShutDownStandaloneTestTest extends TestCase {
+
+    public ExternallyShutDownStandaloneTestTest(String name) {
+        super(name);
+    }
+
+    protected ConfigurationSource configurationSource() {
+        return new StubConfigurationSource() {
+            public String browserFileNames() {
+                return Browser.DEFAULT_SYSTEM_BROWSER;
+            }
+
+            public String url() {
+                return "http://localhost:8080/jsunit/testRunner.html?" +
+                        "testPage=http://localhost:8080/jsunit/tests/jsUnitTestSuite.html" +
+                        "&autoRun=true&submitresults=true&resultId=foobar";
+            }
+        };
+    }
+
+    public void testBrowsersExternallyShutDown() throws Exception {
+        final StandaloneTest test = new StandaloneTest(configurationSource());
+        new Thread() {
+            public void run() {
+                try {
+                    while (test.getServer() == null)
+                        Thread.sleep(100);
+                    while (test.getServer().getBrowserProcess() == null)
+                        Thread.sleep(100);
+                } catch (InterruptedException e) {
+                    fail();
+                }
+                Process process = test.getServer().getBrowserProcess();
+                process.destroy();
+                try {
+                    process.waitFor();
+                } catch (InterruptedException e) {
+                    fail();
+                }
+            }
+        }.start();
+
+        TestResult result = test.run();
+        assertFalse(result.wasSuccessful());
+        assertEquals(
+                ResultType.EXTERNALLY_SHUT_DOWN,
+                test.getServer().lastResult().getResultType());
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FailedToLaunchBrowserStandaloneTestTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FailedToLaunchBrowserStandaloneTestTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FailedToLaunchBrowserStandaloneTestTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,34 @@
+package net.jsunit;
+
+import junit.framework.TestResult;
+import net.jsunit.configuration.ConfigurationSource;
+import net.jsunit.model.ResultType;
+
+public class FailedToLaunchBrowserStandaloneTestTest extends EndToEndTestCase {
+
+    protected ConfigurationSource configurationSource() {
+        return new StubConfigurationSource() {
+            public String browserFileNames() {
+                return "no_such_browser.exe";
+            }
+
+            public String url() {
+                return "http://localhost:"+port+"/jsunit/testRunner.html?" +
+                        "testPage=http://localhost:"+port+"/jsunit/tests/jsUnitUtilityTests.html" +
+                        "&autoRun=true&submitresults=true&resultId=foobar";
+            }
+            
+            public String port() {
+            	return String.valueOf(port);
+            }
+        };
+    }
+
+    public void testFailToLaunchBrowsers() throws Exception {
+        StandaloneTest test = new StandaloneTest(configurationSource());
+        TestResult result = test.run();
+        assertFalse(result.wasSuccessful());
+        assertEquals(ResultType.FAILED_TO_LAUNCH, test.getServer().lastResult().getResultType());
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FarmServerFunctionalTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FarmServerFunctionalTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FarmServerFunctionalTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,38 @@
+package net.jsunit;
+
+import net.jsunit.configuration.Configuration;
+import net.jsunit.model.ResultType;
+import org.jdom.Document;
+
+import java.net.URLEncoder;
+
+public class FarmServerFunctionalTest extends FunctionalTestCase {
+
+    private JsUnitFarmServer farmServer;
+    private int otherPort;
+
+    public void setUp() throws Exception {
+        super.setUp();
+        otherPort = new TestPortManager().newPort();
+        farmServer = new JsUnitFarmServer(new Configuration(new FunctionalTestFarmConfigurationSource(otherPort, port)));
+        farmServer.start();
+    }
+
+    protected int webTesterPort() {
+        return otherPort;
+    }
+
+    public void testHitFarmRunner() throws Exception {
+        String url =
+                "/runner?url=" + URLEncoder.encode("http://localhost:" + port + "/jsunit/tests/jsUnitUtilityTests.html", "UTF-8");
+        webTester.beginAt(url);
+        Document document = responseXmlDocument();
+        assertEquals(ResultType.SUCCESS.name(), document.getRootElement().getAttribute("type").getValue());
+    }
+
+    public void tearDown() throws Exception {
+        farmServer.dispose();
+        super.tearDown();
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FarmServerFunctionalTestSuite.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FarmServerFunctionalTestSuite.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FarmServerFunctionalTestSuite.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,14 @@
+package net.jsunit;
+
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+public class FarmServerFunctionalTestSuite extends TestCase {
+    public static TestSuite suite() {
+        TestSuite result = new TestSuite();
+//        result.addTestSuite(FarmServerFunctionalTest.class);
+        result.addTestSuite(FarmServerLandingPageFunctionalTest.class);
+
+        return result;
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FarmServerLandingPageFunctionalTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FarmServerLandingPageFunctionalTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FarmServerLandingPageFunctionalTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,45 @@
+package net.jsunit;
+
+import com.meterware.httpunit.HttpUnitOptions;
+import junit.framework.TestCase;
+import net.jsunit.configuration.Configuration;
+import net.sourceforge.jwebunit.WebTester;
+
+public class FarmServerLandingPageFunctionalTest extends TestCase {
+
+    static {
+        HttpUnitOptions.setScriptingEnabled(false);
+    }
+
+    private WebTester webTester;
+    private JsUnitFarmServer server;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        int port = new TestPortManager().newPort();
+        Configuration configuration = new Configuration(new FunctionalTestConfigurationSource(port));
+        server = new JsUnitFarmServer(configuration);
+        server.start();
+        webTester = new WebTester();
+        webTester.getTestContext().setBaseUrl("http://localhost:" + port + "/jsunit");
+    }
+
+    protected void tearDown() throws Exception {
+        server.dispose();
+        super.tearDown();
+    }
+
+    public void testSimple() throws Exception {
+        webTester.beginAt("/");
+        assertOnLandingPage();
+        webTester.assertLinkPresentWithText("runner");
+        webTester.assertLinkNotPresentWithText("displayer");
+        webTester.assertLinkPresentWithText("testRunner.html");
+        webTester.assertLinkPresentWithText("config");
+    }
+
+    private void assertOnLandingPage() {
+        webTester.assertTitleEquals("JsUnit  Farm Server");
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FunctionalTestCase.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FunctionalTestCase.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FunctionalTestCase.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,93 @@
+package net.jsunit;
+
+import com.meterware.httpunit.HttpUnitOptions;
+import junit.framework.TestCase;
+import net.jsunit.configuration.Configuration;
+import net.jsunit.model.BrowserResultWriter;
+import net.jsunit.model.ResultType;
+import net.sourceforge.jwebunit.WebTester;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.jdom.input.SAXBuilder;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.List;
+
+public abstract class FunctionalTestCase extends TestCase {
+
+    static {
+        HttpUnitOptions.setScriptingEnabled(false);
+    }
+
+    protected WebTester webTester;
+    protected JsUnitStandardServer server;
+    protected int port;
+    protected Configuration configuration;
+
+    public void setUp() throws Exception {
+        super.setUp();
+        port = new TestPortManager().newPort();
+        configuration = new Configuration(new FunctionalTestConfigurationSource(port));
+        server = new JsUnitStandardServer(configuration, new MockBrowserResultRepository(), true);
+        if (shouldMockOutProcessStarter())
+            server.setProcessStarter(new MockProcessStarter());
+        server.start();
+        webTester = new WebTester();
+        webTester.getTestContext().setBaseUrl("http://localhost:" + webTesterPort() + "/jsunit");
+    }
+
+    protected boolean shouldMockOutProcessStarter() {
+        return true;
+    }
+
+    protected int webTesterPort() {
+        return port;
+    }
+
+    public void tearDown() throws Exception {
+        if (server != null)
+            server.dispose();
+        super.tearDown();
+    }
+
+    protected Document responseXmlDocument() throws JDOMException, IOException {
+        String responseXml = webTester.getDialog().getResponseText();
+        SAXBuilder saxBuilder = new SAXBuilder("org.apache.xerces.parsers.SAXParser");
+        Reader stringReader = new StringReader(responseXml);
+        return saxBuilder.build(stringReader);
+    }
+
+    protected void assertConfigXml() throws JDOMException, IOException {
+        System.out.println(webTester.getDialog().getResponseText());
+        Document result = responseXmlDocument();
+        Element root = result.getRootElement();
+        assertEquals("configuration", root.getName());
+    }
+
+    protected void assertErrorResponse(Element rootElement, String message) {
+        assertEquals("error", rootElement.getName());
+        assertEquals(message, rootElement.getText());
+    }
+
+    protected void assertSuccessfulRunResult(Document result, ResultType expectedResultType, String expectedUrl, int expectedBrowserResultCount) {
+        Element root = result.getRootElement();
+        assertEquals("testRunResult", root.getName());
+        assertEquals(expectedBrowserResultCount, root.getChildren("browserResult").size());
+        assertEquals(expectedResultType.name(), root.getAttribute("type").getValue());
+        Element urlProperty = urlPropertyElement(root);
+        assertEquals(expectedUrl, urlProperty.getAttribute(BrowserResultWriter.PROPERTY_VALUE).getValue());
+    }
+
+    @SuppressWarnings("unchecked")
+    private Element urlPropertyElement(Element root) {
+        List<Element> children = root.getChild("browserResult").getChild(BrowserResultWriter.PROPERTIES).getChildren(BrowserResultWriter.PROPERTY);
+        for (Element child : children) {
+            if (child.getAttribute(BrowserResultWriter.PROPERTY_KEY).getValue().equals(BrowserResultWriter.URL))
+                return child;
+        }
+        return null;
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FunctionalTestConfigurationSource.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FunctionalTestConfigurationSource.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FunctionalTestConfigurationSource.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,61 @@
+/**
+ * 
+ */
+package net.jsunit;
+
+import net.jsunit.configuration.ConfigurationSource;
+import net.jsunit.model.Browser;
+
+public class FunctionalTestConfigurationSource implements ConfigurationSource {
+
+    private final int port;
+
+    public FunctionalTestConfigurationSource(int port) {
+        this.port = port;
+    }
+
+    public String resourceBase() {
+        return ".";
+    }
+
+    public String port() {
+        return String.valueOf(port);
+    }
+
+    public String logsDirectory() {
+        return "";
+    }
+
+    public String browserFileNames() {
+        return Browser.DEFAULT_SYSTEM_BROWSER + "," + Browser.DEFAULT_SYSTEM_BROWSER;
+    }
+
+    public String url() {
+        return "http://localhost:" + port + "/jsunit/testRunner.html?testPage=http://localhost:" + port + "/jsunit/tests/jsUnitUtilityTests.html&autoRun=true&submitresults=true";
+    }
+
+    public String ignoreUnresponsiveRemoteMachines() {
+        return "";
+    }
+
+    public String closeBrowsersAfterTestRuns() {
+        return String.valueOf(Boolean.TRUE);
+    }
+
+    public String description() {
+        return null;
+    }
+
+    public String logStatus() {
+        return String.valueOf(true);
+    }
+
+    public String timeoutSeconds() {
+        return "60";
+    }
+
+    public String remoteMachineURLs() {
+        return "http://www.example.com,http://www.example2.com";
+    }
+
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FunctionalTestFarmConfigurationSource.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FunctionalTestFarmConfigurationSource.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FunctionalTestFarmConfigurationSource.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,59 @@
+package net.jsunit;
+
+import net.jsunit.configuration.ConfigurationSource;
+
+public class FunctionalTestFarmConfigurationSource implements ConfigurationSource {
+
+    private int port;
+    private int remotePort;
+
+    public FunctionalTestFarmConfigurationSource(int port, int remotePort) {
+        this.port = port;
+        this.remotePort = remotePort;
+    }
+
+    public String resourceBase() {
+        return null;
+    }
+
+    public String port() {
+        return String.valueOf(port);
+    }
+
+    public String logsDirectory() {
+        return ".";
+    }
+
+    public String browserFileNames() {
+        return null;
+    }
+
+    public String url() {
+        return null;
+    }
+
+    public String ignoreUnresponsiveRemoteMachines() {
+        return null;
+    }
+
+    public String closeBrowsersAfterTestRuns() {
+        return null;
+    }
+
+    public String description() {
+        return null;
+    }
+
+    public String logStatus() {
+        return "true";
+    }
+
+    public String timeoutSeconds() {
+        return "60";
+    }
+
+    public String remoteMachineURLs() {
+        return "http://localhost:" + remotePort;
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FunctionalTestSuite.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FunctionalTestSuite.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/FunctionalTestSuite.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,25 @@
+package net.jsunit;
+
+import junit.framework.TestSuite;
+
+public class FunctionalTestSuite {
+
+    public static TestSuite suite() {
+        TestSuite result = new TestSuite();
+        result.addTestSuite(AcceptorFunctionalTest.class);
+        result.addTestSuite(ConfigurationFunctionalTest.class);
+        result.addTestSuite(DisplayerFunctionalTest.class);
+        result.addTestSuite(InvalidRemoteMachinesDistributedTestTest.class);
+        result.addTestSuite(FailedToLaunchBrowserStandaloneTestTest.class);
+        result.addTestSuite(ServerLandingPageFunctionalTest.class);
+        result.addTestSuite(OverrideURLDistributedTestTest.class);
+        result.addTestSuite(RemoteConfigurationSourceFunctionalTest.class);
+        result.addTestSuite(RunnerFunctionalTest.class);
+        result.addTestSuite(SpecificBrowserDistributedTestTest.class);
+        result.addTestSuite(SuccessfulStandaloneTestTest.class);
+        result.addTestSuite(TimedOutBrowserStandaloneTestTest.class);
+        result.addTestSuite(TwoValidLocalhostsDistributedTestTest.class);
+        result.addTestSuite(UrlOverrideStandaloneTestTest.class);
+        return result;
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/ImpureUnitTestSuite.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/ImpureUnitTestSuite.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/ImpureUnitTestSuite.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,55 @@
+package net.jsunit;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import net.jsunit.action.DistributedTestRunnerActionTest;
+import net.jsunit.action.FarmServerConfigurationActionTest;
+import net.jsunit.action.TestRunnerActionSimultaneousRunBlockingTest;
+import net.jsunit.action.TestRunnerActionTest;
+import net.jsunit.configuration.ConfigurationSourceResolutionTest;
+import net.jsunit.configuration.ConfigurationTest;
+import net.jsunit.configuration.EnvironmentVariablesConfigurationSourceTest;
+import net.jsunit.configuration.PropertiesConfigurationSourceTest;
+import net.jsunit.interceptor.BrowserResultInterceptorTest;
+import net.jsunit.interceptor.FarmServerInterceptorTest;
+import net.jsunit.interceptor.RequestSourceInterceptorTest;
+import net.jsunit.model.*;
+
+public class ImpureUnitTestSuite {
+
+    public static Test suite() {
+        TestSuite result = new TestSuite();
+        result.addTestSuite(BrowserResultInterceptorTest.class);
+        result.addTestSuite(BrowserResultTest.class);
+        result.addTestSuite(ClientServerInteractionTest.class);
+        result.addTestSuite(ClientServerConnectionTest.class);
+        result.addTestSuite(ConfigurationSourceResolutionTest.class);
+        result.addTestSuite(ConfigurationTest.class);
+        result.addTestSuite(DistributedTestRunResultBuilderTest.class);
+        result.addTestSuite(DistributedTestSuiteBuilderTest.class);
+        result.addTestSuite(EnvironmentVariablesConfigurationSourceTest.class);
+        result.addTestSuite(ExternallyShutDownBrowserResultTest.class);
+        result.addTestSuite(FailedToLaunchBrowserResultTest.class);
+        result.addTestSuite(FarmServerConfigurationActionTest.class);
+        result.addTestSuite(FarmServerInterceptorTest.class);
+        result.addTestSuite(DistributedTestRunManagerTest.class);
+        result.addTestSuite(DistributedTestRunnerActionTest.class);
+        result.addTestSuite(JsUnitFarmServerTest.class);
+        result.addTestSuite(JsUnitStandardServerTest.class);
+        result.addTestSuite(PropertiesConfigurationSourceTest.class);
+        result.addTestSuite(RemoteConfigurationSourceTest.class);
+        result.addTestSuite(RemoteMachineRunnerHitterTest.class);
+        result.addTestSuite(RemoteTestRunClientTest.class);
+        result.addTestSuite(RequestSourceInterceptorTest.class);
+        result.addTestSuite(ResultAcceptorTest.class);
+        result.addTestSuite(TestRunnerActionSimultaneousRunBlockingTest.class);
+        result.addTestSuite(TestRunNotifierServerTest.class);
+        result.addTestSuite(TestRunResultBuilderTest.class);
+        result.addTestSuite(TestRunManagerTest.class);
+        result.addTestSuite(TestRunResultTest.class);
+        result.addTestSuite(TestRunnerActionTest.class);
+        result.addTestSuite(TimeoutCheckerTest.class);
+        result.addTestSuite(TimedOutBrowerResultTest.class);
+        return result;
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/InvalidRemoteMachinesDistributedTestTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/InvalidRemoteMachinesDistributedTestTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/InvalidRemoteMachinesDistributedTestTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,39 @@
+package net.jsunit;
+
+import junit.framework.TestResult;
+import net.jsunit.configuration.ConfigurationSource;
+import net.jsunit.model.ResultType;
+
+public class InvalidRemoteMachinesDistributedTestTest extends EndToEndTestCase {
+
+    protected ConfigurationSource invalidRemoteMachinesFarmSource() {
+        return new StubConfigurationSource() {
+            public String remoteMachineURLs() {
+                return "http://invalid_machine1:8080, http://invalid_machine2:8080";
+            }
+            
+            public String port() {
+            	return String.valueOf(port);
+            }
+        };
+    }
+
+    protected ConfigurationSource serverSource() {
+        return new StubConfigurationSource() {
+        	public String port() {
+        		return String.valueOf(port);
+        	}
+        };
+    }
+
+    public void testUnresponsive() {
+        DistributedTest test = new DistributedTest(serverSource(), invalidRemoteMachinesFarmSource());
+        TestResult testResult = test.run();
+        assertFalse(testResult.wasSuccessful());
+        assertEquals(
+                ResultType.UNRESPONSIVE,
+                test.getDistributedTestRunManager().getDistributedTestRunResult().getResultType()
+        );
+    }
+
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/JsUnitFarmServerTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/JsUnitFarmServerTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/JsUnitFarmServerTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,20 @@
+package net.jsunit;
+
+import junit.framework.TestCase;
+import net.jsunit.configuration.Configuration;
+import net.jsunit.configuration.ServerType;
+
+public class JsUnitFarmServerTest extends TestCase {
+
+    private JsUnitFarmServer server;
+
+    public void setUp() throws Exception {
+        super.setUp();
+        server = new JsUnitFarmServer(new Configuration(new DummyFarmConfigurationSource()));
+    }
+
+    public void testStartTestRun() throws Exception {
+        assertEquals(ServerType.FARM, server.serverType());
+    }
+
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/JsUnitStandardServerTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/JsUnitStandardServerTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/JsUnitStandardServerTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,163 @@
+package net.jsunit;
+
+import junit.framework.TestCase;
+import net.jsunit.configuration.Configuration;
+import net.jsunit.configuration.ConfigurationException;
+import net.jsunit.model.Browser;
+import net.jsunit.model.BrowserResult;
+
+public class JsUnitStandardServerTest extends TestCase {
+
+    private JsUnitStandardServer server;
+
+    public void setUp() throws Exception {
+        super.setUp();
+        server = new JsUnitStandardServer(new Configuration(new DummyConfigurationSource()), new MockBrowserResultRepository(), false);
+    }
+
+    public void testStartTestRun() throws Exception {
+        server.setProcessStarter(new MockProcessStarter());
+        MockTestRunListener listener = new MockTestRunListener();
+        server.addBrowserTestRunListener(listener);
+        Thread thread = new Thread() {
+            public void run() {
+                try {
+                    server.startTestRun();
+                } catch (Exception e) {
+                    fail(e.toString());
+                }
+            }
+        };
+        thread.start();
+        Thread.sleep(500);
+        assertTrue(thread.isAlive());
+        listener.isReady = true;
+        thread.join();
+    }
+
+    public void testLaunchingBrowser() {
+        MockProcessStarter starter = new MockProcessStarter();
+        server.setProcessStarter(starter);
+        MockTestRunListener listener = new MockTestRunListener();
+        server.addBrowserTestRunListener(listener);
+
+        server.launchBrowserTestRun(new BrowserLaunchSpecification(new Browser(DummyConfigurationSource.BROWSER_FILE_NAME, 0)));
+        assertTrue(listener.browserTestRunStartedCalled);
+        assertEquals(2, starter.commandPassed.length);
+        assertEquals("mybrowser.exe", starter.commandPassed[0]);
+        assertEquals(DummyConfigurationSource.DUMMY_URL, starter.commandPassed[1]);
+        assertFalse(listener.testRunFinishedCalled);
+        server.accept(new DummyBrowserResult(true, 0, 0));
+        assertTrue(listener.browserTestRunFinishedCalled);
+    }
+
+    public void testLaunchingBrowserCrashes() throws InterruptedException {
+        BlowingUpProcessStarter starter = new BlowingUpProcessStarter();
+        server.setProcessStarter(starter);
+        MockTestRunListener listener = new MockTestRunListener();
+        server.addBrowserTestRunListener(listener);
+
+        long launchTime = server.launchBrowserTestRun(new BrowserLaunchSpecification(new Browser(DummyConfigurationSource.BROWSER_FILE_NAME, 0)));
+        assertTrue(listener.browserTestRunStartedCalled);
+        assertTrue(listener.browserTestRunFinishedCalled);
+        assertTrue(listener.result.failedToLaunch());
+        assertTrue(server.hasReceivedResultSince(launchTime));
+        assertEquals(new Browser("mybrowser.exe", 0), listener.browser);
+        assertEquals("mybrowser.exe", listener.result.getBrowser().getFileName());
+        assertSame(listener.result, server.lastResult());
+
+        server.setProcessStarter(new MockProcessStarter());
+        listener.reset();
+        launchTime = server.launchBrowserTestRun(new BrowserLaunchSpecification(new Browser("mybrowser2.exe", 1)));
+        assertFalse(server.hasReceivedResultSince(launchTime));
+        assertTrue(listener.browserTestRunStartedCalled);
+        assertFalse(listener.browserTestRunFinishedCalled);
+        assertEquals(new Browser("mybrowser2.exe", 1), listener.browser);
+    }
+
+    public void testStartEnd() {
+        server.setProcessStarter(new MockProcessStarter());
+        MockTestRunListener listener = new MockTestRunListener();
+        listener.isReady = true;
+        server.addBrowserTestRunListener(listener);
+        server.startTestRun();
+        assertTrue(listener.testRunStartedCalled);
+        server.finishTestRun();
+        assertTrue(listener.testRunFinishedCalled);
+    }
+
+    public void testAcceptResult() {
+        server.setProcessStarter(new MockProcessStarter());
+        server.launchBrowserTestRun(new BrowserLaunchSpecification(new Browser("mybrowser.exe", 0)));
+        BrowserResult result = new BrowserResult();
+        server.accept(result);
+        assertEquals("mybrowser.exe", result.getBrowser().getFileName());
+    }
+
+    public void testOverrideUrl() {
+        MockProcessStarter starter = new MockProcessStarter();
+        server.setProcessStarter(starter);
+        MockTestRunListener listener = new MockTestRunListener();
+        server.addBrowserTestRunListener(listener);
+
+        String overrideUrl = "http://my.example.com:8080?submitResults=true&autoRun=true";
+        server.launchBrowserTestRun(new BrowserLaunchSpecification(new Browser("mybrowser.exe", 0), overrideUrl));
+        assertEquals(2, starter.commandPassed.length);
+        assertEquals("mybrowser.exe", starter.commandPassed[0]);
+        assertEquals(overrideUrl, starter.commandPassed[1]);
+    }
+
+    public void testAddingSubmitResultsAndAutoRunParameters() throws Exception {
+        MockProcessStarter starter = new MockProcessStarter();
+        server.setProcessStarter(starter);
+        MockTestRunListener listener = new MockTestRunListener();
+        server.addBrowserTestRunListener(listener);
+
+        String overrideUrlWithoutSubmitResults = "http://my.example.com:8080?param=value";
+        server.launchBrowserTestRun(new BrowserLaunchSpecification(new Browser("mybrowser.exe", 0), overrideUrlWithoutSubmitResults));
+        assertEquals(2, starter.commandPassed.length);
+        assertEquals("mybrowser.exe", starter.commandPassed[0]);
+        assertEquals(
+                overrideUrlWithoutSubmitResults + "&autoRun=true&submitResults=localhost:1234/jsunit/acceptor",
+                starter.commandPassed[1]
+        );
+    }
+
+    public void testNoURLSpecified() throws Exception {
+        server = new JsUnitStandardServer(new Configuration(new DummyConfigurationSource() {
+            public String url() {
+                return "";
+            }
+        }), new MockBrowserResultRepository(), false);
+        MockProcessStarter starter = new MockProcessStarter();
+        server.setProcessStarter(starter);
+        server.launchBrowserTestRun(new BrowserLaunchSpecification(new Browser("mybrowser.exe", 0)));
+        assertFalse(server.lastResult().wasSuccessful());
+        assertTrue(server.lastResult().getServerSideExceptionStackTrace().indexOf(NoUrlSpecifiedException.class.getName()) != -1);
+    }
+
+    public void testInvalidConfiguration() {
+        try {
+            server = new JsUnitStandardServer(new Configuration(new InvalidConfigurationSource()), false);
+            fail();
+        } catch (ConfigurationException e) {
+
+        }
+    }
+
+    public void testAwaitingBrowserSubmission() throws Exception {
+        server.setProcessStarter(new MockProcessStarter());
+        assertFalse(server.isAwaitingBrowserSubmission());
+        server.launchBrowserTestRun(new BrowserLaunchSpecification(new Browser("foo.exe", 1)));
+        assertTrue(server.isAwaitingBrowserSubmission());
+    }
+
+    static class InvalidConfigurationSource extends DummyConfigurationSource {
+
+        public String url() {
+            return "invalid url";
+        }
+
+    }
+
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/MockBrowserResultRepository.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/MockBrowserResultRepository.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/MockBrowserResultRepository.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,21 @@
+package net.jsunit;
+
+import net.jsunit.logging.BrowserResultRepository;
+import net.jsunit.model.Browser;
+import net.jsunit.model.BrowserResult;
+
+public class MockBrowserResultRepository implements BrowserResultRepository {
+    public BrowserResult storedResult;
+    public String requestedId;
+    public Browser requestedBrowser;
+
+    public void store(BrowserResult result) {
+        this.storedResult = result;
+    }
+
+    public BrowserResult retrieve(String id, Browser browser) {
+        this.requestedId = id;
+        this.requestedBrowser = browser;
+        return null;
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/MockProcessStarter.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/MockProcessStarter.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/MockProcessStarter.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,14 @@
+package net.jsunit;
+
+import java.io.IOException;
+
+public class MockProcessStarter implements ProcessStarter {
+
+    public String[] commandPassed;
+
+    public Process execute(String[] command) throws IOException {
+        this.commandPassed = command;
+        return null;
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/MockRemoteServerHitter.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/MockRemoteServerHitter.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/MockRemoteServerHitter.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,24 @@
+/**
+ * 
+ */
+package net.jsunit;
+
+import org.jdom.Document;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class MockRemoteServerHitter implements RemoteServerHitter {
+
+    public List<String> urlsPassed = new ArrayList<String>();
+    public Map<String, Document> urlToDocument = new HashMap<String, Document>();
+
+    public Document hitURL(URL url) {
+        String urlString = url.toString();
+        urlsPassed.add(urlString);
+        return urlToDocument.get(urlString);
+    }
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/OverrideURLDistributedTestTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/OverrideURLDistributedTestTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/OverrideURLDistributedTestTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,49 @@
+package net.jsunit;
+
+import junit.framework.TestResult;
+import net.jsunit.configuration.ConfigurationSource;
+import net.jsunit.model.Browser;
+import net.jsunit.model.ResultType;
+
+public class OverrideURLDistributedTestTest extends EndToEndTestCase {
+
+    protected ConfigurationSource farmSource() {
+        return new StubConfigurationSource() {
+            public String remoteMachineURLs() {
+                return "http://localhost:" + port;
+            }
+        };
+    }
+
+    protected ConfigurationSource serverSourceWithBadTestURL() {
+        return new StubConfigurationSource() {
+            public String browserFileNames() {
+                return Browser.DEFAULT_SYSTEM_BROWSER;
+            }
+
+            public String url() {
+                return "http://www.example.com";
+            }
+
+            public String port() {
+                return String.valueOf(port);
+            }
+        };
+    }
+
+    public void testOverrideURL() throws Throwable {
+        DistributedTest test = new DistributedTest(serverSourceWithBadTestURL(), farmSource());
+        test.getDistributedTestRunManager().setOverrideURL(
+                "http://localhost:" + port + "/jsunit/testRunner.html?" +
+                        "testPage=http://localhost:" + port + "/jsunit/tests/jsUnitUtilityTests.html&autoRun=true&submitresults=true"
+        );
+        TestResult result = test.run();
+
+        assertEquals(
+                ResultType.SUCCESS,
+                test.getDistributedTestRunManager().getDistributedTestRunResult().getResultType()
+        );
+        assertTrue(result.wasSuccessful());
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/PureUnitTestSuite.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/PureUnitTestSuite.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/PureUnitTestSuite.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,37 @@
+package net.jsunit;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import net.jsunit.action.ErrorXmlRenderableTest;
+import net.jsunit.action.LatestVersionActionTest;
+import net.jsunit.action.ResultAcceptorActionTest;
+import net.jsunit.action.ResultDisplayerActionTest;
+import net.jsunit.configuration.ArgumentsConfigurationSourceTest;
+import net.jsunit.interceptor.BrowserTestRunnerInterceptorTest;
+import net.jsunit.interceptor.RemoteRunnerHitterInterceptorTest;
+import net.jsunit.interceptor.VersionGrabberInterceptorTest;
+import net.jsunit.model.BrowserTest;
+import net.jsunit.model.TestCaseResultTest;
+import net.jsunit.model.TestPageResultTest;
+
+public class PureUnitTestSuite {
+
+    public static Test suite() {
+        TestSuite result = new TestSuite();
+        result.addTestSuite(ArgumentsConfigurationSourceTest.class);
+        result.addTestSuite(BrowserLaunchSpecificationTest.class);
+        result.addTestSuite(BrowserResultLogWriterTest.class);
+        result.addTestSuite(BrowserTest.class);
+        result.addTestSuite(BrowserTestRunnerInterceptorTest.class);
+        result.addTestSuite(ErrorXmlRenderableTest.class);
+        result.addTestSuite(DistributedTestRunResultTest.class);
+        result.addTestSuite(LatestVersionActionTest.class);
+        result.addTestSuite(RemoteRunnerHitterInterceptorTest.class);
+        result.addTestSuite(ResultAcceptorActionTest.class);
+        result.addTestSuite(ResultDisplayerActionTest.class);
+        result.addTestSuite(TestCaseResultTest.class);
+        result.addTestSuite(TestPageResultTest.class);
+        result.addTestSuite(VersionGrabberInterceptorTest.class);
+        return result;
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/RemoteConfigurationSourceFunctionalTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/RemoteConfigurationSourceFunctionalTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/RemoteConfigurationSourceFunctionalTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,20 @@
+package net.jsunit;
+
+import net.jsunit.configuration.Configuration;
+import net.jsunit.configuration.ServerType;
+import net.jsunit.utility.XmlUtility;
+
+public class RemoteConfigurationSourceFunctionalTest extends FunctionalTestCase {
+
+    public void testSimple() throws Exception {
+        String remoteMachineURL = "http://localhost:" + port + "/jsunit";
+        RemoteConfigurationSource source = new RemoteConfigurationSource(new RemoteMachineServerHitter(), remoteMachineURL);
+        assertTrue(source.isInitialized());
+        Configuration remoteConfiguration = new Configuration(source);
+        assertEquals(
+                XmlUtility.asString(configuration.asXml(ServerType.STANDARD)),
+                XmlUtility.asString(remoteConfiguration.asXml(ServerType.STANDARD))
+        );
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/RemoteConfigurationSourceTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/RemoteConfigurationSourceTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/RemoteConfigurationSourceTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,36 @@
+package net.jsunit;
+
+import junit.framework.TestCase;
+import net.jsunit.configuration.Configuration;
+import net.jsunit.configuration.ServerType;
+import net.jsunit.utility.XmlUtility;
+import org.jdom.Document;
+
+public class RemoteConfigurationSourceTest extends TestCase {
+    private String baseURL;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        baseURL = "http://www.example.com:1234/jsunit";
+    }
+
+    public void testSimple() throws Exception {
+        Configuration configuration = new Configuration(new DummyConfigurationSource());
+        MockRemoteServerHitter mockHitter = new MockRemoteServerHitter();
+        mockHitter.urlToDocument.put(baseURL + "/config", new Document(configuration.asXml(ServerType.STANDARD)));
+
+        RemoteConfigurationSource remoteSource = new RemoteConfigurationSource(mockHitter, baseURL);
+        assertTrue(remoteSource.isInitialized());
+
+        Configuration remoteConfiguration = new Configuration(remoteSource);
+        assertEquals(XmlUtility.asString(configuration.asXml(ServerType.STANDARD)),
+                XmlUtility.asString(remoteConfiguration.asXml(ServerType.STANDARD))
+        );
+    }
+
+    public void testBlowingUpURL() throws Exception {
+        RemoteConfigurationSource remoteSource = new RemoteConfigurationSource(new BlowingUpRemoteServerHitter(), baseURL);
+        assertFalse(remoteSource.isInitialized());
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/RemoteMachineRunnerHitterTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/RemoteMachineRunnerHitterTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/RemoteMachineRunnerHitterTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,59 @@
+// Copyright 2005 Google Inc.
+// All Rights Reserved.
+package net.jsunit;
+
+import junit.framework.TestCase;
+import net.jsunit.utility.XmlUtility;
+import org.jdom.Document;
+
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+
+public class RemoteMachineRunnerHitterTest extends TestCase {
+
+    String xml = "<my_document><my_node value=\"1\">my text</my_node></my_document>";
+
+    public void testAllAtOnce() throws Exception {
+        RemoteMachineServerHitter hitter = new RemoteMachineServerHitter();
+        Document document = hitter.hitURL(createURL(xml, xml.length()));
+        assertDocumentHasXml(xml, document);
+    }
+
+    public void testAPieceAtATime() throws Exception {
+        RemoteMachineServerHitter hitter = new RemoteMachineServerHitter();
+        Document document = hitter.hitURL(createURL(xml, 3));
+        assertDocumentHasXml(xml, document);
+    }
+
+    private void assertDocumentHasXml(String expectedXML, Document document) {
+        assertEquals(expectedXML, XmlUtility.asString(document.getRootElement()));
+    }
+
+    private URL createURL(final String xml, final int byteCount) throws MalformedURLException {
+        return new URL("http", "www.example.com", 8080, "foo", new URLStreamHandler() {
+            protected URLConnection openConnection(URL u) {
+                return new URLConnection(u) {
+                    public void connect() {
+                    }
+
+                    public InputStream getInputStream() {
+                        return new InputStream() {
+
+                            private int index = 0;
+
+                            public int read() {
+                                if (index >= xml.length())
+                                    return -1;
+                                return xml.codePointAt(index++);
+                            }
+                        };
+                    }
+                };
+            }
+        });
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/ResultAcceptorTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/ResultAcceptorTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/ResultAcceptorTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,116 @@
+package net.jsunit;
+
+import junit.framework.TestCase;
+import net.jsunit.configuration.Configuration;
+import net.jsunit.interceptor.BrowserResultInterceptor;
+import net.jsunit.model.Browser;
+import net.jsunit.model.BrowserResult;
+import net.jsunit.model.BrowserResultWriter;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.Map;
+
+public class ResultAcceptorTest extends TestCase {
+
+    protected Map<String, String[]> requestMap;
+    private JsUnitStandardServer server;
+    private MockBrowserResultRepository mockBrowserResultRepository;
+
+    public void setUp() throws Exception {
+        super.setUp();
+        Configuration configuration = new Configuration(new StubConfigurationSource() {
+
+            public String browserFileNames() {
+                return "browser1.exe,browser2.exe,browser3.exe";
+            }
+
+            public String logStatus() {
+                return String.valueOf(Boolean.FALSE);
+            }
+
+            public String url() {
+                return "http://bar";
+            }
+
+        });
+        mockBrowserResultRepository = new MockBrowserResultRepository();
+        server = new JsUnitStandardServer(configuration, mockBrowserResultRepository, false);
+        server.setProcessStarter(new MockProcessStarter());
+        requestMap = new HashMap<String, String[]>();
+        requestMap.put(BrowserResultWriter.ID, new String[]{"ID_foo"});
+        requestMap.put(BrowserResultWriter.USER_AGENT, new String[]{"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"});
+        requestMap.put(BrowserResultWriter.TIME, new String[]{"4.3"});
+        requestMap.put(BrowserResultWriter.JSUNIT_VERSION, new String[]{"2.5"});
+        requestMap.put(BrowserResultWriter.TEST_CASES, dummyTestCaseStrings());
+    }
+
+    protected String[] dummyTestCaseStrings() {
+        return new String[]{"file:///dummy/path/dummyPage.html:testFoo|1.3|S||", "file:///dummy/path/dummyPage.html:testFoo|1.3|E|Test Error Message|", "file:///dummy/path/dummyPage.html:testFoo|1.3|F|Test Failure Message|"};
+    }
+
+    protected void submit() {
+        server.launchBrowserTestRun(new BrowserLaunchSpecification(new Browser("browser2.exe", 1)));
+        HttpServletRequest request = new DummyHttpRequest(requestMap);
+        server.accept(new BrowserResultInterceptor().build(request));
+    }
+
+    public void testSubmitResults() {
+        assertEquals(0, server.getResults().size());
+        submit();
+        assertEquals(1, server.getResults().size());
+        submit();
+        assertEquals(1, server.getResults().size());
+    }
+
+    public void testSubmittedResultHeaders() {
+        submit();
+        BrowserResult result = server.getResults().get(0);
+        assertEquals("ID_foo", result.getId());
+        assertEquals("Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)", result.getUserAgent());
+        assertEquals("2.5", result.getJsUnitVersion());
+        assertEquals(1, result.getErrorCount());
+        assertEquals(1, result.getFailureCount());
+        assertEquals(3, result.getTestCount());
+        assertEquals(4.3d, result.getTime(), .001d);
+    }
+
+    public void testSubmittedTestCaseResults() {
+        submit();
+        BrowserResult result = server.getResults().get(0);
+        assertEquals(3, result.getTestCaseResults().size());
+    }
+
+    public void testHasReceivedResultSinceDate() throws InterruptedException {
+        assertFalse(server.hasReceivedResultSince(System.currentTimeMillis()));
+        long time = System.currentTimeMillis();
+        Thread.sleep(100);
+        submit();
+        assertTrue(server.hasReceivedResultSince(time));
+    }
+
+    public void testFindResultByIdInMemoryOrOnDisk() throws InvalidBrowserIdException {
+        assertNull(server.findResultWithId("ID_foo", 1));
+        assertEquals("ID_foo", mockBrowserResultRepository.requestedId);
+        assertEquals(1, mockBrowserResultRepository.requestedBrowser.getId());
+        submit();
+        mockBrowserResultRepository.requestedId = null;
+        assertFalse(server.getResults().isEmpty());
+        assertNotNull(server.findResultWithId("ID_foo", 1));
+        assertNull(mockBrowserResultRepository.requestedId);
+        assertNull(server.findResultWithId("Invalid ID", 1));
+        assertEquals("Invalid ID", mockBrowserResultRepository.requestedId);
+        mockBrowserResultRepository.requestedId = null;
+        server.clearResults();
+        assertTrue(server.getResults().isEmpty());
+        server.findResultWithId("ID_foo", 1);
+        assertEquals("ID_foo", mockBrowserResultRepository.requestedId);
+        assertEquals(1, mockBrowserResultRepository.requestedBrowser.getId());
+    }
+
+    public void testLog() {
+        submit();
+        assertEquals("ID_foo", mockBrowserResultRepository.storedResult.getId());
+    }
+
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/RunnerFunctionalTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/RunnerFunctionalTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/RunnerFunctionalTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,47 @@
+package net.jsunit;
+
+import net.jsunit.model.ResultType;
+import org.jdom.Document;
+
+import java.net.URLEncoder;
+
+public class RunnerFunctionalTest extends FunctionalTestCase {
+
+    public void testSimple() throws Exception {
+        webTester.beginAt("runner");
+        Document result = responseXmlDocument();
+        assertSuccessfulRunResult(
+                result,
+                ResultType.SUCCESS,
+                "http://localhost:" + port + "/jsunit/tests/jsUnitUtilityTests.html", 2);
+    }
+
+    public void testOverrideUrl() throws Exception {
+        webTester.beginAt("runner?url=" + URLEncoder.encode("http://127.0.0.1:" + port + "/jsunit/testRunner.html?testPage=http://127.0.0.1:" + port + "/jsunit/tests/jsUnitUtilityTests.html&autoRun=true&submitresults=true", "UTF-8"));
+        Document result = responseXmlDocument();
+        assertSuccessfulRunResult(
+                result,
+                ResultType.SUCCESS,
+                "http://127.0.0.1:" + port + "/jsunit/tests/jsUnitUtilityTests.html", 2);
+    }
+
+    public void testSpecifyBrowser() throws Exception {
+        webTester.beginAt("runner?browserId=0");
+        Document result = responseXmlDocument();
+        assertSuccessfulRunResult(
+                result,
+                ResultType.SUCCESS,
+                "http://localhost:" + port + "/jsunit/tests/jsUnitUtilityTests.html", 1);
+    }
+
+    public void testSpecifyInvalidBrowser() throws Exception {
+        webTester.beginAt("runner?browserId=23");
+        Document result = responseXmlDocument();
+        assertErrorResponse(result.getRootElement(), "Invalid browser ID: 23");
+    }
+
+    protected boolean shouldMockOutProcessStarter() {
+        return false;
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/ServerLandingPageFunctionalTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/ServerLandingPageFunctionalTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/ServerLandingPageFunctionalTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,81 @@
+package net.jsunit;
+
+import net.jsunit.model.Browser;
+import net.jsunit.model.BrowserResult;
+import net.jsunit.model.ResultType;
+import net.jsunit.utility.SystemUtility;
+import net.jsunit.utility.XmlUtility;
+import org.jdom.Document;
+
+public class ServerLandingPageFunctionalTest extends FunctionalTestCase {
+
+    public void testSlash() throws Exception {
+        webTester.beginAt("/");
+        assertOnLandingPage();
+        webTester.assertTextPresent(SystemUtility.osString());
+        webTester.assertTextPresent(SystemUtility.hostname());
+        webTester.assertTextPresent(SystemUtility.ipAddress());
+        webTester.assertLinkPresentWithText(new FunctionalTestConfigurationSource(port).url());
+    }
+
+    public void testIndexDotJsp() throws Exception {
+        webTester.beginAt("/index.jsp");
+        assertOnLandingPage();
+    }
+
+    public void testConfigLink() throws Exception {
+        webTester.beginAt("/");
+        webTester.clickLink("config");
+        assertConfigXml();
+    }
+
+    protected boolean shouldMockOutProcessStarter() {
+        return false;
+    }
+
+    public void testRunnerForParticularBrowser() throws Exception {
+        webTester.beginAt("/");
+        webTester.setWorkingForm("runnerForm");
+        webTester.selectOption("browserId", Browser.DEFAULT_SYSTEM_BROWSER);
+        webTester.setFormElement("url", "http://localhost:" + port + "/jsunit/testRunner.html?testPage=http://localhost:" + port + "/jsunit/tests/jsUnitAssertionTests.html");
+        webTester.submit();
+        assertSuccessfulRunResult(
+                responseXmlDocument(),
+                ResultType.SUCCESS,
+                "http://localhost:" + port + "/jsunit/tests/jsUnitAssertionTests.html",
+                1
+        );
+    }
+
+    public void testRunnerForAllBrowsers() throws Exception {
+        webTester.beginAt("/");
+        webTester.setWorkingForm("runnerForm");
+        webTester.setFormElement("url", "http://localhost:" + port + "/jsunit/testRunner.html?testPage=http://localhost:" + port + "/jsunit/tests/jsUnitAssertionTests.html");
+        webTester.submit();
+        assertSuccessfulRunResult(
+                responseXmlDocument(),
+                ResultType.SUCCESS,
+                "http://localhost:" + port + "/jsunit/tests/jsUnitAssertionTests.html",
+                2
+        );
+    }
+
+    public void testDisplayerForm() throws Exception {
+        server.launchBrowserTestRun(new BrowserLaunchSpecification(new Browser(Browser.DEFAULT_SYSTEM_BROWSER, 0)));
+        BrowserResult browserResult = new BrowserResult();
+        String id = String.valueOf(System.currentTimeMillis());
+        browserResult.setId(id);
+        server.accept(browserResult);
+        webTester.beginAt("/");
+        webTester.setWorkingForm("displayerForm");
+        webTester.setFormElement("id", id);
+        webTester.selectOption("browserId", Browser.DEFAULT_SYSTEM_BROWSER);
+        webTester.submit();
+        assertEquals(XmlUtility.asString(new Document(browserResult.asXml())), webTester.getDialog().getResponseText());
+    }
+
+    private void assertOnLandingPage() {
+        webTester.assertTitleEquals("JsUnit  Server");
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/SpecificBrowserDistributedTestTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/SpecificBrowserDistributedTestTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/SpecificBrowserDistributedTestTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,54 @@
+package net.jsunit;
+
+import junit.framework.TestResult;
+import net.jsunit.configuration.ConfigurationSource;
+import net.jsunit.model.Browser;
+import net.jsunit.model.DistributedTestRunResult;
+import net.jsunit.model.ResultType;
+
+public class SpecificBrowserDistributedTestTest extends EndToEndTestCase {
+
+    protected ConfigurationSource farmSource() {
+        return new StubConfigurationSource() {
+            public String remoteMachineURLs() {
+                return "http://localhost:" + port;
+            }
+
+            public String port() {
+                return String.valueOf(port);
+            }
+
+        };
+    }
+
+    protected StubConfigurationSource serverSource() {
+        return new StubConfigurationSource() {
+
+            public String browserFileNames() {
+                return "invalid1.exe," + Browser.DEFAULT_SYSTEM_BROWSER + ",invalid2.exe";
+            }
+
+            public String url() {
+                return "http://localhost:" + port + "/jsunit/testRunner.html?"
+                        + "testPage=http://localhost:" + port + "/jsunit/tests/jsUnitUtilityTests.html&autoRun=true&submitresults=true";
+            }
+
+            public String port() {
+                return String.valueOf(port);
+            }
+        };
+    }
+
+    public void testSuccessfulRun() {
+        DistributedTest test = new DistributedTest(serverSource(), farmSource());
+        test.limitToBrowser(new Browser(Browser.DEFAULT_SYSTEM_BROWSER, 1));
+        TestResult testResult = test.run();
+        assertTrue(testResult.wasSuccessful());
+        DistributedTestRunResult distributedTestRunResult = test.getDistributedTestRunManager().getDistributedTestRunResult();
+        assertEquals(ResultType.SUCCESS, distributedTestRunResult.getResultType());
+        assertEquals(1, distributedTestRunResult.getTestRunResults().size());
+
+        assertNull(test.getTemporaryStandardServer());
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/SuccessfulStandaloneTestTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/SuccessfulStandaloneTestTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/SuccessfulStandaloneTestTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,35 @@
+package net.jsunit;
+
+import junit.framework.TestResult;
+import net.jsunit.configuration.ConfigurationSource;
+import net.jsunit.model.Browser;
+
+public class SuccessfulStandaloneTestTest extends EndToEndTestCase {
+
+    protected ConfigurationSource configurationSource() {
+        return new StubConfigurationSource() {
+            public String browserFileNames() {
+                return Browser.DEFAULT_SYSTEM_BROWSER + "," + Browser.DEFAULT_SYSTEM_BROWSER;
+            }
+
+            public String url() {
+                return "http://localhost:" + port + "/jsunit/testRunner.html?" +
+                        "testPage=http://localhost:" + port + "/jsunit/tests/jsUnitTestSuite.html" +
+                        "&autoRun=true&submitresults=true&resultId=foobar";
+            }
+
+            public String port() {
+                return String.valueOf(port);
+            }
+
+        };
+    }
+
+    public void testSuccessfulRun() throws Exception {
+        StandaloneTest test = new StandaloneTest(configurationSource());
+        TestResult result = test.run();
+        assertTrue(result.wasSuccessful());
+        assertTrue(test.getServer().lastResult().wasSuccessful());
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/TestPortManager.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/TestPortManager.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/TestPortManager.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,15 @@
+package net.jsunit;
+
+public class TestPortManager {
+
+    /**
+     * Unassigned range from 48004 to 48555:
+     * @see <a href="http://www.iana.org/assignments/port-numbers">IANA Port Assignments</a>
+     */
+    private static int port = 48004;
+
+	public int newPort() {
+		return port++;
+	}
+	
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/TestRunManagerTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/TestRunManagerTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/TestRunManagerTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,240 @@
+package net.jsunit;
+
+import junit.framework.TestCase;
+import net.jsunit.model.Browser;
+import net.jsunit.model.BrowserResult;
+import net.jsunit.model.TestRunResult;
+import net.jsunit.utility.SystemUtility;
+import org.jdom.Element;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class TestRunManagerTest extends TestCase {
+
+    public void testDisposedDuringTestRun() throws InterruptedException {
+        KillableBrowserTestRunner runner = new KillableBrowserTestRunner();
+        final TestRunManager manager = new TestRunManager(runner);
+        Thread thread = new Thread() {
+            public void run() {
+                manager.runTests();
+            }
+        };
+        thread.start();
+        while (!runner.startTestRunCalled)
+            Thread.sleep(10);
+        runner.isAlive = false;
+        thread.join();
+        assertTrue(runner.finishTestRunCalled);
+    }
+
+    public void testOverrideUrl() {
+        MockBrowserTestRunner runner = new MockBrowserTestRunner();
+        runner.hasReceivedResult = true;
+        String overrideUrl = "http://my.override.url:8080/jsunit/testRunner.html?someParam=someValue&someOtherParam=someOtherValue";
+        TestRunManager manager = new TestRunManager(runner, overrideUrl);
+        manager.runTests();
+
+        assertEquals(2, runner.launchSpecs.size());
+        BrowserLaunchSpecification spec1 = runner.launchSpecs.get(0);
+        assertTrue(spec1.hasOverrideUrl());
+        assertEquals(overrideUrl, spec1.getOverrideUrl());
+        BrowserLaunchSpecification spec2 = runner.launchSpecs.get(1);
+        assertTrue(spec2.hasOverrideUrl());
+        assertEquals(overrideUrl, spec2.getOverrideUrl());
+    }
+
+    public void testNoOverrideUrl() {
+        MockBrowserTestRunner runner = new MockBrowserTestRunner();
+        runner.hasReceivedResult = true;
+        TestRunManager manager = new TestRunManager(runner, null);
+        manager.runTests();
+
+        assertEquals(2, runner.launchSpecs.size());
+        assertFalse(runner.launchSpecs.get(0).hasOverrideUrl());
+        assertFalse(runner.launchSpecs.get(1).hasOverrideUrl());
+    }
+
+    public void testPropertiesSet() throws Exception {
+        MockBrowserTestRunner runner = new MockBrowserTestRunner();
+        runner.hasReceivedResult = true;
+        TestRunManager manager = new TestRunManager(runner, null);
+        manager.runTests();
+        TestRunResult testRunResult = manager.getTestRunResult();
+        assertEquals(SystemUtility.osString(), testRunResult.getOsString());
+        assertEquals(SystemUtility.ipAddress(), testRunResult.getIpAddress());
+        assertEquals(SystemUtility.hostname(), testRunResult.getHostname());
+    }
+
+    static class SuccessfulBrowserTestRunner implements BrowserTestRunner {
+
+        public List<Browser> getBrowsers() {
+            return Arrays.asList(new Browser("browser1.exe", 0), new Browser("browser2.exe", 1));
+        }
+
+        public long launchBrowserTestRun(BrowserLaunchSpecification launchSpec) {
+            return 0;
+        }
+
+        public boolean hasReceivedResultSince(long launchTime) {
+            return true;
+        }
+
+        public BrowserResult lastResult() {
+            return new DummyBrowserResult(true, 0, 0);
+        }
+
+        public void accept(BrowserResult result) {
+        }
+
+        public void dispose() {
+        }
+
+        public BrowserResult findResultWithId(String id, int browserId) {
+            return null;
+        }
+
+        public Element asXml() {
+            return null;
+        }
+
+        public void startTestRun() {
+        }
+
+        public void finishTestRun() {
+        }
+
+        public void logStatus(String message) {
+        }
+
+        public int timeoutSeconds() {
+            return 0;
+        }
+
+        public boolean isAlive() {
+            return true;
+        }
+
+    }
+
+    static class FailingBrowserTestRunner implements BrowserTestRunner {
+
+        private Browser currentBrowser;
+
+        public List<Browser> getBrowsers() {
+            return Arrays.asList(
+                    new Browser("browser1.exe", 0),
+                    new Browser("browser2.exe", 1),
+                    new Browser("browser3.exe", 2)
+            );
+        }
+
+        public long launchBrowserTestRun(BrowserLaunchSpecification launchSpec) {
+            currentBrowser = launchSpec.getBrowser();
+            return 0;
+        }
+
+        public boolean hasReceivedResultSince(long launchTime) {
+            return true;
+        }
+
+        public BrowserResult lastResult() {
+            if (currentBrowser.hasId(0))
+                return new DummyBrowserResult(false, 0, 1);
+            else if (currentBrowser.hasId(1))
+                return new DummyBrowserResult(false, 1, 0);
+            else
+                return new DummyBrowserResult(false, 2, 3);
+        }
+
+        public void accept(BrowserResult result) {
+        }
+
+        public void dispose() {
+        }
+
+        public BrowserResult findResultWithId(String id, int browserId) {
+            return null;
+        }
+
+        public Element asXml() {
+            return null;
+        }
+
+        public void startTestRun() {
+        }
+
+        public void finishTestRun() {
+        }
+
+        public void logStatus(String message) {
+        }
+
+        public int timeoutSeconds() {
+            return 0;
+        }
+
+        public boolean isAlive() {
+            return true;
+        }
+
+    }
+
+    static class KillableBrowserTestRunner implements BrowserTestRunner {
+
+        private boolean isAlive;
+        private boolean startTestRunCalled;
+        private boolean finishTestRunCalled;
+
+        public void startTestRun() {
+            startTestRunCalled = true;
+        }
+
+        public void finishTestRun() {
+            finishTestRunCalled = true;
+        }
+
+        public long launchBrowserTestRun(BrowserLaunchSpecification launchSpec) {
+            return 0;
+        }
+
+        public void accept(BrowserResult result) {
+        }
+
+        public boolean hasReceivedResultSince(long launchTime) {
+            return false;
+        }
+
+        public BrowserResult lastResult() {
+            return null;
+        }
+
+        public void dispose() {
+        }
+
+        public BrowserResult findResultWithId(String id, int browserId) {
+            return null;
+        }
+
+        public void logStatus(String message) {
+        }
+
+        public List<Browser> getBrowsers() {
+            return Arrays.asList(new Browser("browser1.exe", 0));
+        }
+
+        public int timeoutSeconds() {
+            return 0;
+        }
+
+        public boolean isAlive() {
+            return isAlive;
+        }
+
+        public Element asXml() {
+            return null;
+        }
+
+    }
+
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/TimedOutBrowserStandaloneTestTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/TimedOutBrowserStandaloneTestTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/TimedOutBrowserStandaloneTestTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,40 @@
+package net.jsunit;
+
+import junit.framework.TestResult;
+import net.jsunit.configuration.ConfigurationSource;
+import net.jsunit.model.Browser;
+import net.jsunit.model.ResultType;
+
+public class TimedOutBrowserStandaloneTestTest extends EndToEndTestCase {
+
+    protected ConfigurationSource configurationSource() {
+        return new StubConfigurationSource() {
+            public String browserFileNames() {
+                return Browser.DEFAULT_SYSTEM_BROWSER;
+            }
+
+            public String url() {
+                return "http://localhost:" + port + "/jsunit/testRunner.html?" +
+                        "testPage=http://localhost:" + port + "/jsunit/tests/jsUnitTestSuite.html" +
+                        "&autoRun=true&submitresults=true&resultId=foobar";
+            }
+
+            public String timeoutSeconds() {
+                return "0";
+            }
+
+            public String port() {
+                return String.valueOf(port);
+            }
+
+        };
+    }
+
+    public void testBrowserTimesOut() throws Exception {
+        StandaloneTest test = new StandaloneTest(configurationSource());
+        TestResult result = test.run();
+        assertEquals(ResultType.TIMED_OUT, test.getServer().lastResult().getResultType());
+        assertFalse(result.wasSuccessful());
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/TimeoutCheckerTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/TimeoutCheckerTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/TimeoutCheckerTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,97 @@
+package net.jsunit;
+
+import junit.framework.TestCase;
+import net.jsunit.model.Browser;
+import net.jsunit.model.ResultType;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+public class TimeoutCheckerTest extends TestCase {
+
+    private MockBrowserTestRunner mockRunner;
+    private TimeoutChecker checker;
+    private MockProcess mockProcess;
+
+    public void setUp() throws Exception {
+        super.setUp();
+        mockRunner = new MockBrowserTestRunner();
+        mockRunner.timeoutSeconds = Integer.MAX_VALUE;
+        mockProcess = new MockProcess();
+        checker = new TimeoutChecker(mockProcess, new Browser("mybrowser.exe", 0), 1, mockRunner, 1);
+        checker.start();
+    }
+
+    public void tearDown() throws Exception {
+        if (checker != null && checker.isAlive()) {
+            checker.die();
+        }
+        super.tearDown();
+    }
+
+    public void testInitialConditions() {
+        assertTrue(checker.isAlive());
+    }
+
+    public void testDie() throws InterruptedException {
+        checker.die();
+        Thread.sleep(10);
+        assertFalse(checker.isAlive());
+    }
+
+    public void testTimeOut() throws InterruptedException {
+        mockRunner.timeoutSeconds = 0;
+        while (mockRunner.acceptedResult == null)
+            Thread.sleep(10);
+        assertEquals(ResultType.TIMED_OUT, mockRunner.acceptedResult.getResultType());
+    }
+
+    public void testNotTimeOut() throws InterruptedException {
+        mockRunner.hasReceivedResult = true;
+        while (checker.isAlive())
+            Thread.sleep(10);
+        assertFalse(checker.isAlive());
+    }
+
+    public void xtestExternallyShutDown() throws InterruptedException {
+        assertFalse(mockRunner.hasReceivedResult);
+        mockProcess.done = true;
+        while (mockRunner.acceptedResult == null)
+            Thread.sleep(10);
+        assertTrue(mockRunner.acceptedResult.externallyShutDown());
+        assertFalse(checker.isAlive());
+    }
+
+    static class MockProcess extends Process {
+
+        private boolean done = false;
+
+        public OutputStream getOutputStream() {
+            return null;
+        }
+
+        public InputStream getInputStream() {
+            return null;
+        }
+
+        public InputStream getErrorStream() {
+            return null;
+        }
+
+        public int waitFor() throws InterruptedException {
+            return 0;
+        }
+
+        public int exitValue() {
+            if (!done)
+                throw new IllegalThreadStateException();
+            else
+                return 0;
+        }
+
+        public void destroy() {
+        }
+
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/TwoValidLocalhostsDistributedTestTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/TwoValidLocalhostsDistributedTestTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/TwoValidLocalhostsDistributedTestTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,87 @@
+package net.jsunit;
+
+import junit.framework.TestResult;
+import net.jsunit.configuration.Configuration;
+import net.jsunit.configuration.ConfigurationSource;
+import net.jsunit.model.Browser;
+import net.jsunit.model.DistributedTestRunResult;
+import net.jsunit.model.ResultType;
+
+public class TwoValidLocalhostsDistributedTestTest extends EndToEndTestCase {
+    private JsUnitStandardServer secondServer;
+    private int otherPort;
+
+    public void setUp() throws Exception {
+        super.setUp();
+        otherPort = new TestPortManager().newPort();
+        secondServer = new JsUnitStandardServer(new Configuration(secondServerSource()), false);
+        secondServer.start();
+    }
+
+    protected void tearDown() throws Exception {
+        if (secondServer != null)
+            secondServer.dispose();
+        super.tearDown();
+    }
+
+    protected ConfigurationSource farmSource() {
+        return new StubConfigurationSource() {
+            public String remoteMachineURLs() {
+                return "http://localhost:" + port + ", http://localhost:" + otherPort;
+            }
+
+            public String port() {
+                return String.valueOf(port);
+            }
+
+        };
+    }
+
+    protected StubConfigurationSource serverSource() {
+        return new StubConfigurationSource() {
+
+            public String browserFileNames() {
+                return Browser.DEFAULT_SYSTEM_BROWSER;
+            }
+
+            public String url() {
+                return "http://localhost:" + port + "/jsunit/testRunner.html?"
+                        + "testPage=http://localhost:" + port + "/jsunit/tests/jsUnitUtilityTests.html&autoRun=true&submitresults=true";
+            }
+
+            public String port() {
+                return String.valueOf(port);
+            }
+        };
+    }
+
+    protected StubConfigurationSource secondServerSource() {
+        return new StubConfigurationSource() {
+
+            public String browserFileNames() {
+                return Browser.DEFAULT_SYSTEM_BROWSER;
+            }
+
+            public String url() {
+                return "http://localhost:" + port + "/jsunit/testRunner.html?"
+                        + "testPage=http://localhost:" + port + "/jsunit/tests/jsUnitUtilityTests.html&autoRun=true&submitresults=true";
+            }
+
+            public String port() {
+                return String.valueOf(otherPort);
+            }
+        };
+    }
+
+    public void testSuccessfulRun() {
+        DistributedTest test = new DistributedTest(serverSource(), farmSource());
+        TestResult testResult = test.run();
+        assertTrue(testResult.wasSuccessful());
+        DistributedTestRunResult distributedTestRunResult = test.getDistributedTestRunManager().getDistributedTestRunResult();
+        assertEquals(ResultType.SUCCESS, distributedTestRunResult.getResultType());
+        assertEquals(2, distributedTestRunResult.getTestRunResults().size());
+
+        assertNull(test.getTemporaryStandardServer());
+    }
+
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/UnitTestSuite.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/UnitTestSuite.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/UnitTestSuite.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,14 @@
+package net.jsunit;
+
+import junit.framework.TestSuite;
+
+public class UnitTestSuite {
+
+    public static TestSuite suite() {
+        TestSuite result = new TestSuite();
+        result.addTest(PureUnitTestSuite.suite());
+        result.addTest(ImpureUnitTestSuite.suite());
+        return result;
+    }
+
+}
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/UrlOverrideStandaloneTestTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/UrlOverrideStandaloneTestTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/UrlOverrideStandaloneTestTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,35 @@
+package net.jsunit;
+
+import junit.framework.TestResult;
+import net.jsunit.configuration.ConfigurationSource;
+import net.jsunit.model.Browser;
+
+public class UrlOverrideStandaloneTestTest extends EndToEndTestCase {
+
+    protected ConfigurationSource configurationSource() {
+        return new StubConfigurationSource() {
+            public String browserFileNames() {
+                return Browser.DEFAULT_SYSTEM_BROWSER;
+            }
+
+            public String url() {
+                return "http://www.example.com";
+            }
+
+            public String port() {
+                return String.valueOf(port);
+            }
+
+        };
+    }
+
+    public void testOverridenURL() throws Exception {
+        StandaloneTest test = new StandaloneTest(configurationSource());
+        test.setOverrideURL(
+                "http://localhost:" + port + "/jsunit/testRunner.html?testPage=http://localhost:" + port + "/jsunit/tests/jsUnitUtilityTests.html&autoRun=true&submitresults=true&resultId=foobar");
+        TestResult testResult = test.run();
+        assertTrue(testResult.wasSuccessful());
+        assertTrue(test.getServer().lastResult().wasSuccessful());
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/BlockingTestRunner.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/BlockingTestRunner.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/BlockingTestRunner.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,69 @@
+package net.jsunit.action;
+
+import net.jsunit.BrowserLaunchSpecification;
+import net.jsunit.BrowserTestRunner;
+import net.jsunit.model.Browser;
+import net.jsunit.model.BrowserResult;
+import org.jdom.Element;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class BlockingTestRunner implements BrowserTestRunner {
+    public boolean blocked;
+
+    public Element asXml() {
+        return null;
+    }
+
+    public void startTestRun() {
+        blocked = true;
+        while (blocked) {
+            try {
+                Thread.sleep(10);
+            } catch (InterruptedException e) {
+            }
+        }
+    }
+
+    public void finishTestRun() {
+    }
+
+    public long launchBrowserTestRun(BrowserLaunchSpecification launchSpec) {
+        return 0;
+    }
+
+    public void accept(BrowserResult result) {
+    }
+
+    public boolean hasReceivedResultSince(long launchTime) {
+        return false;
+    }
+
+    public BrowserResult lastResult() {
+        return null;
+    }
+
+    public void dispose() {
+    }
+
+    public BrowserResult findResultWithId(String id, int browserId) {
+        return null;
+    }
+
+    public void logStatus(String message) {
+    }
+
+    public List<Browser> getBrowsers() {
+        return Arrays.asList(new Browser[]{new Browser("browser.exe", 0)});
+    }
+
+    public int timeoutSeconds() {
+        return 0;
+    }
+
+    public boolean isAlive() {
+        return false;
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/DistributedTestRunnerActionTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/DistributedTestRunnerActionTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/DistributedTestRunnerActionTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,44 @@
+package net.jsunit.action;
+
+import junit.framework.TestCase;
+import net.jsunit.DummyConfigurationSource;
+import net.jsunit.JsUnitFarmServer;
+import net.jsunit.RemoteServerHitter;
+import net.jsunit.configuration.Configuration;
+import net.jsunit.model.TestRunResult;
+import org.jdom.Document;
+
+import java.net.URL;
+
+public class DistributedTestRunnerActionTest extends TestCase {
+
+    private DistributedTestRunnerAction action;
+
+    public void setUp() throws Exception {
+        super.setUp();
+        action = new DistributedTestRunnerAction();
+        action.setFarmServer(new JsUnitFarmServer(new Configuration(new DummyConfigurationSource())));
+        action.setRemoteRunnerHitter(new SuccessfulRemoteServerHitter());
+    }
+
+    public void testSimple() throws Exception {
+        assertEquals(DistributedTestRunnerAction.SUCCESS, action.execute());
+        assertTrue(action.getTestRunManager().getDistributedTestRunResult().wasSuccessful());
+        assertNull(action.getTestRunManager().getOverrideURL());
+    }
+
+    public void testOverrideURL() throws Exception {
+        String overrideURL = "http://overrideurl.com:1234?foo=bar&bar=fo";
+        action.setUrl(overrideURL);
+        assertEquals(DistributedTestRunnerAction.SUCCESS, action.execute());
+        assertEquals(overrideURL, action.getTestRunManager().getOverrideURL());
+    }
+
+    static class SuccessfulRemoteServerHitter implements RemoteServerHitter {
+
+        public Document hitURL(URL url) {
+            return new Document(new TestRunResult().asXml());
+        }
+
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/ErrorXmlRenderableTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/ErrorXmlRenderableTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/ErrorXmlRenderableTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,12 @@
+package net.jsunit.action;
+
+import junit.framework.TestCase;
+import net.jsunit.utility.XmlUtility;
+
+public class ErrorXmlRenderableTest extends TestCase {
+
+    public void testSimple() throws Exception {
+        ErrorXmlRenderable renderable = new ErrorXmlRenderable("a message");
+        assertEquals("<error>a message</error>", XmlUtility.asString(renderable.asXml()));
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/FarmServerConfigurationActionTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/FarmServerConfigurationActionTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/FarmServerConfigurationActionTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,108 @@
+package net.jsunit.action;
+
+import junit.framework.TestCase;
+import net.jsunit.BlowingUpRemoteServerHitter;
+import net.jsunit.DummyConfigurationSource;
+import net.jsunit.JsUnitFarmServer;
+import net.jsunit.MockRemoteServerHitter;
+import net.jsunit.configuration.Configuration;
+import net.jsunit.configuration.ServerType;
+import net.jsunit.utility.XmlUtility;
+import org.jdom.CDATA;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.filter.Filter;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class FarmServerConfigurationActionTest extends TestCase {
+
+    private FarmServerConfigurationAction action;
+
+    public void setUp() throws Exception {
+        super.setUp();
+        action = new FarmServerConfigurationAction();
+        Configuration configuration = new Configuration(new DummyConfigurationSource());
+        JsUnitFarmServer server = new JsUnitFarmServer(configuration);
+        action.setFarmServer(server);
+    }
+
+    public void testSimple() throws Exception {
+        MockRemoteServerHitter mockHitter = new MockRemoteServerHitter();
+        Configuration configuration1 = configuration1();
+        Configuration configuration2 = configuration2();
+        mockHitter.urlToDocument.put(DummyConfigurationSource.REMOTE_URL_1 + "/config", new Document(configuration1.asXml(ServerType.FARM)));
+        mockHitter.urlToDocument.put(DummyConfigurationSource.REMOTE_URL_2 + "/config", new Document(configuration2.asXml(ServerType.FARM)));
+        action.setRemoteRunnerHitter(mockHitter);
+        action.execute();
+        assertEquals(2, mockHitter.urlsPassed.size());
+        String xml = XmlUtility.asString(action.getXmlRenderable().asXml());
+        assertEquals(
+                "<remoteConfigurations>" +
+                        "<remoteConfiguration remoteMachineURL=\"" + DummyConfigurationSource.REMOTE_URL_1 + "\">" +
+                        XmlUtility.asString(configuration1.asXml(ServerType.FARM)) +
+                        "</remoteConfiguration>" +
+                        "<remoteConfiguration remoteMachineURL=\"" + DummyConfigurationSource.REMOTE_URL_2 + "\">" +
+                        XmlUtility.asString(configuration2.asXml(ServerType.FARM)) +
+                        "</remoteConfiguration>" +
+                        "</remoteConfigurations>",
+                xml
+        );
+    }
+
+    public void testCrashingRemoteURLs() throws Exception {
+        action.setRemoteRunnerHitter(new BlowingUpRemoteServerHitter());
+        action.execute();
+        Element rootElement = action.getXmlRenderable().asXml();
+        List<CDATA> stackTraceElements = getCDATAExceptionStackTracesUnder(rootElement);
+        assertEquals(2, stackTraceElements.size());
+        for (CDATA stackTraceElement : stackTraceElements)
+            stackTraceElement.detach();
+
+        String xml = XmlUtility.asString(rootElement);
+        assertEquals(
+                "<remoteConfigurations>" +
+                        "<remoteConfiguration remoteMachineURL=\"" + DummyConfigurationSource.REMOTE_URL_1 + "\">" +
+                        "<configuration failedToConnect=\"true\" />" +
+                        "</remoteConfiguration>" +
+                        "<remoteConfiguration remoteMachineURL=\"" + DummyConfigurationSource.REMOTE_URL_2 + "\">" +
+                        "<configuration failedToConnect=\"true\" />" +
+                        "</remoteConfiguration>" +
+                        "</remoteConfigurations>",
+                xml
+        );
+    }
+
+    private List<CDATA> getCDATAExceptionStackTracesUnder(Element rootElement) {
+        Iterator it = rootElement.getDescendants(new Filter() {
+            public boolean matches(Object arg0) {
+                return arg0 instanceof CDATA;
+            }
+        });
+        List<CDATA> stackTraceElements = new ArrayList<CDATA>();
+        while (it.hasNext()) {
+            CDATA next = (CDATA) it.next();
+            stackTraceElements.add(next);
+        }
+        return stackTraceElements;
+    }
+
+    private Configuration configuration2() {
+        return new Configuration(new DummyConfigurationSource() {
+            public String url() {
+                return "http://www.2.example.com";
+            }
+        });
+    }
+
+    private Configuration configuration1() {
+        return new Configuration(new DummyConfigurationSource() {
+            public String url() {
+                return "http://www.1.example.com";
+            }
+        });
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/LatestVersionActionTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/LatestVersionActionTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/LatestVersionActionTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,26 @@
+package net.jsunit.action;
+
+import junit.framework.TestCase;
+import net.jsunit.version.MockVersionGrabber;
+import net.jsunit.version.BlowingUpVersionGrabber;
+
+public class LatestVersionActionTest extends TestCase {
+    private LatestVersionAction action;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        action = new LatestVersionAction();
+    }
+
+    public void testGetLatestVersion() throws Exception {
+        action.setVersionGrabber(new MockVersionGrabber(43.21));
+        assertEquals(LatestVersionAction.SUCCESS, action.execute());
+        assertEquals(43.21, action.getLatestVersion());
+    }
+
+    public void testBlowUp() throws Exception {
+        action.setVersionGrabber(new BlowingUpVersionGrabber());
+        assertEquals(LatestVersionAction.ERROR, action.execute());
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/ResultAcceptorActionTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/ResultAcceptorActionTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/ResultAcceptorActionTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,18 @@
+package net.jsunit.action;
+
+import junit.framework.TestCase;
+import net.jsunit.DummyBrowserResult;
+import net.jsunit.MockBrowserTestRunner;
+
+public class ResultAcceptorActionTest extends TestCase {
+
+    public void testSimple() throws Exception {
+        ResultAcceptorAction action = new ResultAcceptorAction();
+        DummyBrowserResult dummyResult = new DummyBrowserResult(false, 1, 2);
+        action.setBrowserResult(dummyResult);
+        MockBrowserTestRunner mockRunner = new MockBrowserTestRunner();
+        action.setBrowserTestRunner(mockRunner);
+        assertEquals(ResultAcceptorAction.SUCCESS, action.execute());
+        assertSame(dummyResult, mockRunner.acceptedResult);
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/ResultDisplayerActionTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/ResultDisplayerActionTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/ResultDisplayerActionTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,62 @@
+package net.jsunit.action;
+
+import junit.framework.TestCase;
+import net.jsunit.InvalidBrowserIdException;
+import net.jsunit.MockBrowserTestRunner;
+import net.jsunit.model.BrowserResult;
+import net.jsunit.utility.XmlUtility;
+
+public class ResultDisplayerActionTest extends TestCase {
+
+    private ResultDisplayerAction action;
+    private MockBrowserTestRunner mockRunner;
+
+    public void setUp() throws Exception {
+        super.setUp();
+        action = new ResultDisplayerAction();
+        mockRunner = new MockBrowserTestRunner();
+        action.setBrowserTestRunner(mockRunner);
+        action.setId("12345");
+        action.setBrowserId(8);
+    }
+
+    public void testResultFound() throws Exception {
+        mockRunner.resultToReturn = new BrowserResult();
+        assertEquals(ResultDisplayerAction.SUCCESS, action.execute());
+        assertEquals("12345", mockRunner.idPassed);
+        assertEquals(8, mockRunner.browserIdPassed.intValue());
+        assertEquals(mockRunner.resultToReturn, action.getXmlRenderable());
+    }
+
+    public void testResultNotFound() throws Exception {
+        assertEquals(ResultDisplayerAction.SUCCESS, action.execute());
+        assertEquals("12345", mockRunner.idPassed);
+        assertEquals(8, mockRunner.browserIdPassed.intValue());
+        assertEquals("<error>No Test Result has been submitted with ID '12345' for browser ID '8'</error>", XmlUtility.asString(action.getXmlRenderable().asXml()));
+    }
+
+    public void testIdNotGiven() throws Exception {
+        action.setId(null);
+        action.setBrowserId(null);
+        assertEquals(ResultDisplayerAction.ERROR, action.execute());
+        assertNull(mockRunner.idPassed);
+        assertNull(mockRunner.browserIdPassed);
+        assertEquals("<error>A Test Result ID and a browser ID must both be given</error>", XmlUtility.asString(action.getXmlRenderable().asXml()));
+    }
+
+    public void testInvalidBrowserId() throws Exception {
+        action.setId("54321");
+        action.setBrowserId(12345);
+        mockRunner = new MockBrowserTestRunner() {
+            public BrowserResult findResultWithId(String id, int browserId) throws InvalidBrowserIdException {
+                super.findResultWithId(id, browserId);
+                throw new InvalidBrowserIdException(browserId);
+            }
+        };
+        action.setBrowserTestRunner(mockRunner);
+        assertEquals(ResultDisplayerAction.ERROR, action.execute());
+        assertEquals("54321", this.mockRunner.idPassed);
+        assertEquals(12345, this.mockRunner.browserIdPassed.intValue());
+        assertEquals("<error>Invalid Browser ID '12345'</error>", XmlUtility.asString(action.getXmlRenderable().asXml()));
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/TestRunnerActionSimultaneousRunBlockingTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/TestRunnerActionSimultaneousRunBlockingTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/TestRunnerActionSimultaneousRunBlockingTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,60 @@
+package net.jsunit.action;
+
+import junit.framework.TestCase;
+
+public class TestRunnerActionSimultaneousRunBlockingTest extends TestCase {
+    private BlockingTestRunner runner;
+    private TestRunnerAction action1;
+    private TestRunnerAction action2;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        runner = new BlockingTestRunner();
+        action1 = new TestRunnerAction();
+        action1.setBrowserTestRunner(runner);
+        action2 = new TestRunnerAction();
+        action2.setBrowserTestRunner(runner);
+    }
+
+    public void testSimultaneousRequestsAreQueued() throws Exception {
+        Executor executor1 = new Executor(action1);
+        executor1.start();
+        waitTillRunnerIsBlocked(runner);
+        Executor executor2 = new Executor(action2);
+        executor2.start();
+        runner.blocked = false;
+        waitTillExecutorIsDead(executor1);
+        waitTillRunnerIsBlocked(runner);
+        runner.blocked = false;
+        waitTillExecutorIsDead(executor2);
+    }
+
+    private void waitTillExecutorIsDead(Executor executor) throws InterruptedException {
+        while (executor.isAlive())
+            Thread.sleep(10);
+    }
+
+    private void waitTillRunnerIsBlocked(BlockingTestRunner runner) throws InterruptedException {
+        while (!runner.blocked) {
+            Thread.sleep(10);
+        }
+    }
+
+    class Executor extends Thread {
+
+        private TestRunnerAction action;
+
+        public Executor(TestRunnerAction action) {
+            this.action = action;
+
+        }
+
+        public void run() {
+            try {
+                action.execute();
+            } catch (Exception e) {
+                fail();
+            }
+        }
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/TestRunnerActionTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/TestRunnerActionTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/action/TestRunnerActionTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,98 @@
+package net.jsunit.action;
+
+import junit.framework.TestCase;
+import net.jsunit.BrowserLaunchSpecification;
+import net.jsunit.MockBrowserTestRunner;
+import net.jsunit.model.ResultType;
+import net.jsunit.utility.XmlUtility;
+
+public class TestRunnerActionTest extends TestCase {
+
+    private TestRunnerAction action;
+    private MockBrowserTestRunner mockRunner;
+
+    public void setUp() throws Exception {
+        super.setUp();
+        action = new TestRunnerAction();
+        mockRunner = new MockBrowserTestRunner();
+        mockRunner.hasReceivedResult = true;
+        action.setBrowserTestRunner(mockRunner);
+    }
+
+    public void testSuccess() throws Exception {
+        mockRunner.shouldSucceed = true;
+        assertEquals(TestRunnerAction.SUCCESS, action.execute());
+        String xmlString = XmlUtility.asString(action.getXmlRenderable().asXml());
+        assertTrue(xmlString.startsWith("<testRunResult type=\"" + ResultType.SUCCESS.name()));
+    }
+
+    public void testFailure() throws Exception {
+        mockRunner.shouldSucceed = false;
+        assertEquals(TestRunnerAction.SUCCESS, action.execute());
+        String xmlString = XmlUtility.asString(action.getXmlRenderable().asXml());
+        assertTrue(xmlString.startsWith("<testRunResult type=\"" + ResultType.FAILURE.name()));
+    }
+
+    public void testOverrideUrl() throws Exception {
+        String overrideUrl = "http://www.example.com:8954/jsunit/testRunner.html?testPage=http://www.example.com:8954/tests/myTests.html?autoRun=true&submitResults=http://www.example.com:8954/tests";
+        action.setUrl(overrideUrl);
+        assertEquals(TestRunnerAction.SUCCESS, action.execute());
+        assertEquals(2, mockRunner.launchSpecs.size());
+        BrowserLaunchSpecification spec1 = mockRunner.launchSpecs.get(0);
+        BrowserLaunchSpecification spec2 = mockRunner.launchSpecs.get(1);
+        assertTrue(spec1.hasOverrideUrl());
+        assertEquals(overrideUrl, spec1.getOverrideUrl());
+        assertTrue(spec2.hasOverrideUrl());
+        assertEquals(overrideUrl, spec2.getOverrideUrl());
+    }
+
+    public void testRequestIpAddressAndHostLogged() throws Exception {
+        action.execute();
+        assertEquals("Received request to run tests", mockRunner.logMessages.get(0));
+
+        mockRunner.logMessages.clear();
+        action.setRequestIPAddress("123.456.78.9");
+        action.execute();
+        assertEquals("Received request to run tests from 123.456.78.9", mockRunner.logMessages.get(0));
+
+        mockRunner.logMessages.clear();
+        action.setRequestHost("www.example.com");
+        action.execute();
+        assertEquals("Received request to run tests from www.example.com (123.456.78.9)", mockRunner.logMessages.get(0));
+
+        mockRunner.logMessages.clear();
+        action.setRequestIPAddress("");
+        action.execute();
+        assertEquals("Received request to run tests from www.example.com", mockRunner.logMessages.get(0));
+
+        mockRunner.logMessages.clear();
+        action.setRequestIPAddress("12.34.56.78");
+        action.setRequestHost("12.34.56.78");
+        action.execute();
+        assertEquals("Received request to run tests from 12.34.56.78", mockRunner.logMessages.get(0));
+    }
+
+    public void testLimitToParticularBrowser() throws Exception {
+        action.setBrowserId("1");
+        assertEquals(TestRunnerAction.SUCCESS, action.execute());
+        assertEquals(1, mockRunner.launchSpecs.size());
+        assertEquals("mybrowser2.exe", mockRunner.launchSpecs.get(0).getBrowser().getFileName());
+    }
+
+    public void testLimitToBrowserWithBadId() throws Exception {
+        action.setBrowserId("34");
+        action.execute();
+        assertEquals(TestRunnerAction.ERROR, action.execute());
+        assertTrue(mockRunner.launchSpecs.isEmpty());
+        assertEquals("<error>Invalid browser ID: 34</error>", XmlUtility.asString(action.getXmlRenderable().asXml()));
+    }
+
+    public void testLimitToBrowserWithNonIntegerId() throws Exception {
+        action.setBrowserId("foo");
+        action.execute();
+        assertEquals(TestRunnerAction.ERROR, action.execute());
+        assertTrue(mockRunner.launchSpecs.isEmpty());
+        assertEquals("<error>Invalid browser ID: foo</error>", XmlUtility.asString(action.getXmlRenderable().asXml()));
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/interceptor/BrowserResultInterceptorTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/interceptor/BrowserResultInterceptorTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/interceptor/BrowserResultInterceptorTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,56 @@
+package net.jsunit.interceptor;
+
+import com.opensymphony.webwork.ServletActionContext;
+import com.opensymphony.xwork.Action;
+import junit.framework.TestCase;
+import net.jsunit.DummyHttpRequest;
+import net.jsunit.action.BrowserResultAware;
+import net.jsunit.model.BrowserResult;
+import net.jsunit.model.BrowserResultWriter;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.Map;
+
+public class BrowserResultInterceptorTest extends TestCase {
+
+    public void setUp() throws Exception {
+        super.setUp();
+        Map<String, String[]> requestMap = new HashMap<String, String[]>();
+        requestMap.put(BrowserResultWriter.ID, new String[]{"ID_foo"});
+        requestMap.put(BrowserResultWriter.USER_AGENT, new String[]{"user agent"});
+        requestMap.put(BrowserResultWriter.TIME, new String[]{"4.3"});
+        requestMap.put(BrowserResultWriter.JSUNIT_VERSION, new String[]{"2.5"});
+        requestMap.put(BrowserResultWriter.TEST_CASES, new String[]{"file:///dummy/path/dummyPage.html:testFoo|1.3|S||"});
+        HttpServletRequest request = new DummyHttpRequest(requestMap);
+        ServletActionContext.setRequest(request);
+    }
+
+    public void tearDown() throws Exception {
+        ServletActionContext.setRequest(null);
+        super.tearDown();
+    }
+
+    public void testSimple() throws Exception {
+        BrowserResultInterceptor interceptor = new BrowserResultInterceptor();
+        MockAction action = new MockAction();
+        MockActionInvocation invocation = new MockActionInvocation(action);
+        interceptor.intercept(invocation);
+        assertEquals("ID_foo", action.result.getId());
+    }
+
+    static class MockAction implements Action, BrowserResultAware {
+
+        private BrowserResult result;
+
+        public String execute() throws Exception {
+            return null;
+        }
+
+        public void setBrowserResult(BrowserResult result) {
+            this.result = result;
+        }
+
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/interceptor/BrowserTestRunnerInterceptorTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/interceptor/BrowserTestRunnerInterceptorTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/interceptor/BrowserTestRunnerInterceptorTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,47 @@
+package net.jsunit.interceptor;
+
+import junit.framework.TestCase;
+import net.jsunit.BrowserTestRunner;
+import net.jsunit.MockBrowserTestRunner;
+import net.jsunit.XmlRenderable;
+import net.jsunit.action.JsUnitBrowserTestRunnerAction;
+
+public class BrowserTestRunnerInterceptorTest extends TestCase {
+
+    public void testSimple() throws Exception {
+        MockJsUnitAction action = new MockJsUnitAction();
+        final BrowserTestRunner mockRunner = new MockBrowserTestRunner();
+        BrowserTestRunnerInterceptor.setBrowserTestRunnerSource(new BrowserTestRunnerSource() {
+            public BrowserTestRunner getRunner() {
+                return mockRunner;
+            }
+
+        });
+        assertNull(action.getBrowserTestRunner());
+        BrowserTestRunnerInterceptor interceptor = new BrowserTestRunnerInterceptor();
+
+        MockActionInvocation mockInvocation = new MockActionInvocation(action);
+        interceptor.intercept(mockInvocation);
+
+        assertSame(mockRunner, action.getBrowserTestRunner());
+        assertTrue(mockInvocation.wasInvokeCalled);
+    }
+
+    public void tearDown() throws Exception {
+        BrowserTestRunnerInterceptor.setBrowserTestRunnerSource(new DefaultBrowserTestRunnerSource());
+        super.tearDown();
+    }
+
+    static class MockJsUnitAction extends JsUnitBrowserTestRunnerAction {
+
+        public String execute() throws Exception {
+            return null;
+        }
+
+        public XmlRenderable getXmlRenderable() {
+            return null;
+        }
+
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/interceptor/FarmServerInterceptorTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/interceptor/FarmServerInterceptorTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/interceptor/FarmServerInterceptorTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,37 @@
+package net.jsunit.interceptor;
+
+import com.opensymphony.xwork.Action;
+import junit.framework.TestCase;
+import net.jsunit.DummyConfigurationSource;
+import net.jsunit.JsUnitFarmServer;
+import net.jsunit.action.JsUnitServerAware;
+import net.jsunit.configuration.Configuration;
+
+public class FarmServerInterceptorTest extends TestCase {
+
+    public void testSimple() throws Exception {
+        MockAction action = new MockAction();
+        JsUnitFarmServer server = new JsUnitFarmServer(new Configuration(new DummyConfigurationSource()));
+        assertNull(action.farmServer);
+        FarmServerInterceptor interceptor = new FarmServerInterceptor();
+
+        MockActionInvocation mockInvocation = new MockActionInvocation(action);
+        interceptor.intercept(mockInvocation);
+
+        assertSame(server, action.farmServer);
+        assertTrue(mockInvocation.wasInvokeCalled);
+    }
+
+    static class MockAction implements Action, JsUnitServerAware {
+        public JsUnitFarmServer farmServer;
+
+        public String execute() throws Exception {
+            return null;
+        }
+
+        public void setFarmServer(JsUnitFarmServer farmServer) {
+            this.farmServer = farmServer;
+        }
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/interceptor/MockActionInvocation.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/interceptor/MockActionInvocation.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/interceptor/MockActionInvocation.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,59 @@
+package net.jsunit.interceptor;
+
+import com.opensymphony.xwork.*;
+import com.opensymphony.xwork.interceptor.PreResultListener;
+import com.opensymphony.xwork.util.OgnlValueStack;
+
+public class MockActionInvocation implements ActionInvocation {
+
+    private Action action;
+    public boolean wasInvokeCalled;
+
+    public MockActionInvocation(Action action) {
+        this.action = action;
+    }
+
+    public Action getAction() {
+        return action;
+    }
+
+    public boolean isExecuted() {
+        return false;
+    }
+
+    public ActionContext getInvocationContext() {
+        return null;
+    }
+
+    public ActionProxy getProxy() {
+        return null;
+    }
+
+    public Result getResult() throws Exception {
+        return null;
+    }
+
+    public String getResultCode() {
+        return null;
+    }
+
+    public void setResultCode(String string) {
+    }
+
+    public OgnlValueStack getStack() {
+        return null;
+    }
+
+    public void addPreResultListener(PreResultListener arg0) {
+    }
+
+    public String invoke() throws Exception {
+        wasInvokeCalled = true;
+        return null;
+    }
+
+    public String invokeActionOnly() throws Exception {
+        return null;
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/interceptor/RemoteRunnerHitterInterceptorTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/interceptor/RemoteRunnerHitterInterceptorTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/interceptor/RemoteRunnerHitterInterceptorTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,34 @@
+package net.jsunit.interceptor;
+
+import com.opensymphony.xwork.Action;
+import junit.framework.TestCase;
+import net.jsunit.RemoteMachineServerHitter;
+import net.jsunit.RemoteServerHitter;
+import net.jsunit.action.RemoteRunnerHitterAware;
+
+public class RemoteRunnerHitterInterceptorTest extends TestCase {
+
+    public void testSimple() throws Exception {
+        RemoteRunnerHitterInterceptor interceptor = new RemoteRunnerHitterInterceptor();
+        MockAction action = new MockAction();
+        MockActionInvocation invocation = new MockActionInvocation(action);
+        interceptor.intercept(invocation);
+        assertNotNull(action.hitter);
+        assertTrue(action.hitter instanceof RemoteMachineServerHitter);
+    }
+
+    static class MockAction implements RemoteRunnerHitterAware, Action {
+
+        private RemoteServerHitter hitter;
+
+        public String execute() throws Exception {
+            return null;
+        }
+
+        public void setRemoteRunnerHitter(RemoteServerHitter hitter) {
+            this.hitter = hitter;
+        }
+
+    }
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/interceptor/RequestSourceInterceptorTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/interceptor/RequestSourceInterceptorTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/interceptor/RequestSourceInterceptorTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,44 @@
+package net.jsunit.interceptor;
+
+import com.opensymphony.webwork.ServletActionContext;
+import com.opensymphony.xwork.Action;
+import junit.framework.TestCase;
+import net.jsunit.DummyHttpRequest;
+import net.jsunit.action.RequestSourceAware;
+
+import java.util.HashMap;
+
+public class RequestSourceInterceptorTest extends TestCase {
+
+    public void testSimple() throws Exception {
+        DummyHttpRequest request = new DummyHttpRequest(new HashMap());
+        request.setIpAddress("123.456.78.9");
+        request.setHost("www.example.com");
+        ServletActionContext.setRequest(request);
+        RequestSourceInterceptor interceptor = new RequestSourceInterceptor();
+        RequestSourceAction action = new RequestSourceAction();
+        MockActionInvocation invocation = new MockActionInvocation(action);
+        interceptor.intercept(invocation);
+        assertTrue(invocation.wasInvokeCalled);
+
+        assertEquals("123.456.78.9", action.ipAddress);
+        assertEquals("www.example.com", action.host);
+    }
+
+    static class RequestSourceAction implements RequestSourceAware, Action {
+        private String ipAddress;
+        private String host;
+
+        public void setRequestIPAddress(String ipAddress) {
+            this.ipAddress = ipAddress;
+        }
+
+        public void setRequestHost(String host) {
+            this.host = host;
+        }
+
+        public String execute() throws Exception {
+            return null;
+        }
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/interceptor/VersionGrabberInterceptorTest.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/interceptor/VersionGrabberInterceptorTest.java	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/java/tests_server/net/jsunit/interceptor/VersionGrabberInterceptorTest.java	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,32 @@
+package net.jsunit.interceptor;
+
+import junit.framework.TestCase;
+import com.opensymphony.xwork.Action;
+import net.jsunit.action.VersionGrabberAware;
+import net.jsunit.version.VersionGrabber;
+import net.jsunit.version.JsUnitWebsiteVersionGrabber;
+
+public class VersionGrabberInterceptorTest extends TestCase {
+
+    public void testSimple() throws Exception {
+        VersionGrabberInterceptor interceptor = new VersionGrabberInterceptor();
+        VersionGrabberAction action = new VersionGrabberAction();
+        MockActionInvocation invocation = new MockActionInvocation(action);
+        interceptor.intercept(invocation);
+        assertNotNull(action.versionGrabber);
+        assertTrue(action.versionGrabber instanceof JsUnitWebsiteVersionGrabber);
+        assertTrue(invocation.wasInvokeCalled);
+    }
+
+    static class VersionGrabberAction implements Action, VersionGrabberAware {
+        private VersionGrabber versionGrabber;
+
+        public String execute() throws Exception {
+            return null;
+        }
+
+        public void setVersionGrabber(VersionGrabber versionGrabber) {
+            this.versionGrabber = versionGrabber;
+        }
+    }
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/jsunit.properties.sample
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/jsunit.properties.sample	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/jsunit.properties.sample	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,35 @@
+
+            
+            #Using jsunit.properties is one way to specify the various properties used by the JsUnitServer.
+            #It is deprecated in favor of using ant build files. See build.xml.
+            #To use this file, rename it to "jsunit.properties". You need to provide values for the mandatory properties.
+            #See the documentation at http://www.jsunit.net for more information.
+            
+        
+            #closeBrowsersAfterTestRuns determines whether to attempt to close browsers after test runs. This is not a mandatory property. The default is true. For example: 'true'
+            closeBrowsersAfterTestRuns=
+            
+            #description is a human-readable description of a standard or farm server. This is not a mandatory property. The default is blank. For example: 'This is our Mac - it's only running Safari right now'
+            description=
+            
+            #ignoreUnresponsiveRemoteMachines is a property used only by the JsUnit Farm Server and the distributed_test target. Its value is whether to ignore a remove machine that does not respond.  If true, test runs will be green even if one or more remove machines fail to respond; if false, an unresponsive remove machine results in a failure.  This is not a mandatory property.  Its default is false. For example: 'true'
+            ignoreUnresponsiveRemoteMachines=
+            
+            #logsDirectory is the directory in which the JsUnitStandardServer stores the XML logs produced from tests run. It can be specified relative to the working directory. This is not a mandatory property. If not specified, the directory called 'logs' inside resourceBase is assumed. For example: 'c:\jsunit\java\logs'
+            logsDirectory=
+            
+            #port is the port on which the JsUnitStandardServer runs. This is not a mandatory property. If not specified, 8080 is assumed. For exapmle: '8080'
+            port=
+            
+            #remoteMachineURLs is a property used only by the JsUnit Farm Server and the distributed_test target. Its value is the list of URLs of remove machines to which a request to run tests will be sent. For example: 'http://machine1.company.com:8080,http://localhost:8080,http://192.168.1.200:9090'
+            remoteMachineURLs=
+            
+            #resourceBase is the directory that the JsUnitStandardServer considers to be its document root. It can be specified relative to the working directory. This is not a mandatory property. If not specified, the working directory is assumed. For example: 'c:\jsunit'
+            resourceBase=
+            
+            #timeoutSeconds is the number of seconds to wait before timing out a browser during a test run. This is not a mandatory property. If not specified, 60 is assumed. For example: '60'
+            timeoutSeconds=
+            
+            #url is the URL (HTTP or file protocol) to open in the browser. For a JsUnit Server, this is a mandatory property for a test run if the server is not passed the 'url' parameter. For example: 'file:///c:/jsunit/testRunner.html?testPage=c:/jsunit/tests/jsUnitTestSuite.html'
+            url=
+            
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/JDOM_license.txt
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/JDOM_license.txt	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/JDOM_license.txt	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,56 @@
+/*-- 
+
+ $Id: JDOM_license.txt 81 2003-07-24 04:44:54Z edwardhieatt $
+
+ Copyright (C) 2000-2003 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+ 
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows 
+    these conditions in the documentation and/or other materials 
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <license AT jdom DOT org>.
+ 
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <pm AT jdom DOT org>.
+ 
+ In addition, we request (but do not require) that you include in the 
+ end-user documentation provided with the redistribution and/or in the 
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos 
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many 
+ individuals on behalf of the JDOM Project and was originally 
+ created by Jason Hunter <jhunter AT jdom DOT org> and
+ Brett McLaughlin <brett AT jdom DOT org>.  For more information on
+ the JDOM Project, please see <http://www.jdom.org/>.
+ 
+ */
+

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/Jetty_license.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/Jetty_license.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/Jetty_license.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,213 @@
+<HTML>
+<HEAD>
+    <TITLE>Jetty License</TITLE>
+</HEAD>
+
+<BODY BGCOLOR="#FFFFFF">
+<FONT FACE=ARIAL,HELVETICA>
+<CENTER><FONT SIZE=+3><B>Jetty License</B></FONT></CENTER>
+<CENTER><FONT SIZE=-1><B>$Revision$</B></FONT></CENTER>
+
+<B>Preamble:</B>
+
+<p>
+
+    The intent of this document is to state the conditions under which the
+    Jetty Package may be copied, such that the Copyright Holder maintains some
+    semblance of control over the development of the package, while giving the
+    users of the package the right to use, distribute and make reasonable
+    modifications to the Package in accordance with the goals and ideals of
+    the Open Source concept as described at
+    <A HREF="http://www.opensource.org">http://www.opensource.org</A>.
+
+<P>
+    It is the intent of this license to allow commercial usage of the Jetty
+    package, so long as the source code is distributed or suitable visible
+    credit given or other arrangements made with the copyright holders.
+
+<P><B>Definitions:</B>
+
+<P>
+
+<UL>
+    <LI> "Jetty" refers to the collection of Java classes that are
+        distributed as a HTTP server with servlet capabilities and
+        associated utilities.
+
+    <p>
+
+    <LI> "Package" refers to the collection of files distributed by the
+        Copyright Holder, and derivatives of that collection of files
+        created through textual modification.
+
+    <P>
+
+    <LI> "Standard Version" refers to such a Package if it has not been
+        modified, or has been modified in accordance with the wishes
+        of the Copyright Holder.
+
+    <P>
+
+    <LI> "Copyright Holder" is whoever is named in the copyright or
+        copyrights for the package. <BR>
+        Mort Bay Consulting Pty. Ltd. (Australia) is the "Copyright
+        Holder" for the Jetty package.
+
+    <P>
+
+    <LI> "You" is you, if you're thinking about copying or distributing
+        this Package.
+
+    <P>
+
+    <LI> "Reasonable copying fee" is whatever you can justify on the
+        basis of media cost, duplication charges, time of people involved,
+        and so on. (You will not be required to justify it to the
+        Copyright Holder, but only to the computing community at large
+        as a market that must bear the fee.)
+
+    <P>
+
+    <LI> "Freely Available" means that no fee is charged for the item
+        itself, though there may be fees involved in handling the item.
+        It also means that recipients of the item may redistribute it
+        under the same conditions they received it.
+
+    <P>
+</UL>
+
+0. The Jetty Package is Copyright (c) Mort Bay Consulting Pty. Ltd.
+(Australia) and others. Individual files in this package may contain
+additional copyright notices. The javax.servlet packages are copyright
+Sun Microsystems Inc. <P>
+
+    1. The Standard Version of the Jetty package is
+    available from <A HREF=http://jetty.mortbay.org>http://jetty.mortbay.org</A>.
+
+<P>
+
+    2. You may make and distribute verbatim copies of the source form
+    of the Standard Version of this Package without restriction, provided that
+    you include this license and all of the original copyright notices
+    and associated disclaimers.
+
+<P>
+
+    3. You may make and distribute verbatim copies of the compiled form of the
+    Standard Version of this Package without restriction, provided that you
+    include this license.
+
+<P>
+
+    4. You may apply bug fixes, portability fixes and other modifications
+    derived from the Public Domain or from the Copyright Holder. A Package
+    modified in such a way shall still be considered the Standard Version.
+
+<P>
+
+    5. You may otherwise modify your copy of this Package in any way, provided
+    that you insert a prominent notice in each changed file stating how and
+    when you changed that file, and provided that you do at least ONE of the
+    following:
+
+<P>
+
+<BLOCKQUOTE>
+    a) Place your modifications in the Public Domain or otherwise make them
+    Freely Available, such as by posting said modifications to Usenet or
+    an equivalent medium, or placing the modifications on a major archive
+    site such as ftp.uu.net, or by allowing the Copyright Holder to include
+    your modifications in the Standard Version of the Package.<P>
+
+    b) Use the modified Package only within your corporation or organization.
+
+    <P>
+
+        c) Rename any non-standard classes so the names do not conflict
+        with standard classes, which must also be provided, and provide
+        a separate manual page for each non-standard class that clearly
+        documents how it differs from the Standard Version.
+
+    <P>
+
+        d) Make other arrangements with the Copyright Holder.
+
+    <P>
+</BLOCKQUOTE>
+
+6. You may distribute modifications or subsets of this Package in source
+code or compiled form, provided that you do at least ONE of the following:<P>
+
+<BLOCKQUOTE>
+    a) Distribute this license and all original copyright messages, together
+    with instructions (in the about dialog, manual page or equivalent) on where
+    to get the complete Standard Version.<P>
+
+    b) Accompany the distribution with the machine-readable source of
+    the Package with your modifications. The modified package must include
+    this license and all of the original copyright notices and associated
+    disclaimers, together with instructions on where to get the complete
+    Standard Version.
+
+    <P>
+
+        c) Make other arrangements with the Copyright Holder.
+
+    <P>
+</BLOCKQUOTE>
+
+7. You may charge a reasonable copying fee for any distribution of this
+Package. You may charge any fee you choose for support of this Package.
+You may not charge a fee for this Package itself. However,
+you may distribute this Package in aggregate with other (possibly
+commercial) programs as part of a larger (possibly commercial) software
+distribution provided that you meet the other distribution requirements
+of this license.<P>
+
+    8. Input to or the output produced from the programs of this Package
+    do not automatically fall under the copyright of this Package, but
+    belong to whomever generated them, and may be sold commercially, and
+    may be aggregated with this Package.
+
+<P>
+
+    9. Any program subroutines supplied by you and linked into this Package
+    shall not be considered part of this Package.
+
+<P>
+
+    10. The name of the Copyright Holder may not be used to endorse or promote
+    products derived from this software without specific prior written
+    permission.
+
+<P>
+
+    11. This license may change with each release of a Standard Version of
+    the Package. You may choose to use the license associated with version
+    you are using or the license of the latest Standard Version.
+
+<P>
+
+    12. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
+    IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+<P>
+
+    13. If any superior law implies a warranty, the sole remedy under such shall
+    be , at the Copyright Holders option either a) return of any price paid or
+    b) use or reasonable endeavours to repair or replace the software.
+
+<P>
+
+    14. This license shall be read under the laws of Australia.
+
+<P>
+
+<center>The End</center>
+
+<center><FONT size=-1>This license was derived from the <I>Artistic</I> license published
+    on <a href=http://www.opensource.org>http://www.opensource.com</a></font></center>
+</FONT>
+
+

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/MPL-1.1.txt
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/MPL-1.1.txt	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/MPL-1.1.txt	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,470 @@
+                          MOZILLA PUBLIC LICENSE
+                                Version 1.1
+
+                              ---------------
+
+1. Definitions.
+
+     1.0.1. "Commercial Use" means distribution or otherwise making the
+     Covered Code available to a third party.
+
+     1.1. "Contributor" means each entity that creates or contributes to
+     the creation of Modifications.
+
+     1.2. "Contributor Version" means the combination of the Original
+     Code, prior Modifications used by a Contributor, and the Modifications
+     made by that particular Contributor.
+
+     1.3. "Covered Code" means the Original Code or Modifications or the
+     combination of the Original Code and Modifications, in each case
+     including portions thereof.
+
+     1.4. "Electronic Distribution Mechanism" means a mechanism generally
+     accepted in the software development community for the electronic
+     transfer of data.
+
+     1.5. "Executable" means Covered Code in any form other than Source
+     Code.
+
+     1.6. "Initial Developer" means the individual or entity identified
+     as the Initial Developer in the Source Code notice required by Exhibit
+     A.
+
+     1.7. "Larger Work" means a work which combines Covered Code or
+     portions thereof with code not governed by the terms of this License.
+
+     1.8. "License" means this document.
+
+     1.8.1. "Licensable" means having the right to grant, to the maximum
+     extent possible, whether at the time of the initial grant or
+     subsequently acquired, any and all of the rights conveyed herein.
+
+     1.9. "Modifications" means any addition to or deletion from the
+     substance or structure of either the Original Code or any previous
+     Modifications. When Covered Code is released as a series of files, a
+     Modification is:
+          A. Any addition to or deletion from the contents of a file
+          containing Original Code or previous Modifications.
+
+          B. Any new file that contains any part of the Original Code or
+          previous Modifications.
+
+     1.10. "Original Code" means Source Code of computer software code
+     which is described in the Source Code notice required by Exhibit A as
+     Original Code, and which, at the time of its release under this
+     License is not already Covered Code governed by this License.
+
+     1.10.1. "Patent Claims" means any patent claim(s), now owned or
+     hereafter acquired, including without limitation,  method, process,
+     and apparatus claims, in any patent Licensable by grantor.
+
+     1.11. "Source Code" means the preferred form of the Covered Code for
+     making modifications to it, including all modules it contains, plus
+     any associated interface definition files, scripts used to control
+     compilation and installation of an Executable, or source code
+     differential comparisons against either the Original Code or another
+     well known, available Covered Code of the Contributor's choice. The
+     Source Code can be in a compressed or archival form, provided the
+     appropriate decompression or de-archiving software is widely available
+     for no charge.
+
+     1.12. "You" (or "Your")  means an individual or a legal entity
+     exercising rights under, and complying with all of the terms of, this
+     License or a future version of this License issued under Section 6.1.
+     For legal entities, "You" includes any entity which controls, is
+     controlled by, or is under common control with You. For purposes of
+     this definition, "control" means (a) the power, direct or indirect,
+     to cause the direction or management of such entity, whether by
+     contract or otherwise, or (b) ownership of more than fifty percent
+     (50%) of the outstanding shares or beneficial ownership of such
+     entity.
+
+2. Source Code License.
+
+     2.1. The Initial Developer Grant.
+     The Initial Developer hereby grants You a world-wide, royalty-free,
+     non-exclusive license, subject to third party intellectual property
+     claims:
+          (a)  under intellectual property rights (other than patent or
+          trademark) Licensable by Initial Developer to use, reproduce,
+          modify, display, perform, sublicense and distribute the Original
+          Code (or portions thereof) with or without Modifications, and/or
+          as part of a Larger Work; and
+
+          (b) under Patents Claims infringed by the making, using or
+          selling of Original Code, to make, have made, use, practice,
+          sell, and offer for sale, and/or otherwise dispose of the
+          Original Code (or portions thereof).
+
+          (c) the licenses granted in this Section 2.1(a) and (b) are
+          effective on the date Initial Developer first distributes
+          Original Code under the terms of this License.
+
+          (d) Notwithstanding Section 2.1(b) above, no patent license is
+          granted: 1) for code that You delete from the Original Code; 2)
+          separate from the Original Code;  or 3) for infringements caused
+          by: i) the modification of the Original Code or ii) the
+          combination of the Original Code with other software or devices.
+
+     2.2. Contributor Grant.
+     Subject to third party intellectual property claims, each Contributor
+     hereby grants You a world-wide, royalty-free, non-exclusive license
+
+          (a)  under intellectual property rights (other than patent or
+          trademark) Licensable by Contributor, to use, reproduce, modify,
+          display, perform, sublicense and distribute the Modifications
+          created by such Contributor (or portions thereof) either on an
+          unmodified basis, with other Modifications, as Covered Code
+          and/or as part of a Larger Work; and
+
+          (b) under Patent Claims infringed by the making, using, or
+          selling of  Modifications made by that Contributor either alone
+          and/or in combination with its Contributor Version (or portions
+          of such combination), to make, use, sell, offer for sale, have
+          made, and/or otherwise dispose of: 1) Modifications made by that
+          Contributor (or portions thereof); and 2) the combination of
+          Modifications made by that Contributor with its Contributor
+          Version (or portions of such combination).
+
+          (c) the licenses granted in Sections 2.2(a) and 2.2(b) are
+          effective on the date Contributor first makes Commercial Use of
+          the Covered Code.
+
+          (d)    Notwithstanding Section 2.2(b) above, no patent license is
+          granted: 1) for any code that Contributor has deleted from the
+          Contributor Version; 2)  separate from the Contributor Version;
+          3)  for infringements caused by: i) third party modifications of
+          Contributor Version or ii)  the combination of Modifications made
+          by that Contributor with other software  (except as part of the
+          Contributor Version) or other devices; or 4) under Patent Claims
+          infringed by Covered Code in the absence of Modifications made by
+          that Contributor.
+
+3. Distribution Obligations.
+
+     3.1. Application of License.
+     The Modifications which You create or to which You contribute are
+     governed by the terms of this License, including without limitation
+     Section 2.2. The Source Code version of Covered Code may be
+     distributed only under the terms of this License or a future version
+     of this License released under Section 6.1, and You must include a
+     copy of this License with every copy of the Source Code You
+     distribute. You may not offer or impose any terms on any Source Code
+     version that alters or restricts the applicable version of this
+     License or the recipients' rights hereunder. However, You may include
+     an additional document offering the additional rights described in
+     Section 3.5.
+
+     3.2. Availability of Source Code.
+     Any Modification which You create or to which You contribute must be
+     made available in Source Code form under the terms of this License
+     either on the same media as an Executable version or via an accepted
+     Electronic Distribution Mechanism to anyone to whom you made an
+     Executable version available; and if made available via Electronic
+     Distribution Mechanism, must remain available for at least twelve (12)
+     months after the date it initially became available, or at least six
+     (6) months after a subsequent version of that particular Modification
+     has been made available to such recipients. You are responsible for
+     ensuring that the Source Code version remains available even if the
+     Electronic Distribution Mechanism is maintained by a third party.
+
+     3.3. Description of Modifications.
+     You must cause all Covered Code to which You contribute to contain a
+     file documenting the changes You made to create that Covered Code and
+     the date of any change. You must include a prominent statement that
+     the Modification is derived, directly or indirectly, from Original
+     Code provided by the Initial Developer and including the name of the
+     Initial Developer in (a) the Source Code, and (b) in any notice in an
+     Executable version or related documentation in which You describe the
+     origin or ownership of the Covered Code.
+
+     3.4. Intellectual Property Matters
+          (a) Third Party Claims.
+          If Contributor has knowledge that a license under a third party's
+          intellectual property rights is required to exercise the rights
+          granted by such Contributor under Sections 2.1 or 2.2,
+          Contributor must include a text file with the Source Code
+          distribution titled "LEGAL" which describes the claim and the
+          party making the claim in sufficient detail that a recipient will
+          know whom to contact. If Contributor obtains such knowledge after
+          the Modification is made available as described in Section 3.2,
+          Contributor shall promptly modify the LEGAL file in all copies
+          Contributor makes available thereafter and shall take other steps
+          (such as notifying appropriate mailing lists or newsgroups)
+          reasonably calculated to inform those who received the Covered
+          Code that new knowledge has been obtained.
+
+          (b) Contributor APIs.
+          If Contributor's Modifications include an application programming
+          interface and Contributor has knowledge of patent licenses which
+          are reasonably necessary to implement that API, Contributor must
+          also include this information in the LEGAL file.
+
+               (c)    Representations.
+          Contributor represents that, except as disclosed pursuant to
+          Section 3.4(a) above, Contributor believes that Contributor's
+          Modifications are Contributor's original creation(s) and/or
+          Contributor has sufficient rights to grant the rights conveyed by
+          this License.
+
+     3.5. Required Notices.
+     You must duplicate the notice in Exhibit A in each file of the Source
+     Code.  If it is not possible to put such notice in a particular Source
+     Code file due to its structure, then You must include such notice in a
+     location (such as a relevant directory) where a user would be likely
+     to look for such a notice.  If You created one or more Modification(s)
+     You may add your name as a Contributor to the notice described in
+     Exhibit A.  You must also duplicate this License in any documentation
+     for the Source Code where You describe recipients' rights or ownership
+     rights relating to Covered Code.  You may choose to offer, and to
+     charge a fee for, warranty, support, indemnity or liability
+     obligations to one or more recipients of Covered Code. However, You
+     may do so only on Your own behalf, and not on behalf of the Initial
+     Developer or any Contributor. You must make it absolutely clear than
+     any such warranty, support, indemnity or liability obligation is
+     offered by You alone, and You hereby agree to indemnify the Initial
+     Developer and every Contributor for any liability incurred by the
+     Initial Developer or such Contributor as a result of warranty,
+     support, indemnity or liability terms You offer.
+
+     3.6. Distribution of Executable Versions.
+     You may distribute Covered Code in Executable form only if the
+     requirements of Section 3.1-3.5 have been met for that Covered Code,
+     and if You include a notice stating that the Source Code version of
+     the Covered Code is available under the terms of this License,
+     including a description of how and where You have fulfilled the
+     obligations of Section 3.2. The notice must be conspicuously included
+     in any notice in an Executable version, related documentation or
+     collateral in which You describe recipients' rights relating to the
+     Covered Code. You may distribute the Executable version of Covered
+     Code or ownership rights under a license of Your choice, which may
+     contain terms different from this License, provided that You are in
+     compliance with the terms of this License and that the license for the
+     Executable version does not attempt to limit or alter the recipient's
+     rights in the Source Code version from the rights set forth in this
+     License. If You distribute the Executable version under a different
+     license You must make it absolutely clear that any terms which differ
+     from this License are offered by You alone, not by the Initial
+     Developer or any Contributor. You hereby agree to indemnify the
+     Initial Developer and every Contributor for any liability incurred by
+     the Initial Developer or such Contributor as a result of any such
+     terms You offer.
+
+     3.7. Larger Works.
+     You may create a Larger Work by combining Covered Code with other code
+     not governed by the terms of this License and distribute the Larger
+     Work as a single product. In such a case, You must make sure the
+     requirements of this License are fulfilled for the Covered Code.
+
+4. Inability to Comply Due to Statute or Regulation.
+
+     If it is impossible for You to comply with any of the terms of this
+     License with respect to some or all of the Covered Code due to
+     statute, judicial order, or regulation then You must: (a) comply with
+     the terms of this License to the maximum extent possible; and (b)
+     describe the limitations and the code they affect. Such description
+     must be included in the LEGAL file described in Section 3.4 and must
+     be included with all distributions of the Source Code. Except to the
+     extent prohibited by statute or regulation, such description must be
+     sufficiently detailed for a recipient of ordinary skill to be able to
+     understand it.
+
+5. Application of this License.
+
+     This License applies to code to which the Initial Developer has
+     attached the notice in Exhibit A and to related Covered Code.
+
+6. Versions of the License.
+
+     6.1. New Versions.
+     Netscape Communications Corporation ("Netscape") may publish revised
+     and/or new versions of the License from time to time. Each version
+     will be given a distinguishing version number.
+
+     6.2. Effect of New Versions.
+     Once Covered Code has been published under a particular version of the
+     License, You may always continue to use it under the terms of that
+     version. You may also choose to use such Covered Code under the terms
+     of any subsequent version of the License published by Netscape. No one
+     other than Netscape has the right to modify the terms applicable to
+     Covered Code created under this License.
+
+     6.3. Derivative Works.
+     If You create or use a modified version of this License (which you may
+     only do in order to apply it to code which is not already Covered Code
+     governed by this License), You must (a) rename Your license so that
+     the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
+     "MPL", "NPL" or any confusingly similar phrase do not appear in your
+     license (except to note that your license differs from this License)
+     and (b) otherwise make it clear that Your version of the license
+     contains terms which differ from the Mozilla Public License and
+     Netscape Public License. (Filling in the name of the Initial
+     Developer, Original Code or Contributor in the notice described in
+     Exhibit A shall not of themselves be deemed to be modifications of
+     this License.)
+
+7. DISCLAIMER OF WARRANTY.
+
+     COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
+     WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+     WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
+     DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
+     THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
+     IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
+     YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
+     COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
+     OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
+     ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+8. TERMINATION.
+
+     8.1.  This License and the rights granted hereunder will terminate
+     automatically if You fail to comply with terms herein and fail to cure
+     such breach within 30 days of becoming aware of the breach. All
+     sublicenses to the Covered Code which are properly granted shall
+     survive any termination of this License. Provisions which, by their
+     nature, must remain in effect beyond the termination of this License
+     shall survive.
+
+     8.2.  If You initiate litigation by asserting a patent infringement
+     claim (excluding declatory judgment actions) against Initial Developer
+     or a Contributor (the Initial Developer or Contributor against whom
+     You file such action is referred to as "Participant")  alleging that:
+
+     (a)  such Participant's Contributor Version directly or indirectly
+     infringes any patent, then any and all rights granted by such
+     Participant to You under Sections 2.1 and/or 2.2 of this License
+     shall, upon 60 days notice from Participant terminate prospectively,
+     unless if within 60 days after receipt of notice You either: (i)
+     agree in writing to pay Participant a mutually agreeable reasonable
+     royalty for Your past and future use of Modifications made by such
+     Participant, or (ii) withdraw Your litigation claim with respect to
+     the Contributor Version against such Participant.  If within 60 days
+     of notice, a reasonable royalty and payment arrangement are not
+     mutually agreed upon in writing by the parties or the litigation claim
+     is not withdrawn, the rights granted by Participant to You under
+     Sections 2.1 and/or 2.2 automatically terminate at the expiration of
+     the 60 day notice period specified above.
+
+     (b)  any software, hardware, or device, other than such Participant's
+     Contributor Version, directly or indirectly infringes any patent, then
+     any rights granted to You by such Participant under Sections 2.1(b)
+     and 2.2(b) are revoked effective as of the date You first made, used,
+     sold, distributed, or had made, Modifications made by that
+     Participant.
+
+     8.3.  If You assert a patent infringement claim against Participant
+     alleging that such Participant's Contributor Version directly or
+     indirectly infringes any patent where such claim is resolved (such as
+     by license or settlement) prior to the initiation of patent
+     infringement litigation, then the reasonable value of the licenses
+     granted by such Participant under Sections 2.1 or 2.2 shall be taken
+     into account in determining the amount or value of any payment or
+     license.
+
+     8.4.  In the event of termination under Sections 8.1 or 8.2 above,
+     all end user license agreements (excluding distributors and resellers)
+     which have been validly granted by You or any distributor hereunder
+     prior to termination shall survive termination.
+
+9. LIMITATION OF LIABILITY.
+
+     UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
+     (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
+     DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
+     OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
+     ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
+     CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
+     WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+     COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
+     INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
+     LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
+     RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
+     PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
+     EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
+     THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+
+10. U.S. GOVERNMENT END USERS.
+
+     The Covered Code is a "commercial item," as that term is defined in
+     48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
+     software" and "commercial computer software documentation," as such
+     terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
+     C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
+     all U.S. Government End Users acquire Covered Code with only those
+     rights set forth herein.
+
+11. MISCELLANEOUS.
+
+     This License represents the complete agreement concerning subject
+     matter hereof. If any provision of this License is held to be
+     unenforceable, such provision shall be reformed only to the extent
+     necessary to make it enforceable. This License shall be governed by
+     California law provisions (except to the extent applicable law, if
+     any, provides otherwise), excluding its conflict-of-law provisions.
+     With respect to disputes in which at least one party is a citizen of,
+     or an entity chartered or registered to do business in the United
+     States of America, any litigation relating to this License shall be
+     subject to the jurisdiction of the Federal Courts of the Northern
+     District of California, with venue lying in Santa Clara County,
+     California, with the losing party responsible for costs, including
+     without limitation, court costs and reasonable attorneys' fees and
+     expenses. The application of the United Nations Convention on
+     Contracts for the International Sale of Goods is expressly excluded.
+     Any law or regulation which provides that the language of a contract
+     shall be construed against the drafter shall not apply to this
+     License.
+
+12. RESPONSIBILITY FOR CLAIMS.
+
+     As between Initial Developer and the Contributors, each party is
+     responsible for claims and damages arising, directly or indirectly,
+     out of its utilization of rights under this License and You agree to
+     work with Initial Developer and Contributors to distribute such
+     responsibility on an equitable basis. Nothing herein is intended or
+     shall be deemed to constitute any admission of liability.
+
+13. MULTIPLE-LICENSED CODE.
+
+     Initial Developer may designate portions of the Covered Code as
+     "Multiple-Licensed".  "Multiple-Licensed" means that the Initial
+     Developer permits you to utilize portions of the Covered Code under
+     Your choice of the NPL or the alternative licenses, if any, specified
+     by the Initial Developer in the file described in Exhibit A.
+
+EXHIBIT A -Mozilla Public License.
+
+     ``The contents of this file are subject to the Mozilla Public License
+     Version 1.1 (the "License"); you may not use this file except in
+     compliance with the License. You may obtain a copy of the License at
+     http://www.mozilla.org/MPL/
+
+     Software distributed under the License is distributed on an "AS IS"
+     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+     License for the specific language governing rights and limitations
+     under the License.
+
+     The Original Code is ______________________________________.
+
+     The Initial Developer of the Original Code is ________________________.
+     Portions created by ______________________ are Copyright (C) ______
+     _______________________. All Rights Reserved.
+
+     Contributor(s): ______________________________________.
+
+     Alternatively, the contents of this file may be used under the terms
+     of the _____ license (the  "[___] License"), in which case the
+     provisions of [______] License are applicable instead of those
+     above.  If you wish to allow use of your version of this file only
+     under the terms of the [____] License and not to allow others to use
+     your version of this file under the MPL, indicate your decision by
+     deleting  the provisions above and replace  them with the notice and
+     other provisions required by the [___] License.  If you do not delete
+     the provisions above, a recipient may use your version of this file
+     under either the MPL or the [___] License."
+
+     [NOTE: The text of this Exhibit A may differ slightly from the text of
+     the notices in the Source Code files of the Original Code. You should
+     use the text of this Exhibit A rather than the text found in the
+     Original Code Source Code for Your Modifications.]
+

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/gpl-2.txt
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/gpl-2.txt	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/gpl-2.txt	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/index.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/index.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/index.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,141 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<!-- JsUnit -->
+<!-- ***** BEGIN LICENSE BLOCK *****
+   - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+   -
+   - The contents of this file are subject to the Mozilla Public License Version
+   - 1.1 (the "License"); you may not use this file except in compliance with
+   - the License. You may obtain a copy of the License at
+   - http://www.mozilla.org/MPL/
+   -
+   - Software distributed under the License is distributed on an "AS IS" basis,
+   - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+   - for the specific language governing rights and limitations under the
+   - License.
+   -
+   - The Original Code is Edward Hieatt code.
+   -
+   - The Initial Developer of the Original Code is
+   - Edward Hieatt, edward at jsunit.net.
+   - Portions created by the Initial Developer are Copyright (C) 2001
+   - the Initial Developer. All Rights Reserved.
+   -
+   - Contributor(s):
+   - Edward Hieatt, edward at jsunit.net (original author)
+   - Bob Clary, bc at bclary.comn
+   -
+   - Alternatively, the contents of this file may be used under the terms of
+   - either the GNU General Public License Version 2 or later (the "GPL"), or
+   - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+   - in which case the provisions of the GPL or the LGPL are applicable instead
+   - of those above. If you wish to allow use of your version of this file only
+   - under the terms of either the GPL or the LGPL, and not to allow others to
+   - use your version of this file under the terms of the MPL, indicate your
+   - decision by deleting the provisions above and replace them with the notice
+   - and other provisions required by the LGPL or the GPL. If you do not delete
+   - the provisions above, a recipient may use your version of this file under
+   - the terms of any one of the MPL, the GPL or the LGPL.
+   -
+   - ***** END LICENSE BLOCK ***** -->
+
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>Licensing</title>
+    <link rel="stylesheet" type="text/css" href="../app/css/jsUnitStyle.css">
+</head>
+
+<body>
+<table width="100%" cellpadding="0" cellspacing="0" border="1" summary="jsUnit Information">
+    <tr>
+        <th align="center" valign="top"><h1>JsUnit Licenses</h1></th>
+
+        <td align="right" valign="top">
+            <a href="http://www.jsunit.net/" target="_blank">JsUnit Home</a><br>
+            <a href="mailto:edward at jsunit.net">edward at jsunit.net</a><br>
+        </tr>
+</table>
+
+<p><h2>Third-party licenses:</h2>
+    <ul>
+        <li>JDOM: Portions of this software are copyright Copyright (C) 2000-2003 Jason Hunter & Brett McLaughlin. All
+            rights reserved. See <a href="JDOM_license.txt">JDOM_license.txt</a>.
+        <li>Jetty: Portions of this software are copyright � Mort Bay Consulting Pty. Ltd. (Australia) and others. All
+            Rights Reserved. See <a href="Jetty_license.html">Jetty_license.html</a>.
+        <li>Individual files in this package may contain additional copyright notices. The javax.servlet packages are
+            copyright Sun Microsystems Inc. All Rights Reserved.
+    </ul>
+</p>
+
+<p><h2>JsUnit licenses:</h2>
+    JsUnit is licensed under 3 different licenses giving you the freedom
+    to use, modify and distribute JsUnit in a variety of fashions.
+</p>
+
+<ol>
+    <li>
+        <p><a href="MPL-1.1.txt">Mozilla Public License 1.1</a></p>
+
+        <p>See <a href="http://www.mozilla.org/MPL/">mozilla.org</a>
+            for more details.</p>
+    </li>
+
+    <li>
+        <p><a href="gpl-2.txt">GNU Public License 2</a></p>
+
+        <p>See <a href="http://www.gnu.org/licenses/licenses.html">www.gnu.org</a>
+            for more details.</p>
+    </li>
+
+    <li>
+        <p><a href="lgpl-2.1.txt">GNU Lesser Public License 2.1</a></p>
+
+        <p>See <a href="http://www.gnu.org/licenses/licenses.html">www.gnu.org</a>
+            for more details.</p>
+    </li>
+</ol>
+
+<p>
+    Every Java and JavaScript source file in this distribution should be considered to be under the following licensing
+    terms.
+    <pre>
+        ***** BEGIN LICENSE BLOCK *****
+        - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+        -
+        - The contents of this file are subject to the Mozilla Public License Version
+        - 1.1 (the "License"); you may not use this file except in compliance with
+        - the License. You may obtain a copy of the License at
+        - http://www.mozilla.org/MPL/
+        -
+        - Software distributed under the License is distributed on an "AS IS" basis,
+        - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+        - for the specific language governing rights and limitations under the
+        - License.
+        -
+        - The Original Code is Edward Hieatt code.
+        -
+        - The Initial Developer of the Original Code is
+        - Edward Hieatt, edward at jsunit.net.
+        - Portions created by the Initial Developer are Copyright (C) 2003
+        - the Initial Developer. All Rights Reserved.
+        -
+        - Author Edward Hieatt, edward at jsunit.net
+        -
+        - Alternatively, the contents of this file may be used under the terms of
+        - either the GNU General Public License Version 2 or later (the "GPL"), or
+        - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+        - in which case the provisions of the GPL or the LGPL are applicable instead
+        - of those above. If you wish to allow use of your version of this file only
+        - under the terms of either the GPL or the LGPL, and not to allow others to
+        - use your version of this file under the terms of the MPL, indicate your
+        - decision by deleting the provisions above and replace them with the notice
+        - and other provisions required by the LGPL or the GPL. If you do not delete
+        - the provisions above, a recipient may use your version of this file under
+        - the terms of any one of the MPL, the GPL or the LGPL.
+        -
+        - ***** END LICENSE BLOCK *****
+    </pre>
+</p>
+</body>
+</html>
+

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/lgpl-2.1.txt
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/lgpl-2.1.txt	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/lgpl-2.1.txt	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,504 @@
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/mpl-tri-license-c.txt
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/mpl-tri-license-c.txt	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/mpl-tri-license-c.txt	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,35 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is __________________________________________.
+ *
+ * The Initial Developer of the Original Code is
+ * ____________________________________________.
+ * Portions created by the Initial Developer are Copyright (C) 2___
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/mpl-tri-license-html.txt
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/mpl-tri-license-html.txt	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/licenses/mpl-tri-license-html.txt	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,35 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+   - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+   -
+   - The contents of this file are subject to the Mozilla Public License Version
+   - 1.1 (the "License"); you may not use this file except in compliance with
+   - the License. You may obtain a copy of the License at
+   - http://www.mozilla.org/MPL/
+   -
+   - Software distributed under the License is distributed on an "AS IS" basis,
+   - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+   - for the specific language governing rights and limitations under the
+   - License.
+   -
+   - The Original Code is __________________________________________.
+   -
+   - The Initial Developer of the Original Code is
+   - ____________________________________________.
+   - Portions created by the Initial Developer are Copyright (C) 2___
+   - the Initial Developer. All Rights Reserved.
+   -
+   - Contributor(s):
+   -
+   - Alternatively, the contents of this file may be used under the terms of
+   - either the GNU General Public License Version 2 or later (the "GPL"), or
+   - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+   - in which case the provisions of the GPL or the LGPL are applicable instead
+   - of those above. If you wish to allow use of your version of this file only
+   - under the terms of either the GPL or the LGPL, and not to allow others to
+   - use your version of this file under the terms of the MPL, indicate your
+   - decision by deleting the provisions above and replace them with the notice
+   - and other provisions required by the LGPL or the GPL. If you do not delete
+   - the provisions above, a recipient may use your version of this file under
+   - the terms of any one of the MPL, the GPL or the LGPL.
+   -
+   - ***** END LICENSE BLOCK ***** -->

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/logging.properties
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/logging.properties	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/logging.properties	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,12 @@
+.level=INFO
+
+handlers=java.util.logging.ConsoleHandler
+
+java.util.logging.ConsoleHandler.level=ALL
+java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
+
+net.jsunit.level=INFO
+org.mortbay.level=WARNING
+com.opensymphony.webwork.level=SEVERE
+com.opensymphony.xwork.level=SEVERE
+

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/readme.txt
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/readme.txt	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/readme.txt	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,19 @@
+JsUnit
+Copyright (C) 2001-6 Edward Hieatt, edward at jsunit.net
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+Please see http://www.jsunit.net/ for JsUnit documentation and
+the "licenses" directory for license information.
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/testRunner.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/testRunner.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/testRunner.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,167 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
+<html>
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>JsUnit Test Runner</title>
+<script language="JavaScript" type="text/javascript" src="app/xbDebug.js"></script>
+<script language="JavaScript" type="text/javascript" src="app/jsUnitCore.js"></script>
+<script language="JavaScript" type="text/javascript">
+    var DEFAULT_TEST_FRAME_HEIGHT = 250;
+
+    function jsUnitParseParms(string) {
+        var i;
+        var searchString = unescape(string);
+        var parameterHash = new Object();
+
+        if (!searchString) {
+            return parameterHash;
+        }
+
+        i = searchString.indexOf('?');
+        if (i != -1) {
+            searchString = searchString.substring(i + 1);
+        }
+
+        var parmList = searchString.split('&');
+        var a;
+        for (i = 0; i < parmList.length; i++) {
+            a = parmList[i].split('=');
+            a[0] = a[0].toLowerCase();
+            if (a.length > 1) {
+                parameterHash[a[0]] = a[1];
+            }
+            else {
+                parameterHash[a[0]] = true;
+            }
+        }
+        return parameterHash;
+    }
+
+    function jsUnitConstructTestParms() {
+        var p;
+        var parms = '';
+
+        for (p in jsUnitParmHash) {
+            var value = jsUnitParmHash[p];
+
+            if (!value ||
+                p == 'testpage' ||
+                p == 'autorun' ||
+                p == 'submitresults' ||
+                p == 'showtestframe' ||
+                p == 'resultid') {
+                continue;
+            }
+
+            if (parms) {
+                parms += '&';
+            }
+
+            parms += p;
+
+            if (typeof(value) != 'boolean') {
+                parms += '=' + value;
+            }
+        }
+        return escape(parms);
+    }
+
+    var jsUnitParmHash = jsUnitParseParms(document.location.search);
+
+    // set to true to turn debugging code on, false to turn it off.
+    xbDEBUG.on = jsUnitGetParm('debug') ? true : false;
+</script>
+
+<script language="JavaScript" type="text/javascript" src="app/jsUnitTestManager.js"></script>
+<script language="JavaScript" type="text/javascript" src="app/jsUnitTracer.js"></script>
+<script language="JavaScript" type="text/javascript" src="app/jsUnitTestSuite.js"></script>
+<script language="JavaScript" type="text/javascript">
+
+    var testManager;
+    var utility;
+    var tracer;
+
+
+    if (!Array.prototype.push) {
+        Array.prototype.push = function (anObject) {
+            this[this.length] = anObject;
+        }
+    }
+
+    if (!Array.prototype.pop) {
+        Array.prototype.pop = function () {
+            if (this.length > 0) {
+                delete this[this.length - 1];
+                this.length--;
+            }
+        }
+    }
+
+    function shouldKickOffTestsAutomatically() {
+        return jsUnitGetParm('autorun') == "true";
+    }
+
+    function shouldShowTestFrame() {
+        return jsUnitGetParm('showtestframe');
+    }
+
+    function shouldSubmitResults() {
+        return jsUnitGetParm('submitresults');
+    }
+
+    function getResultId() {
+        if (jsUnitGetParm('resultid'))
+            return jsUnitGetParm('resultid');
+        return "";
+    }
+
+    function submitResults() {
+        window.mainFrame.mainData.document.testRunnerForm.runButton.disabled = true;
+        window.mainFrame.mainResults.populateHeaderFields(getResultId(), navigator.userAgent, JSUNIT_VERSION, testManager.resolveUserEnteredTestFileName());
+        window.mainFrame.mainResults.submitResults();
+    }
+
+    function wasResultUrlSpecified() {
+        return shouldSubmitResults() && jsUnitGetParm('submitresults') != 'true';
+    }
+
+    function getSpecifiedResultUrl() {
+        return jsUnitGetParm('submitresults');
+    }
+
+    function init() {
+        var testRunnerFrameset = document.getElementById('testRunnerFrameset');
+        if (shouldShowTestFrame() && testRunnerFrameset) {
+            var testFrameHeight;
+            if (jsUnitGetParm('showtestframe') == 'true')
+                testFrameHeight = DEFAULT_TEST_FRAME_HEIGHT;
+            else
+                testFrameHeight = jsUnitGetParm('showtestframe');
+            testRunnerFrameset.rows = '*,0,' + testFrameHeight;
+        }
+        testManager = new jsUnitTestManager();
+        tracer = new JsUnitTracer(testManager);
+        if (shouldKickOffTestsAutomatically()) {
+            window.mainFrame.mainData.kickOffTests();
+        }
+    }
+
+
+</script>
+</head>
+
+<frameset id="testRunnerFrameset" rows="*,0,0" border="0" onload="init()">
+
+    <frame frameborder="0" name="mainFrame" src="./app/main-frame.html">
+    <frame frameborder="0" name="documentLoader" src="./app/main-loader.html">
+    <frame frameborder="0" name="testContainer" src="./app/testContainer.html">
+
+    <noframes>
+        <body>
+        <p>Sorry, JsUnit requires support for frames.</p>
+        </body>
+    </noframes>
+</frameset>
+
+</html>
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/data/data.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/data/data.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/data/data.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,218 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+        "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>test</title>
+</head>
+
+<body>
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+
+<p>foo</p>
+</body>
+</html>

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/data/staff.css
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/data/staff.css	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/data/staff.css	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,30 @@
+staff {
+    display: table;
+    color: black;
+    background-color: white;
+    border: solid 1px black;
+}
+
+employee {
+    display: table-row;
+    border: solid 1px black;
+    padding: 1px;
+}
+
+employeeId, name, position, salary, gender, address {
+    display: table-cell;
+    border: solid 1px black;
+    padding: 1px;
+}
+
+address[domestic="Yes"] {
+    background-color: silver;
+}
+
+address[street="Yes"] {
+    color: green;
+}
+
+address[street="No"] {
+    color: red;
+}

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/data/staff.dtd
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/data/staff.dtd	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/data/staff.dtd	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,17 @@
+<!ELEMENT employeeId (#PCDATA)>
+<!ELEMENT name (#PCDATA)>
+<!ELEMENT position (#PCDATA)>
+<!ELEMENT salary (#PCDATA)>
+<!ELEMENT address (#PCDATA)>
+<!ELEMENT entElement ( #PCDATA ) >
+<!ELEMENT gender ( #PCDATA | entElement )* >
+<!ELEMENT employee (employeeId, name, position, salary, gender, address) >
+<!ELEMENT staff (employee)+>
+<!ATTLIST entElement
+attr1 CDATA "Attr">
+<!ATTLIST address
+domestic CDATA #IMPLIED
+street CDATA "Yes">
+<!ATTLIST entElement
+domestic CDATA "MALE" >
+

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/data/staff.xml
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/data/staff.xml	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/data/staff.xml	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,58 @@
+<?xml version="1.0"?><?TEST-STYLE PIDATA?>
+<!DOCTYPE staff SYSTEM "staff.dtd" [
+        <!ENTITY ent1 "es">
+        <!ENTITY ent2 "1900 Dallas Road">
+        <!ENTITY ent3 "Texas">
+        <!ENTITY ent4 "<entElement domestic='Yes'>Element data</entElement><?PItarget PIdata?>">
+        <!ENTITY ent5 PUBLIC "entityURI" "entityFile" NDATA notation1>
+        <!ENTITY ent1 "This entity should be discarded">
+        <!NOTATION notation1 PUBLIC "notation1File">
+        <!NOTATION notation2 SYSTEM "notation2File">
+        ]>
+<!-- This is comment number 1.-->
+<staff>
+    <employee>
+        <employeeId>EMP0001</employeeId>
+        <name>Margaret Martin</name>
+        <position>Accountant</position>
+        <salary>56,000</salary>
+        <gender>Female</gender>
+        <address domestic="Yes">1230 North Ave. Dallas, Texas 98551</address>
+    </employee>
+    <employee>
+        <employeeId>EMP0002</employeeId>
+        <name>Martha Raynolds<![CDATA[This is a CDATASection with EntityReference number 2 &ent2;]]>
+            <![CDATA[This is an adjacent CDATASection with a reference to a tab &tab;]]></name>
+        <position>Secretary</position>
+        <salary>35,000</salary>
+        <gender>Female</gender>
+        <address domestic="Yes" street="Yes">&ent2; Dallas, &ent3;
+            98554</address>
+    </employee>
+    <employee>
+        <employeeId>EMP0003</employeeId>
+        <name>Roger
+            Jones</name>
+        <position>Department Manager</position>
+        <salary>100,000</salary>
+        <gender>&ent4;
+        </gender>
+        <address domestic="Yes" street="No">PO Box 27 Irving, texas 98553</address>
+    </employee>
+    <employee>
+        <employeeId>EMP0004</employeeId>
+        <name>Jeny Oconnor</name>
+        <position>Personnel Director</position>
+        <salary>95,000</salary>
+        <gender>Female</gender>
+        <address domestic="Yes" street="Y&ent1;">27 South Road. Dallas, Texas 98556</address>
+    </employee>
+    <employee>
+        <employeeId>EMP0005</employeeId>
+        <name>Robert Myers</name>
+        <position>Computer Specialist</position>
+        <salary>90,000</salary>
+        <gender>male</gender>
+        <address street="Yes">1821 Nordic. Road, Irving Texas 98558</address>
+    </employee>
+</staff>

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitAssertionTests.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitAssertionTests.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitAssertionTests.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,405 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>JsUnit Assertion Tests</title>
+<link rel="stylesheet" type="text/css" href="../css/jsUnitStyle.css">
+<script language="JavaScript" type="text/javascript" src="../app/jsUnitCore.js"></script>
+<script language="JavaScript" type="text/javascript">
+
+function testAssert() {
+    assert("true should be true", true);
+    assert(true);
+}
+
+function testAssertTrue() {
+    assertTrue("true should be true", true);
+    assertTrue(true);
+}
+
+function testAssertFalse() {
+    assertFalse("false should be false", false);
+    assertFalse(false);
+}
+
+function testAssertEquals() {
+    assertEquals("1 should equal 1", 1, 1);
+    assertEquals(1, 1);
+}
+
+function testAssertNotEquals() {
+    assertNotEquals("1 should not equal 2", 1, 2);
+    assertNotEquals(1, 2);
+}
+
+function testAssertNull() {
+    assertNull("null should be null", null);
+    assertNull(null);
+}
+
+function testAssertNotNull() {
+    assertNotNull("1 should not be null", 1);
+    assertNotNull(1);
+}
+
+function testAssertUndefined() {
+    var myVar;
+    assertUndefined("A declared but unassigned variable should have the undefined value", myVar);
+    assertUndefined(myVar);
+}
+
+function testAssertNotUndefined() {
+    assertNotUndefined("1 should not be undefined", 1);
+    assertNotUndefined(1);
+}
+
+function testAssertNaN() {
+    assertNaN("a string should not be a number", "string");
+    assertNaN("string");
+}
+
+function testAssertNotNaN() {
+    assertNotNaN("1 should not be not a number", 1);
+    assertNotNaN(1);
+}
+
+function testFail() {
+    var excep = null;
+    try {
+        fail("Failure message");
+    } catch (e) {
+        excep = e;
+    }
+    assertJsUnitException("fail(string) should throw a JsUnitException", excep);
+}
+
+function testTooFewArguments() {
+    var excep = null;
+    try {
+        assert();
+    } catch (e1) {
+        excep = e1;
+    }
+    assertNonJsUnitException("Calling an assertion function with too few arguments should throw an exception", excep);
+}
+
+function testTooManyArguments() {
+    var excep = null;
+    try {
+        assertEquals("A comment", true, true, true);
+    } catch (e2) {
+        excep = e2;
+    }
+    assertNonJsUnitException("Calling an assertion function with too many arguments should throw an exception", excep);
+}
+
+function testInvalidCommentArgumentType() {
+    var excep = null;
+    try {
+        assertNull(1, true);
+    } catch (e3) {
+        excep = e3;
+    }
+    assertNonJsUnitException("Calling an assertion function with a non-string comment should throw an exception", excep);
+}
+
+function testInvalidArgumentType() {
+    var excep = null;
+    try {
+        assert("string");
+    } catch (e) {
+        excep = e;
+    }
+    assertNonJsUnitException("Calling an assertion function with an invalid argument should throw an exception", excep);
+}
+
+function testAssertArrayEquals() {
+    var array1 = Array();
+    array1[0] = "foo";
+    array1[1] = "bar";
+    array1[2] = "foobar";
+    var array2 = Array();
+    array2[0] = "foo";
+    array2[1] = "bar";
+    array2[2] = "foobar";
+    var array3 = Array();
+    array3[0] = "foo";
+    array3[1] = "bar";
+    var array4 = Array();
+    array4[0] = "bar";
+    array4[1] = "foo";
+    array4[2] = "foobar";
+
+    assertArrayEquals(array1, array1);
+    assertArrayEquals(array1, array2);
+    try {
+        assertArrayEquals(array1, array3);
+        fail("Should not be equal");
+    } catch (e) {
+        assertJsUnitException("Should be a JsUnitException", e);
+        if (e.comment == "Call to fail()")
+            fail(e.comment + e.jsUnitMessage); //tried fail is also caught
+    }
+    try {
+        assertArrayEquals(array1, array4);
+        fail("Should not be equal");
+    } catch (e) {
+        assertJsUnitException("Should be a JsUnitException", e);
+        if (e.comment == "Call to fail()")
+            fail(e.comment + e.jsUnitMessage); //tried fail is also caught
+    }
+    var array5 = ['foo', 'bar', ['nested', 'bar'], 'foobar'];
+    var array6 = ['foo', 'bar', ['nested', 'bar'], 'foobar'];
+    var array7 = ['foo', 'bar', ['nested', 'foo'], 'foobar'];
+    assertArrayEquals('Equal nested arrays', array5, array6);
+    try
+    {
+        assertArrayEquals(array5, array7);
+        var failure = 'Differing nested arrays found to be equal';
+        fail(failure);
+    }
+    catch (e)
+    {
+        assertJsUnitException("Should be a JsUnitException", e);
+        if (e.jsUnitMessage == failure)
+            fail(e.jsUnitMessage);
+    }
+}
+
+function testAssertObjectEquals()
+{
+    var failure;
+    var o1 = {foo:'bar'};
+    var o2 = {foo:'bar'};
+    assertObjectEquals('Single object', o1, o1);
+    assertObjectEquals('Same objects', o1, o2);
+    var o3 = {foo:'foo'};
+    var o4 = {foo:'foo',
+        bar: function () {
+            this.foo = 'bar';
+            delete this.bar
+        }};
+    var o5 = {foo:'foo',
+        bar: function () {
+            this.foo = 'foo';
+            delete this.bar
+        }};
+    try
+    {
+        assertObjectEquals(o1, o3);
+        fail(failure = 'Simple differing objects found to be the same');
+    }
+    catch (e)
+    {
+        assertJsUnitException("Should be a JsUnitException", e);
+        if (e.jsUnitMessage == failure)
+            fail(e.jsUnitMessage);
+    }
+    try
+    {
+        assertObjectEquals(o4, o5);
+        fail(failure = 'Objects with different methods found to be the same');
+    }
+    catch (e)
+    {
+        assertJsUnitException("Should be a JsUnitException", e);
+        if (e.jsUnitMessage == failure)
+            fail(e.jsUnitMessage);
+    }
+
+    o4.bar();
+    assertObjectEquals('Different objects, made to be the same', o1, o4);
+    try
+    {
+        assertObjectEquals({ts:new Date()}, {ts:new Date()});
+        fail(failure = 'Objects with different Date attributes found to be the same');
+    }
+    catch (e)
+    {
+        assertJsUnitException("Should be a JsUnitException", e);
+        if (e.jsUnitMessage == failure)
+            fail(e.jsUnitMessage);
+    }
+    try
+    {
+        assertObjectEquals(new Date(), new Date());
+        fail(failure = 'Different Date objects found to be the same');
+    }
+    catch (e)
+    {
+        assertJsUnitException("Should be a JsUnitException", e);
+        if (e.jsUnitMessage == failure)
+            fail(e.jsUnitMessage);
+    }
+    assertObjectEquals(/a/, new RegExp('a'));
+    assertObjectEquals(/a/i, new RegExp('a', 'i'));
+
+    try
+    {
+        assertObjectEquals(/a/i, new RegExp('a', 'g'));
+        fail(failure = 'RegExp with different flags found to be the same');
+    }
+    catch (e)
+    {
+        assertJsUnitException("Should be a JsUnitException", e);
+        if (e.jsUnitMessage == failure)
+            fail(e.jsUnitMessage);
+    }
+    try
+    {
+        assertObjectEquals(/a/, new RegExp('b'));
+        fail(failure = 'RegExp with different patterns found to be the same');
+    }
+    catch (e)
+    {
+        assertJsUnitException("Should be a JsUnitException", e);
+        if (e.jsUnitMessage == failure)
+            fail(e.jsUnitMessage);
+    }
+}
+
+function testAssertObjectEqualsOnStrings() {
+    var s1 = 'string1';
+    var s2 = 'string1';
+    var newS1 = new String('string1');
+    assertObjectEquals('Same Strings', s1, s2);
+    assertObjectEquals('Same Strings 1 with new', s1, newS1);
+}
+
+function testAssertObjectEqualsOnNumbers() {
+    var failure;
+    var n1 = 1;
+    var n2 = 1;
+    var newN1 = new Number(1);
+    assertObjectEquals('Same Numbers', n1, n2);
+    assertObjectEquals('Same Numbers 1 with new', n1, newN1);
+    var n3 = 2;
+    var newN3 = new Number(2);
+    try
+    {
+        assertObjectEquals(n1, n3);
+        fail(failure = 'Different Numbers');
+    }
+    catch (e)
+    {
+        assertJsUnitException("Should be a JsUnitException", e);
+        if (e.jsUnitMessage == failure)
+            fail(e.jsUnitMessage);
+    }
+    try
+    {
+        assertObjectEquals(newN1, newN3);
+        fail(failure = 'Different New Numbers');
+    }
+    catch (e)
+    {
+        assertJsUnitException("Should be a JsUnitException", e);
+        if (e.jsUnitMessage == failure)
+            fail(e.jsUnitMessage);
+    }
+
+}
+
+function testAssertEvaluatesToTrue() {
+    assertEvaluatesToTrue("foo");
+    assertEvaluatesToTrue(true);
+    assertEvaluatesToTrue(1);
+    try {
+        assertEvaluatesToTrue(null);
+        fail("Should have thrown a JsUnitException");
+    } catch (e) {
+        assertJsUnitException("Should be a JsUnitException", e);
+    }
+}
+
+function testAssertEvaluatesToFalse() {
+    assertEvaluatesToFalse("");
+    assertEvaluatesToFalse(null);
+    assertEvaluatesToFalse(false);
+    assertEvaluatesToFalse(0);
+    try {
+        assertEvaluatesToFalse("foo");
+        fail("Should have thrown a JsUnitException");
+    } catch (e) {
+        assertJsUnitException("Should be a JsUnitException", e);
+    }
+}
+
+function testAssertHTMLEquals() {
+    assertHTMLEquals("<div id=mydiv>foobar</div>", "<div id='mydiv'>foobar</div>");
+    assertHTMLEquals("<p/>", "<p></p>");
+    assertHTMLEquals("foo bar", "foo bar");
+    assertHTMLEquals("a comment", "<p id='foo'>foo bar</p>", "<p id=foo>foo bar</p>");
+}
+
+function testAssertHashEquals() {
+    var hash1 = new Array();
+    hash1["key1"] = "value1";
+    hash1["key2"] = "value2";
+
+    var hash2 = new Array();
+    try {
+        assertHashEquals(hash1, hash2);
+        fail();
+    } catch (e) {
+        assertJsUnitException("hash2 is empty", e);
+    }
+    hash2["key1"] = "value1";
+    try {
+        assertHashEquals(hash1, hash2);
+        fail();
+    } catch (e) {
+        assertJsUnitException("hash2 is a of a different size", e);
+    }
+    hash2["key2"] = "foo";
+    try {
+        assertHashEquals(hash1, hash2);
+        fail();
+    } catch (e) {
+        assertJsUnitException("hash2 has different values", e);
+    }
+    hash2["key2"] = "value2";
+    assertHashEquals(hash1, hash2);
+}
+
+function testAssertRoughlyEquals() {
+    assertRoughlyEquals(1, 1.1, 0.5);
+    assertRoughlyEquals(1, 5, 6);
+    assertRoughlyEquals(-4, -5, 2);
+    assertRoughlyEquals(-0.5, 0.1, 0.7);
+    try {
+        assertRoughlyEquals(1, 2, 0.5);
+    } catch (e) {
+        assertJsUnitException("1 and 2 are more than 0.5 apart", e);
+    }
+}
+
+function testAssertContains() {
+    assertContains("foo", "foobar");
+    assertContains("ooba", "foobar");
+    assertContains("bar", "foobar");
+}
+
+function assertJsUnitException(comment, allegedJsUnitException) {
+    assertNotNull(comment, allegedJsUnitException);
+    assert(comment, allegedJsUnitException.isJsUnitException);
+    assertNotUndefined(comment, allegedJsUnitException.comment);
+}
+
+function assertNonJsUnitException(comment, allegedNonJsUnitException) {
+    assertNotNull(comment, allegedNonJsUnitException);
+    assertUndefined(comment, allegedNonJsUnitException.isJsUnitException);
+    assertNotUndefined(comment, allegedNonJsUnitException.description);
+}
+</script>
+</head>
+
+<body>
+<h1>JsUnit Assertion Tests</h1>
+
+<p>This page contains tests for the JsUnit Assertion
+    functions. To see them, take a look at the source.</p>
+</body>
+</html>

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitFrameworkUtilityTests.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitFrameworkUtilityTests.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitFrameworkUtilityTests.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,99 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>JsUnit StackTrace Tests</title>
+    <link rel="stylesheet" type="text/css" href="../css/jsUnitStyle.css">
+    <script language="JavaScript" type="text/javascript" src="../app/jsUnitCore.js"></script>
+
+    <script language="JavaScript" type="text/javascript">
+
+        function testStackTrace() {
+            doStackTraceTest(3, "testStackTrace");
+        }
+
+        function doStackTraceTest(numberLeft, testFunctionName) {
+            if (numberLeft > 0) {
+                doStackTraceTest(numberLeft - 1, testFunctionName);
+                return;
+            }
+            assertEquals("> doStackTraceTest\n> doStackTraceTest\n> doStackTraceTest\n> doStackTraceTest\n> " + testFunctionName + "\n", getStackTrace());
+        }
+
+        function testJsUnitTestSuiteClass() {
+            var aSuite = new top.jsUnitTestSuite();
+            aSuite.addTestPage("foo.html");
+            aSuite.addTestPage("bar.html");
+            assertEquals(2, aSuite.testPages.length);
+            assertEquals("foo.html", aSuite.testPages[0]);
+            assertEquals("bar.html", aSuite.testPages[1]);
+            var anotherSuite = new top.jsUnitTestSuite();
+            anotherSuite.addTestPage("foo2.html");
+            anotherSuite.addTestPage("bar2.html");
+            aSuite.addTestSuite(anotherSuite);
+            assertEquals(4, aSuite.testPages.length);
+            assertEquals("foo.html", aSuite.testPages[0]);
+            assertEquals("bar.html", aSuite.testPages[1]);
+            assertEquals("foo2.html", aSuite.testPages[2]);
+            assertEquals("bar2.html", aSuite.testPages[3]);
+        }
+
+        function testTracing() {
+            warn("This is warning 1", "foo");
+            warn("This is warning 2");
+            inform("This is info 1", "foo");
+            inform("This is info 2");
+            debug("This is debug 1", "foo");
+            debug("This is debug 2");
+            info("This is info 3", "foo");
+            info("This is info 4");
+        }
+
+        function testTracingWithUndefinedValue() {
+            inform(JSUNIT_UNDEFINED_VALUE);
+            inform("JSUNIT_UNDEFINED_VALUE", JSUNIT_UNDEFINED_VALUE);
+        }
+
+        function testTraceLevel() {
+            var levelA = new top.JsUnitTraceLevel(100, "foo");
+            var levelB = new top.JsUnitTraceLevel(200, "bar");
+            var levelC = new top.JsUnitTraceLevel(300, "foobar");
+            assertFalse(levelA.matches(levelB));
+            assertTrue(levelB.matches(levelB));
+            assertTrue(levelC.matches(levelB));
+            assertEquals("bar", levelB.getColor());
+        }
+
+        function testDisplayStringForNumber() {
+            assertEquals("<3> (Number)", _displayStringForValue(3));
+        }
+
+        function testDisplayStringForString() {
+            assertEquals("<foo> (String)", _displayStringForValue("foo"));
+        }
+
+        function testDisplayStringForNull() {
+            assertEquals("<null>", _displayStringForValue(null));
+        }
+
+        function testDisplayStringForUndefined() {
+            assertEquals("<undefined>", _displayStringForValue(JSUNIT_UNDEFINED_VALUE));
+        }
+
+        function testDisplayStringForArray() {
+            var anArray = new Array();
+            anArray[0] = "foo";
+            anArray[1] = "bar";
+            assertEquals("<foo,bar> (Array)", _displayStringForValue(anArray));
+        }
+
+    </script>
+</head>
+
+<body>
+<h1>JsUnit Utility Tests</h1>
+
+<p>This page contains tests for the JsUnit framework uses. To see them, take a look at the source.</p>
+</body>
+</html>

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitMockTimeoutTest.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitMockTimeoutTest.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitMockTimeoutTest.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,180 @@
+<html>
+<head>
+<title>Tests for jsUnitMockTimeout.js</title>
+<script language="javascript" src="../app/jsUnitCore.js"></script>
+<script src="../app/jsUnitMockTimeout.js" type="text/javascript"></script>
+<script language="javascript">
+var clockLand;
+
+function setUp() {
+    Clock.reset();
+    clockLand = "";
+}
+
+function testSimpleClock() {
+    setTimeout(function() {
+        clockLand = 'A';
+    }, 1000);
+    setTimeout(function() {
+        clockLand = 'B';
+    }, 2000);
+    setTimeout(function() {
+        clockLand = 'C';
+    }, 3000);
+    Clock.tick(1000);
+    assertEquals('A', clockLand);
+    Clock.tick(1000);
+    assertEquals('B', clockLand);
+    Clock.tick(1000);
+    assertEquals('C', clockLand);
+}
+
+function testClockOutOfOrder() {
+    setTimeout(function() {
+        clockLand = 'A';
+    }, 2000);
+    setTimeout(function() {
+        clockLand = 'B';
+    }, 1000);
+    setTimeout(function() {
+        clockLand = 'C';
+    }, 3000);
+    Clock.tick(1000);
+    assertEquals('B', clockLand);
+    Clock.tick(1000);
+    assertEquals('A', clockLand);
+    Clock.tick(1000);
+    assertEquals('C', clockLand);
+}
+
+function testTimeoutsCanBeCleared() {
+    setTimeout(function() {
+        clockLand = 'A';
+    }, 1000);
+    var timeoutToClear = setTimeout(function() {
+        clockLand = 'B';
+    }, 2000);
+    setTimeout(function() {
+        clockLand = 'C';
+    }, 3000);
+    clearTimeout(timeoutToClear);
+    Clock.tick(1000);
+    assertEquals('A', clockLand);
+    Clock.tick(1000);
+    assertEquals('A', clockLand);
+    Clock.tick(1000);
+    assertEquals('C', clockLand);
+}
+
+function testTimeoutWithinTimeout() {
+    var timeoutFunction = function() {
+        clockLand = "A";
+        setTimeout(function() {
+            clockLand = "B";
+        }, 10)
+    };
+
+    setTimeout(timeoutFunction, 100);
+    Clock.tick(100);
+    assertEquals('A', clockLand);
+    Clock.tick(10);
+    assertEquals('B', clockLand);
+}
+
+function testTimeoutWithRecursion() {
+    var recursiveFunction = function() {
+        clockLand = "A";
+        setTimeout(
+                function() {
+                    recursiveFunction();
+                    clockLand = "B";
+                }, 10);
+    }
+    setTimeout(recursiveFunction, 100);
+    Clock.tick(100);
+    assertEquals("A", clockLand);
+    Clock.tick(10);
+    assertEquals("B", clockLand);
+}
+
+function testTimeoutWithRecursionWithinTick() {
+    var recursiveFunction = function() {
+        clockLand = "A";
+        setTimeout(
+                function() {
+                    recursiveFunction();
+                    clockLand = "B";
+                }, 10);
+    }
+    setTimeout(recursiveFunction, 100);
+    Clock.tick(110);
+    assertEquals("B", clockLand);
+}
+
+function testTimeoutWithDelayedRecursion() {
+    var recursiveFunction = function() {
+        clockLand = "A";
+        setTimeout(
+                function() {
+                    recursiveFunction();
+                    clockLand = "B";
+                }, 100);
+    }
+    setTimeout(recursiveFunction, 10);
+    Clock.tick(10);
+    assertEquals("A", clockLand);
+    Clock.tick(100);
+    assertEquals("B", clockLand);
+}
+
+function testComplicatedBigTickWithOutOfOrderTimeouts() {
+    setTimeout(function() {
+        clockLand = 'A';
+    }, 4000);
+    setTimeout(function() {
+        clockLand = 'B';
+    }, 1000);
+    setTimeout(function() {
+        setTimeout(function() {
+            clockLand = 'D';
+        }, 1000);
+        clockLand = 'C';
+    }, 2000);
+    Clock.tick(4000);
+    assertEquals('D', clockLand);
+}
+
+function testBigTickWithOutOfOrderTimeouts() {
+    setTimeout(function() {
+        clockLand = 'A';
+    }, 3000);
+    setTimeout(function() {
+        clockLand = 'B';
+    }, 1000);
+    setTimeout(function() {
+        clockLand = 'C';
+    }, 2000);
+    Clock.tick(3000);
+    assertEquals('A', clockLand);
+}
+
+function testInterval() {
+    var currentInterval = 0;
+    var intervalKey = setInterval(function () {
+        ++currentInterval;
+    }, 200);
+    Clock.tick(200);
+    assertEquals(1, currentInterval);
+    Clock.tick(400);
+    assertEquals(3, currentInterval);
+    clearInterval(intervalKey);
+    Clock.tick(400);
+    assertEquals(3, currentInterval);
+}
+</script>
+
+</head>
+
+<body>
+</body>
+</html>
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitOnLoadTests.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitOnLoadTests.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitOnLoadTests.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>JsUnit OnLoad Tests</title>
+    <link rel="stylesheet" type="text/css" href="../css/jsUnitStyle.css">
+    <script language="JavaScript" type="text/javascript" src="../app/jsUnitCore.js"></script>
+    <script language="JavaScript" type="text/javascript">
+
+        var aVar = null;
+
+        function testOnLoadFired() {
+            assertEquals("foo", aVar);
+        }
+        function myOnLoadEvent() {
+            aVar = "foo";
+        }
+    </script>
+</head>
+
+<body onload="myOnLoadEvent()">
+<h1>JsUnit OnLoad Tests</h1>
+
+<p>This page contains tests for the JsUnit Framework. To see them, take a look at the source.</p>
+</body>
+</html>

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitRestoredHTMLDivTests.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitRestoredHTMLDivTests.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitRestoredHTMLDivTests.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>JsUnit Framework tests</title>
+    <link rel="stylesheet" type="text/css" href="../css/jsUnitStyle.css">
+    <script language="JavaScript" type="text/javascript" src="../app/jsUnitCore.js"></script>
+    <script language="JavaScript" type="text/javascript">
+
+        function testOriginalHTMLPresent1() {
+            assertJsUnitjsUnitRestoredHTMLDivContainsOriginalHTML();
+        }
+
+        function testAlterOriginalHTML() {
+            var theDiv = document.getElementById("jsUnitRestoredHTML");
+            theDiv.innerHTML = "something <i>totally</i> different";
+        }
+
+        function testOriginalHTMLPresent2() {
+            assertJsUnitjsUnitRestoredHTMLDivContainsOriginalHTML();
+        }
+
+        function assertJsUnitjsUnitRestoredHTMLDivContainsOriginalHTML() {
+            var theDiv = document.getElementById("jsUnitRestoredHTML");
+            assertHTMLEquals(
+                    '<b>foo</b><input type="text" name="bar" value="12345">',
+                    theDiv.innerHTML);
+        }
+
+    </script>
+</head>
+
+<body>
+<h1>JsUnit Framework tests</h1>
+
+<p>This page contains tests for the JsUnit setUp and tearDown framework. To see them, take a look at the source.</p>
+
+<div id="jsUnitRestoredHTML"><b>foo</b><input type="text" name="bar" value="12345"></div>
+
+</body>
+</html>

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitSetUpTearDownTests.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitSetUpTearDownTests.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitSetUpTearDownTests.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>JsUnit Framework tests</title>
+    <link rel="stylesheet" type="text/css" href="../css/jsUnitStyle.css">
+    <script language="JavaScript" type="text/javascript" src="../app/jsUnitCore.js"></script>
+    <script language="JavaScript" type="text/javascript">
+
+        var atLeastOneTestHasRun = false;
+        var aVariable = null;
+
+        function setUp() {
+            aVariable = "foo";
+        }
+
+        function tearDown() {
+            atLeastOneTestHasRun = true;
+            aVariable = null;
+        }
+
+        function testEmpty1() {
+        }
+
+        function testSetUp() {
+            assertEquals("foo", aVariable);
+        }
+
+        function testEmpty2() {
+        }
+
+        function testTearDown() {
+            assertTrue(atLeastOneTestHasRun);
+        }
+
+        function testEmpty3() {
+        }
+
+    </script>
+</head>
+
+<body>
+<h1>JsUnit Framework tests</h1>
+
+<p>This page contains tests for the JsUnit setUp and tearDown framework. To see them, take a look at the source.</p>
+</body>
+</html>

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitTestLoadData.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitTestLoadData.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitTestLoadData.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>Test loading a local HTML Document</title>
+    <link rel="stylesheet" type="text/css" href="../css/jsUnitStyle.css">
+    <script language="JavaScript" type="text/javascript" src="../app/jsUnitCore.js"></script>
+    <script language="JavaScript" type="text/javascript">
+
+        var uri = 'tests/data/data.html';
+
+        function setUpPage() {
+            setUpPageStatus = 'running';
+            top.testManager.documentLoader.callback = setUpPageComplete;
+            top.testManager.documentLoader.load(uri);
+        }
+
+        function setUpPageComplete() {
+            if (setUpPageStatus == 'running')
+                setUpPageStatus = 'complete';
+        }
+
+        function testDocumentGetElementsByTagName() {
+            assertEquals(setUpPageStatus, 'complete');
+            var buffer = top.testManager.documentLoader.buffer();
+            var elms = buffer.document.getElementsByTagName('P');
+            assert('getElementsByTagName("P") returned is null', elms != null);
+            assert('getElementsByTagName("P") is empty', elms.length > 0);
+        }
+
+    </script>
+</head>
+
+<body>
+<h1>JsUnit Asynchronous Load Tests</h1>
+
+<p>This page tests loading data documents asynchronously. To see them, take a look at the source.</p>
+</body>
+</html>

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitTestLoadStaff.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitTestLoadStaff.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitTestLoadStaff.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>Test loading a local XML Document</title>
+    <link rel="stylesheet" type="text/css" href="../css/jsUnitStyle.css">
+    <script language="JavaScript" type="text/javascript" src="../app/jsUnitCore.js"></script>
+    <script language="JavaScript" type="text/javascript">
+        function exposeTestFunctionNames() {
+            return ['test1', 'test2', 'test3'];
+        }
+
+        var uri = 'tests/data/staff.xml';
+
+        function setUpPage() {
+            setUpPageStatus = 'running';
+            top.testManager.documentLoader.callback = setUpPageComplete;
+            top.testManager.documentLoader.load(uri);
+        }
+
+        function setUpPageComplete() {
+            if (setUpPageStatus == 'running')
+                setUpPageStatus = 'complete';
+        }
+
+        function test1() {
+            assertEquals(setUpPageStatus, 'complete');
+            var buffer = top.testManager.documentLoader.buffer();
+            var elms = buffer.document.getElementsByTagName('*');
+            assert('getElementsByTagName("*") returned is null', elms != null);
+            assert('getElementsByTagName("*") is empty', elms.length > 0);
+        }
+
+        function test2() {
+            var buffer = top.testManager.documentLoader.buffer();
+            var elm = buffer.document.documentElement;
+            assert('expected documentElement.tagName == staff, found ' + elm.tagName, elm.tagName == 'staff');
+        }
+
+        function test3() {
+            var buffer = top.testManager.documentLoader.buffer();
+            var emps = buffer.document.getElementsByTagName('employee');
+            assert('expected 5 employee elements, found ' + emps.length, emps.length == 5);
+            var empid = emps[0].getElementsByTagName('employeeId');
+            assert('expected first employeeId EMP0001, found ' + empid[0].firstChild.data, empid[0].firstChild.data == 'EMP0001');
+        }
+    </script>
+</head>
+
+<body>
+<h1>JsUnit Load XML</h1>
+
+<p>This page tests loading XML. To see them, take a look at the source.</p>
+</body>
+</html>

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitTestSetUpPages.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitTestSetUpPages.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitTestSetUpPages.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>Test loading a local HTML Document</title>
+    <link rel="stylesheet" type="text/css" href="../css/jsUnitStyle.css">
+    <script language="JavaScript" type="text/javascript" src="../app/jsUnitCore.js"></script>
+    <script language="JavaScript" type="text/javascript">
+
+        function setUpPage() {
+            inform('setUpPage()');
+            setUpPageStatus = 'running';
+            // test delayed setUpPage completion
+            setTimeout('setUpPageComplete()', 30);
+        }
+
+        function setUpPageComplete() {
+            if (setUpPageStatus == 'running')
+                setUpPageStatus = 'complete';
+            inform('setUpPageComplete()', setUpPageStatus);
+        }
+
+        function testDocumentGetElementsByTagName() {
+            assertEquals(setUpPageStatus, 'complete');
+        }
+
+    </script>
+</head>
+
+<body>
+<h1>JsUnit Asynchronous setUpPages</h1>
+
+<p>This page tests asynchronoush pre tests. To see them, take a look at the source.</p>
+<iframe name="documentBuffer"></iframe>
+</body>
+</html>

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitTestSetUpPagesSuite.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitTestSetUpPagesSuite.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitTestSetUpPagesSuite.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>JsUnit Test Suite</title>
+    <link rel="stylesheet" type="text/css" href="../css/jsUnitStyle.css">
+    <script language="JavaScript" type="text/javascript" src="../app/jsUnitCore.js"></script>
+    <script language="JavaScript" type="text/javascript">
+
+        function setUpPagesTestSuite() {
+            var newsuite = new top.jsUnitTestSuite();
+            newsuite.addTestPage("tests/jsUnitTestSetUpPages.html");
+            return newsuite;
+        }
+
+        function suite() {
+            var newsuite = new top.jsUnitTestSuite();
+            newsuite.addTestSuite(setUpPagesTestSuite());
+            return newsuite;
+        }
+    </script>
+</head>
+
+<body>
+<h1>JsUnit Test Suite</h1>
+
+<p>This page contains a suite of tests for testing JsUnit's setUpPages functionality.</p>
+</body>
+</html>

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitTestSuite.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitTestSuite.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitTestSuite.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>JsUnit Test Suite</title>
+    <link rel="stylesheet" type="text/css" href="../css/jsUnitStyle.css">
+    <script language="JavaScript" type="text/javascript" src="../app/jsUnitCore.js"></script>
+    <script language="JavaScript" type="text/javascript">
+
+        function coreSuite() {
+            var result = new top.jsUnitTestSuite();
+            result.addTestPage("tests/jsUnitAssertionTests.html");
+            result.addTestPage("tests/jsUnitSetUpTearDownTests.html");
+            result.addTestPage("tests/jsUnitRestoredHTMLDivTests.html");
+            result.addTestPage("tests/jsUnitFrameworkUtilityTests.html");
+            result.addTestPage("tests/jsUnitOnLoadTests.html");
+            result.addTestPage("tests/jsUnitUtilityTests.html");
+            result.addTestPage("tests/jsUnitVersionCheckTests.html");
+            return result;
+        }
+
+        function librariesSuite() {
+            var result = new top.jsUnitTestSuite();
+            result.addTestPage("tests/jsUnitMockTimeoutTest.html");
+            return result;
+        }
+
+        function suite() {
+            var newsuite = new top.jsUnitTestSuite();
+            newsuite.addTestSuite(coreSuite());
+            newsuite.addTestSuite(librariesSuite());
+            return newsuite;
+        }
+    </script>
+</head>
+
+<body>
+<h1>JsUnit Test Suite</h1>
+
+<p>This page contains a suite of tests for testing JsUnit.</p>
+</body>
+</html>

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitUtilityTests.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitUtilityTests.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitUtilityTests.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,100 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>JsUnit Utility Tests</title>
+    <link rel="stylesheet" type="text/css" href="../css/jsUnitStyle.css">
+    <script language="JavaScript" type="text/javascript" src="../app/jsUnitCore.js"></script>
+    <script language="JavaScript" type="text/javascript">
+        function testTrim() {
+            assertEquals(null, trim(null));
+            assertEquals(null, trim(JSUNIT_UNDEFINED_VALUE));
+            assertEquals("", trim(""));
+            assertEquals("", trim("    "));
+            assertEquals("string", trim("string"));
+            assertEquals("str  ing", trim("str  ing"));
+            assertEquals("string", trim(" string   "));
+        }
+
+        function testIsBlank() {
+            assert(!isBlank("  string "));
+            assert(isBlank(""));
+            assert(isBlank("    "));
+        }
+
+        function testPushAndPop() {
+            //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
+            var anArray = Array();
+            anArray[0] = "element 0";
+            anArray[1] = "element 1";
+            push(anArray, "element 2");
+            push(anArray, "element 3");
+
+            assertEquals("There should be 4 elements after 2 are pushed onto an array of size 2", 4, anArray.length);
+            assertEquals("element 0", anArray[0]);
+            assertEquals("element 1", anArray[1]);
+            assertEquals("element 2", anArray[2]);
+            assertEquals("element 3", anArray[3]);
+
+            pop(anArray);
+            assertEquals("Should be 3 elements after popping 1 from an array of size 4", 3, anArray.length);
+            assertEquals("element 0", anArray[0]);
+            assertEquals("element 1", anArray[1]);
+            assertEquals("element 2", anArray[2]);
+            pop(anArray);
+            pop(anArray);
+            pop(anArray);
+            assertEquals("Should be 0 elements after popping 3 from an array of size 3", 0, anArray.length);
+            pop(anArray);
+            assertEquals("Should be 0 elements after trying to pop an array of size 0", 0, anArray.length);
+        }
+
+        function FooBarThingy() {
+            this.foo = 'bar';
+        }
+
+        FooBarThingy.prototype.bar = function() {
+            return this.foo;
+        }
+
+        function testTrueTypeOf() {
+            assertEquals('Boolean', _trueTypeOf(true));
+            assertEquals('Using new', 'Boolean', _trueTypeOf(new Boolean('1')));
+
+            assertEquals('Number', _trueTypeOf(1));
+            var GI = new Number(1);
+            assertEquals('Using new', 'Number', _trueTypeOf(GI));
+            assertEquals('Number', _trueTypeOf(1.5));
+
+            assertEquals('String', _trueTypeOf('foo'));
+            assertEquals('Using new', 'String', _trueTypeOf(new String('foo')));
+
+            assertEquals('Using new', 'Function', _trueTypeOf(new Function()));
+            assertEquals('Function', _trueTypeOf(function foo() {
+            }));
+            assertEquals('Function', _trueTypeOf(testTrueTypeOf));
+
+            assertEquals('RegExp', _trueTypeOf(/foo/));
+            assertEquals('Using new', 'RegExp', _trueTypeOf(new RegExp('foo')));
+
+            var o = {foo: 'bar'};
+            assertEquals('Object', _trueTypeOf(o));
+            var o = new FooBarThingy();
+            assertEquals('FooBarThingy', _trueTypeOf(o));
+            assertEquals('String', _trueTypeOf(o.foo));
+            assertEquals('String', _trueTypeOf(o.bar()));
+            assertEquals('Function', _trueTypeOf(o.bar));
+
+            assertEquals('Object without constructor', 'Object', _trueTypeOf(window));
+        }
+    </script>
+</head>
+
+<body>
+<h1>JsUnit Utility Tests</h1>
+
+<p>This page contains tests for the utility functions
+    that JsUnit uses. To see them, take a look at the source.</p>
+</body>
+</html>

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitVersionCheckTests.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitVersionCheckTests.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/jsunit/tests/jsUnitVersionCheckTests.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,131 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>JsUnit Version Check Tests</title>
+<link rel="stylesheet" type="text/css" href="../css/jsUnitStyle.css">
+<script language="JavaScript" type="text/javascript" src="../app/jsUnitCore.js"></script>
+<script language="JavaScript" type="text/javascript" src="../app/jsUnitVersionCheck.js"></script>
+<script language="JavaScript" type="text/javascript">
+
+var versionLatestCalled;
+var versionNotLatestCalled;
+var versionCheckErrorCalled;
+var latestVersion;
+
+MockXmlHttpRequest = function() {
+}
+
+MockXmlHttpRequest.prototype.open = function (method, url, isAsync, userName, password) {
+    this.method = method;
+    this.url = url;
+    this.isAsync = isAsync;
+    this.userName = userName;
+    this.password = password;
+}
+
+MockXmlHttpRequest.prototype.send = function (data) {
+    this.sendCalled = true;
+    this.data = data;
+}
+
+function setUp() {
+    versionRequest = new MockXmlHttpRequest();
+    versionLatestCalled = false;
+    versionNotLatestCalled = false;
+    versionCheckErrorCalled = false;
+    latestVersion = null;
+}
+
+function createXmlHttpRequest() {
+    return versionRequest;
+}
+
+function versionNotLatest(aVersion) {
+    versionNotLatestCalled = true;
+    latestVersion = aVersion;
+}
+
+function versionLatest() {
+    versionLatestCalled = true;
+}
+
+function versionCheckError() {
+    versionCheckErrorCalled = true;
+}
+
+function testIsOutOfDate() {
+    assertTrue(isOutOfDate("" + (JSUNIT_VERSION + 1)));
+    assertFalse(isOutOfDate("" + JSUNIT_VERSION));
+    assertFalse(isOutOfDate("" + (JSUNIT_VERSION - 1)));
+}
+
+function testSendRequestForLatestVersion() {
+    sendRequestForLatestVersion("http://www.example.com/foo/bar/version.txt");
+    assertEquals("GET", versionRequest.method);
+    assertEquals("http://www.example.com/foo/bar/version.txt", versionRequest.url);
+    assertTrue(versionRequest.isAsync);
+    assertUndefined(versionRequest.userName);
+    assertUndefined(versionRequest.password);
+
+    assertTrue(versionRequest.sendCalled);
+    assertNull(versionRequest.data);
+
+    assertEquals(requestStateChanged, versionRequest.onreadystatechange);
+}
+
+function testBadResponse() {
+    versionRequest.readyState = 999;
+    versionRequest.status = 404;
+    requestStateChanged();
+    assertFalse("both bad", versionNotLatestCalled);
+    assertFalse("both bad", versionLatestCalled);
+    assertFalse(versionCheckErrorCalled);
+
+    versionRequest.status = 200;
+    requestStateChanged();
+    assertFalse("readyState bad", versionNotLatestCalled);
+    assertFalse("readyState bad", versionLatestCalled);
+    assertFalse(versionCheckErrorCalled);
+
+    versionRequest.readyState = 4;
+    versionRequest.status = 404;
+    requestStateChanged();
+    assertFalse("status bad", versionNotLatestCalled);
+    assertFalse("status bad", versionLatestCalled);
+    assertTrue(versionCheckErrorCalled);
+}
+
+function testReceiveNewerLatestVersion() {
+    versionRequest.readyState = 4;
+    versionRequest.status = 200;
+    versionRequest.responseText = "" + (JSUNIT_VERSION + 1);
+    requestStateChanged();
+    assertTrue(versionNotLatestCalled);
+    assertFalse(versionLatestCalled);
+    assertEquals("" + (JSUNIT_VERSION + 1), latestVersion);
+}
+
+function testReceiveSameLatestVersion() {
+    versionRequest.readyState = 4;
+    versionRequest.status = 200;
+    versionRequest.responseText = "" + JSUNIT_VERSION;
+    requestStateChanged();
+    assertFalse(versionNotLatestCalled);
+    assertTrue(versionLatestCalled);
+}
+
+function enablePrivileges() {
+}
+
+</script>
+</head>
+
+<body>
+<h1>JsUnit Version Check Tests</h1>
+
+<p>This page contains tests for the version checking code in JsUnit that looks to see whether a newer version of JsUnit
+    is available. To see them, take a look at the source.</p>
+</body>
+</html>

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/test/jsUnitCore.js
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/test/jsUnitCore.js	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/test/jsUnitCore.js	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,534 @@
+var JSUNIT_UNDEFINED_VALUE;
+var JSUNIT_VERSION = 2.2;
+var isTestPageLoaded = false;
+
+//hack for NS62 bug
+function jsUnitFixTop() {
+    var tempTop = top;
+    if (!tempTop) {
+        tempTop = window;
+        while (tempTop.parent) {
+            tempTop = tempTop.parent;
+            if (tempTop.top && tempTop.top.jsUnitTestSuite) {
+                tempTop = tempTop.top;
+                break;
+            }
+        }
+    }
+    try {
+        window.top = tempTop;
+    } catch (e) {
+    }
+}
+
+jsUnitFixTop();
+
+/**
+ + * 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 String:
+                        result = 'String';
+                        break;
+                    case Boolean:
+                        result = 'Boolean';
+                        break;
+                    case Number:
+                        result = 'Number';
+                        break;
+                    case Array:
+                        result = 'Array';
+                        break;
+                    case RegExp:
+                        result = 'RegExp';
+                        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 = '<' + aVar + '>';
+    if (!(aVar === null || aVar === top.JSUNIT_UNDEFINED_VALUE)) {
+        result += ' (' + _trueTypeOf(aVar) + ')';
+    }
+    return result;
+}
+
+function fail(failureMessage) {
+    throw new JsUnitException("Call to fail()", failureMessage);
+}
+
+function error(errorMessage) {
+    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)
+        throw new JsUnitException(comment, failureMessage);
+}
+
+function assert() {
+    _validateArguments(1, arguments);
+    var booleanValue = nonCommentArg(1, 1, arguments);
+
+    if (typeof(booleanValue) != 'boolean')
+        error('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('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('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);
+    _assert(commentArg(2, arguments), 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 === top.JSUNIT_UNDEFINED_VALUE, 'Expected ' + _displayStringForValue(top.JSUNIT_UNDEFINED_VALUE) + ' but was ' + _displayStringForValue(aVar));
+}
+
+function assertNotUndefined() {
+    _validateArguments(1, arguments);
+    var aVar = nonCommentArg(1, 1, arguments);
+    _assert(commentArg(1, arguments), aVar !== top.JSUNIT_UNDEFINED_VALUE, 'Expected not to be ' + _displayStringForValue(top.JSUNIT_UNDEFINED_VALUE));
+}
+
+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 = (var1 === var2);
+                break;
+            case 'RegExp':
+            case 'Function':
+                isEqual = (var1.toString() === var2.toString());
+                break;
+            default: //Object | Array
+                var i;
+                if (isEqual = (var1.length === var2.length))
+                    for (i in var1)
+                        assertObjectEquals(msg + ' found nested ' + type + '@' + i + '\n', var1[i], var2[i]);
+        }
+        _assert(msg, isEqual, 'Expected ' + _displayStringForValue(var1) + ' but was ' + _displayStringForValue(var2));
+    }
+}
+
+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 expected = nonCommentArg(1, 3, arguments);
+    var actual = nonCommentArg(2, 3, arguments);
+    var tolerance = nonCommentArg(3, 3, arguments);
+    assertTrue(
+            "Expected " + expected + ", but got " + actual + " which was more than " + tolerance + " away",
+            Math.abs(expected - actual) < tolerance
+            );
+}
+
+function assertContains() {
+    _validateArguments(2, arguments);
+    var contained = nonCommentArg(1, 2, arguments);
+    var container = nonCommentArg(2, 2, arguments);
+    assertTrue(
+            "Expected '" + container + "' to contain '" + contained + "'",
+            container.indexOf(contained) != -1
+            );
+}
+
+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
+        {
+            foo.bar;
+        }
+        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();
+}
+
+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 (top && 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 ||
+                      navigator.userAgent.indexOf('Safari/') != -1;
+
+    if (typeof(windowRef.attachEvent) != 'undefined') {
+        // Internet Explorer, Opera
+        windowRef.attachEvent("onload", onloadHandler);
+    } else if (typeof(windowRef.addEventListener) != 'undefined' && !isKonqueror) {
+        // Mozilla, Konqueror
+        // 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;
+    }
+}
+
+jsUnitSetOnLoad(window, newOnLoadEvent);
\ No newline at end of file

Added: labs/jbosslabs/trunk/portal-extensions/portal-dnd/test/testPortletDrop.html
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/portal-dnd/test/testPortletDrop.html	2006-08-28 18:05:27 UTC (rev 5993)
+++ labs/jbosslabs/trunk/portal-extensions/portal-dnd/test/testPortletDrop.html	2006-08-28 21:37:06 UTC (rev 5994)
@@ -0,0 +1,92 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>Test loading a local HTML Document</title>
+    <!-- JSUnit lib -->
+    <script language="JavaScript" type="text/javascript" src="jsUnitCore.js"></script>
+    
+    <!-- All used YUI and portal ajax libs -->
+    <script language="JavaScript" type='text/javascript' src='../dndRenderer.war/js/yahoo/yahoo.js' ></script>
+    <script language="JavaScript" type='text/javascript' src='../dndRenderer.war/js/event/event.js' ></script>
+    <script language="JavaScript" type='text/javascript' src='../dndRenderer.war/js/dom/dom.js'></script>
+    <script language="JavaScript" type='text/javascript' src='../dndRenderer.war/js/logger/logger.js' ></script>
+    <script language="JavaScript" type='text/javascript' src='../dndRenderer.war/js/dragdrop/dragdrop-debug.js' ></script>
+    <script language="JavaScript" type='text/javascript' src='../dndRenderer.war/js/connection/connection.js' ></script>
+    <script language="JavaScript" type='text/javascript' src='../dndRenderer.war/js/portal/PortalDD.js' ></script>
+    
+					
+    <script language="JavaScript" type="text/javascript">
+    	var ddPortletregionNumberOne0, ddPortletregionNumberOne1, regionDropregionNumberOne;
+    	var ddPortletregionNumberTwo0, ddPortletregionNumberTwo1, regionDropregionNumberTwo;
+    	
+		YAHOO.example.DDAppregionNumberOne = function() {
+		    var DDM = YAHOO.util.DDM;
+		    DDM.mode = DDM.POINT;
+		    return {
+		        init: function() {
+		            regionDropregionNumberOne = new YAHOO.util.PortalDD('regionDropregionNumberOne');
+		            regionDropregionNumberOne.setXConstraint(0, 0, 1);
+		            regionDropregionNumberOne.setYConstraint(0, 0, 1);
+		            ddPortletregionNumberOne0 = new YAHOO.util.PortalDD('portlet-dnd-regionNumberOne-0');
+		            ddPortletregionNumberOne0.windowId = "FirstPortletWindowNumberOne";
+		            ddPortletregionNumberOne1 = new YAHOO.util.PortalDD('portlet-dnd-regionNumberOne-1');
+		            ddPortletregionNumberOne1.windowId = "SecondPortletWindowNumberOne";
+	
+		            regionDropregionNumberOne.getEl().parentNode.dropToRegion = 'regionDropregionNumberOne';
+		            regionDropregionNumberOne.getEl().parentNode.regionId = 'NumberOne';
+		        }
+		    };
+		} ();
+		YAHOO.util.Event.addListener(window, 'load', YAHOO.example.DDAppregionNumberOne.init);
+		
+		YAHOO.example.DDAppregionNumberTwo = function() {
+		    var DDM = YAHOO.util.DDM;
+		    DDM.mode = DDM.POINT;
+		    return {
+		        init: function() {
+		            regionDropregionNumberTwo = new YAHOO.util.PortalDD('regionDropregionNumberTwo');
+		            regionDropregionNumberTwo.setXConstraint(0, 0, 1);
+		            regionDropregionNumberTwo.setYConstraint(0, 0, 1);
+		            ddPortletregionNumberTwo0 = new YAHOO.util.PortalDD('portlet-dnd-regionNumberTwo-0');
+		            ddPortletregionNumberTwo0.windowId = "FirstPortletWindowNumberTwo";
+		            ddPortletregionNumberTwo1 = new YAHOO.util.PortalDD('portlet-dnd-regionNumberTwo-1');
+		            ddPortletregionNumberTwo1.windowId = "SecondPortletWindowNumberTwo";
+	
+		            regionDropregionNumberTwo.getEl().parentNode.dropToRegion = 'regionDropregionNumberTwo';
+		            regionDropregionNumberTwo.getEl().parentNode.regionId = 'NumberTwo';
+		        }
+		    };
+		} ();
+		YAHOO.util.Event.addListener(window, 'load', YAHOO.example.DDAppregionNumberTwo.init);
+	
+
+		function testDragAndDrop() {
+			// objects should have different parents
+			assertNotEquals("Parents do match", ddPortletregionNumberTwo0.getEl().parentNode, ddPortletregionNumberOne0.getEl().parentNode);
+			
+			// turn of ajax callbacks
+			setAjaxEnabled(false);
+			var e;
+			// execute drop
+			ddPortletregionNumberTwo0.onDragDrop(e, ddPortletregionNumberOne0.getEl().id);
+			
+			// parents should match now
+			assertEquals("Parents don't match", ddPortletregionNumberTwo0.getEl().parentNode, ddPortletregionNumberOne0.getEl().parentNode);
+		}
+
+    </script>
+    
+</head>
+
+<body>
+<h1>JsUnit test portlets DnD</h1>
+
+<div id='regionDDregionNumberOne'><div style='display: none; visibility: hidden; padding: 50px; margin: 10px; border: 1px dashed black;' id='regionDropregionNumberOne'>Drop your portlets here</div><div id='portlet-dnd-regionNumberOne-0'>Portlet No 1 (Region ONE)</div><div id='portlet-dnd-regionNumberOne-1'>Portlet No 2 (Region ONE)</div></div>
+<div id='regionDDregionNumberTwo'><div style='display: none; visibility: hidden; padding: 50px; margin: 10px; border: 1px dashed black;' id='regionDropregionNumberTwo'>Drop your portlets here</div><div id='portlet-dnd-regionNumberTwo-0'>Portlet No 1 (Region TWO)</div><div id='portlet-dnd-regionNumberTwo-1'>Portlet No 2 (Region TWO)</div></div>
+	
+<p>This page tests DnD.</p>
+<iframe name="documentBuffer"></iframe>
+</body>
+</html>




More information about the jboss-svn-commits mailing list